これは、https://qiita.com/tkoji3744/items/b51981aa8d9c3e02d454
の続きである。
昔の開発で ( https://qiita.com/tkoji3744/items/d564f55bfc6076a6074a )
ランダムbotの着手は、まさに脈略がなく、またモンテカルロbotの手は、1路、2路ばかりうつようなものだった。なにより、囲んで石をとる、ような動きや、あたりで逃げるような動きは皆無だった。要するに、弱すぎて、話にならなかった。このとき、Pyaqをもとにしたbotを開発したつもりだったが、そのとき一度うまくいったと思ったのだが、その後再現性はなかった。
そこで今回、もう一度、機械学習bot作成に挑戦してみた。そして、さらに、それをオンラインで「人 対 機械学習bot」ができるようにするという目標を掲げた。
結論からいうと、Pyaq( ymgaq/AQ: A Go game engine. Download here: http://github.com/ymgaq/AQ/releases )
( https://colab.research.google.com/drive/1qTJY_0AfrtwiyGYnmd6PZweWw1zG7n33#scrollTo=ODfvSX7fCFKl ) やdlGo
( https://github.com/maxpumperla/deep_learning_and_the_game_of_go )
を応用、あるいは模倣した機械学習botは敷居が高く、あきらめた。かわりに、一応、TensorFlow(機械学習のパックージ 例 Keras)とNumPy(高速な配列計算のパックージ)を用いた、原始的な機械学習botを作成して、このFlaskによる囲碁オンライン対戦アプリに組み込むことに目標を下げ、何とか成功したので、報告する。
だが、この方法では、 9路盤限定であればある程度は打てるようになるが、がんばっても5〜7級相当が限界、ということだ。
なぜなら、この方法は、機械学習botの以下の3つの力のうち、ほんの少ししかとりれてないからだ。
△ 深層学習:最善手の直感(形の模倣)
シンプルなニューラルネット(例: Keras/TensorFlow, PyTorchでのMLPや小型CNN)のみ
X 強化学習:よみ、経験
self-play: 自己対戦による経験(よみ) ⇒このモデルでは不可能
X 探索:先読みする力
?モンテカルロ木探索 は導入せず
機会がもしあれば、強い機械学習botもいつか挑戦してみたいものだ。
(参考)なぜ dlgo を今回あきらめたか?
• dlgo(Deep Learning and the Game of Go)は、Python 3.6 時代のコードで、
o 依存関係が複雑
o Keras + TensorFlow 1.x 前提
o Windows 環境ではインストールや修正が非常に手間
(1)まず、tkinkerで、main_gui.py「人 対 機械学習bot」を作成する。
これに関して、パッケージ(バージョン)の組み合わせはたいへん狭く、厳しくエラーが続出。結果:
現在のぼくのPCのパッケージ(バージョン)
Python 3.10.x NumPy 1.24.3 TensorFlow 2.13.0
では機械学習botはつくれなかった。
必要なのは、
Python3.8 Numpy==1.21.6 Tensorflow==2.10.0
(むしろ、最新バージョンよりダウングレード)
そのため、PC内に「仮想環境」をつくることになった。この「仮想環境」の場所も、最初は
(venv) C:\Users\koji3\deep_learning_and_the_game_of_go>
につくっていたが、CUI(Character User Interface)に弱く、GUI(Graphical User Inerface)にたよるぼく(Linuxはできず、WindowsやVSCのターミナルがなんとできる)にとっては使いにくく、結局、デストップにフォルダをつくって、そこを「仮想環境」にする(venv) PS C:\Users\koji3\デスクトップ\ml_test_project> )という方法におちついた。
実際的には、ml_test_projectフォルダ内に、「機械学習bot対 人」のコードを書いたmain_gui.pyをおいく。そして、VSC→Open Folder→ml_test_projectフォルダ選択→画面左のエクスプローラでml_bot_project_fixed内のapp.pyを選択 →右クリックで、一番下の「Run Pythin file in terminal」を選択(VSCのターミナルが、(venv) PS C:\Users\koji3\デスクトップ\ml_test_project>でWindowの右下がvenv(3.8)となっていることを確認)、というやり方を、コードを書き換えるたびにおこなって、起動テストをおこないながら完成させていった。
①まず、最初にtest.pyをつくり、これがうまく動けば、このしくみが成功した証拠とする。
test.py
import tensorflow as tf
import numpy as np
print("TensorFlow version:", tf.__version__)
print("NumPy version:", np.__version__)
hello = tf.constant('Hello, TensorFlow!')
print(hello)
② sgfフォルダ内に1,028局分をよみこむ
サイト:yenw/computer-go-dataset: datasets for computer go
(参考)最終的には、1028局→10327局、にふやした
③sgf_to_csv.pyを用いて
sgf→csvへ変換 (csvフォルダ内に1028局分)
④prepare_dataset.pyを用いて
「AIの学習用データセット作成」上記の1028局分から、1つの、train_data.csv ファイル作成
⑤train.py「モデル学習」
イメージは、うちかたの形のまね。
画像識別のようなもの
(これは、地になるから、とか相手の地を消すとか、相手の石をとる、とか自の石をとられないように、とかはない。
python
import pandas as pd
import numpy as np
import ast
import tensorflow as tf
# 1. データ読み込み
df = pd.read_csv("../data/train_data.csv") # パスは適宜調整
X_list, Y_list = [], []
for idx, row in df.iterrows():
# 盤面情報
board = ast.literal_eval(row["board"])
board = np.array(board, dtype=np.int8)
board_flat = board.flatten() # (81,)
# 手番(b/w → 1/-1)
player = 1 if row["player"] == "b" else -1
X = np.concatenate([board_flat, [player]])
X_list.append(X)
# 着手点 (row, col) → 0〜80
move_idx = row["move"]
if isinstance(move_idx, str):
move_idx = ast.literal_eval(move_idx)
move_flat = move_idx[0]*9 + move_idx[1]
Y_list.append(move_flat)
X = np.stack(X_list)
Y = np.array(Y_list)
# 2. モデル定義
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(82,)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(81, activation='softmax') # 9x9=81手
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 3. 学習
model.fit(X, Y, epochs=20, batch_size=64)
# 4. モデル保存
model.save("../model/model9x9.h5") # フォルダは適宜
print("モデル保存完了!")
このtrain.pyを実行 → model9x9.h5ができれば成功!
学習の最中
このtrain.pyのパラメーター:Epock 1/10 ⇒ 1/50 とすると、学習完了までの時間、数十秒→40分程度 に延長。すなわち。強化学習がより強くおこなわれることになる。
できた、main_gui.pyで動かすと
(2) Flaskでこのmodel9x9.h5を動かす
①まずは、PC本体で「ランダムbot対人」(go_flask_app_dl2)をFlaskで作成。これをml_test_projectフォルダにいれて、main_gui.pyが動くその仮想環境にて実行してみる。動いたら、これをもとに、main_gui.pyを参考にしながら、go_flask_app_dl2を「機械学習bot対人」(model9x9.h5使用):ml_bot_projectに変更していく。Flaskのバージョンは3.0.3で、本体PCでも、仮想環境Python3.8 Numpy==1.21.6 Tensorflow==2.10.0 でも、ともにバッチングしなかった。
②ml_test_projectフォルダの仮想環境内に、Flaskファイル ml_bot_projectをつくり、app.pyで実行→オンラインで、「機械学習bot対人」対戦をする準備ができた。
フォルダ構成は、
ml_test_project/
├── venv/
├── ml_bot_project/
│ ├── app.py ←★この中でFlaskアプリ実行
│ ├── bot.py ←★model9x9.h5を利用してBot応答
│ ├── go_board.py
│ ├── go_types.py
│ ├── templates/
│ │ └── play.html
├── model9x9.h5 ←★この場所(親フォルダ直下)
最初、
A 前回つくった囲碁SNSのFlaskの起動時に、仮想環境を利用する。
⇒pythonanywhereにデプロイ時、SNSを扱うgo_flask_app_dl3 と機械学習を利用するml_test_projectを分割する。
(なぜなら、それぞれ、つかう、Python、tensorflow、numpyのバージョンが違う)
B 簡易法:go_flask_app_dl3をml_test_projectの仮想環境内でうごくよう改変(=go_flask_app_dl3_env)して、一括してpythonanywhereにデプロイ
のどちらかか?、と思ってしばらう開発したが、結局、SNS本体サイト:
Flask(最新・通常の環境、AI無し)
→ 投稿・掲示板・碁会所マップ・人同士の対局
→ 「Botと対戦したい人はここからどうぞ」のリンクボタンを設置
と、Bot対戦専門サイト:
Flask(Python3.8/TensorFlow2.10.0/NumPy1.21.6などAI環境にあわせたvenv)
→ 9路盤人対bot専用(自分のAIモデルやPyAQ/KataGo導入もOK)
→ 「トップページ」や「戻る」ボタンでSNS本体に戻れるようにする
をわける方針とした。
最終的に、ml_test_projectフォルダ内に、「機械学習bot対 人」のコードを書いた、ml_bot_project_fixedをおく。VSC→Open Folder→ml_test_projectフォルダ選択→画面左のエクスプローラでml_bot_project_fixed内のapp.pyを選択 →右クリックで、一番下の「Run Pythin file in terminal」を選択(VSCのターミナルが、(venv) PS C:\Users\koji3\デスクトップ\ml_test_project>でWindowの右下がvenv(3.8)となっていることを確認(なぜか、右クリックで、一番下の「Run Pythin file in terminal」を選択を3回おこなわねばならない)。そして、model9x9.h5をつかったbotを使うプログラムをFlask で起動して成功した(下図)。実力は予想どおり。
最後の最後で碁盤の描画(play.html)で意外につまづいた。
その原因を、かいつまんでいえば、
当初HTMLは table を使って碁盤を描いてた。だが、これは以下の理由でうまく動作しにくいです: 問題点項目 内容📏 サイズ table だと碁盤の正方形レイアウトが崩れやすく、CSSでの細かい位置指定が難しい🎯 中心点 囲碁の石は「交点」に打ちますが、


