TensorFlow将棋ソフトを作ることにした
経緯
プライベートでTensorFlowを使ったニューラルネットワークを遊んでいるがアプリケーションが思いつかない。ネタに走り過ぎず学習データの調達が容易で他人と価値が共有できるようなものが良い。もともと自分は画像認識をお仕事としてやってきたが画像認識系は個人でやるにはデータセット調達の負担が大きい。規定のタスクのベンチマーク用のデータセットはあるがすでに解かれているタスクをやったって面白くない。
将棋はすでに解かれている(解く試みが多くなされている)タスクではあるものの他者と競技できるという点で面白い。将棋文化自体は個人的に良い印象はなかったがタスクとして楽しそうなのでやってみることにする。なお将棋のルールはよくわかっていない。
アプローチ
Alpha Goに近いアプローチになると思う。入力盤面に対する出力次手について勝敗を基準にロスを与えていく。既存の棋譜を使用するのであれば各手順の盤面について勝敗が紐付いているため各盤面を独立に学習することができる。AI同士の対局から学習する場合は終了してからその対局の各盤面について勝敗を基準に学習する。
既存の棋譜による学習を事前学習的に先に行い以降はAI同士の学習を重視していく。
学習を加速させるために指し手モデルと勝敗予測モデルのふたつを作る。AI同士の学習において(つまり各盤面の勝敗が未決定の学習において)、合理的な手を指していないと学習する対局自体が価値の低いものになってしまう。
対局の1手および全体については以下のような形になる。
- 指し手モデルが次手を出力する
- 勝敗予測モデルが勝敗を予測する
- 勝敗予測モデルの合否によるロスで指し手モデルは学習し、合格が出るまで学習した後に実際に駒を進める
- 対局が終了した段階で勝敗予測モデルが対戦結果による学習を行う
勝敗予測モデルが成長することで指し手モデルは合理的な手をより早く学習し、指し手モデルが成長することで勝敗予測モデルは盤面からの勝敗可能性をより真実に近い形で学習する。これはGANに近いアプローチになっていると思う。
ここまでRNN、LSTMの話題を出していないが将棋とは本質的にはそういうものである。時系列データとして扱うのは対局者の個性というファクターを導入するときであろうと思うが今のところそれは考えていない。
ここまでいろいろ書いたがちゃけば大した自信はない。
モデルの検討
入力ベクトル、出力ベクトルの設計が一番影響が大きいと見込んでいる。入力ベクトルについてシンプルな形式から学習できるはずのインプリシットな情報をエクスプリシットに与えるかどうかが大きい。つまり例えば盤面から次に可能な手は陰に与えられているわけだが、これを学習で獲得するか入力ベクトルとして与えてしまうかというようなことだ。前者の場合は学習の収束に時間がかかりかつモデルを大きくしなければならない。後者の場合は入力ベクトルが大きくなるため一層ごとの学習コストが大きくなる。自分は入力ベクトルについては後者のアプローチをとる。
出力ベクトルについても似たような話がある。理想的には合法な次手のみが出力される線形のきれいな(つまり学習しやすい)関数の重みとして得られるのが良い。合法な手の中のうちロスが小さいものを学習させていきたい。しかしこれは今のところ自分には思いつかないので非合法な次手の出力も許し合法な手により小さなロスをつけて学習させるアプローチを取る。合法・非合法を学習しなければならないので学習コストがかかるがしかたがない。
中間層についてはまだあまり考えていない。とりあえずは5層くらい重ねたいが勾配消失との戦い、財布との戦いになりそうな感じ。
当面の課題
- 棋譜データを一括でダウンロードできるサービスを探すこと。
- 勝敗判定などの補助ライブラリにpython-shogiを利用するが盤面の左右反転・180度回転(画像認識におけるデータオーグメンテーション)機能がなかったり、入力ベクトル化するのに使いにくかったりするのでなんとかする。
- 電王戦はめんどくさそうなので興味がないのだがAI将棋のネットワーク対戦ランク付けサービスがあると良いのだがまだ見つけてない。
目標
年内中に「まあ将棋にはなっている」「〜級程度には見える」というところまで到達したい。