Deep Learningを用いた将棋プログラムGunyanzaを公開しました
ディープラーニング(深層学習)というのが流行っているそうです。すべての人類はディープラーニングによって実現されたAIに隷属する未来なんですってよ!!! こわーい。
そんなバラ色の技術、いっちょかみしておきたいですよね。
さて、オフィスで社長とダベっていたところ、「将棋プログラム面白そうだよね」という話になりました。お互将棋プログラムを作って闘わせようぜ、いぇー、と盛り上がり、勢いでコンピュータ将棋選手権に申し込みまでしてしまいました。
そんな経緯で、ディープラーニングをミリしら(=1ミリも知らない)な僕が、試しにディープラーニングを使って将棋のAIを書いてみたらいいやん、と思いついたのでした。将棋も、ハム将棋でハム8枚落ちで負けるレベルくらい。ダメじゃん。
ミリしらなので、「チェスで何かやってるヤツがいるだろう」とアタリをつけてググった結果、Erik Bernhardssonさんによる deep pinkを発見。要約すると、「ディープラーニングでチェスをプレイしてみた」。おお、これ適当に移植してみよう。ついでに、今シャレオツな会社として世間で名高い、Preferred NetworksのChainerというライブラリを使えばナウい!
という大脳新皮質が1%も働いていない思考に基づいて、将棋AIを書いてみました、その名もGunyanza。
https://github.com/gunyarakun/gunyanza
棋士の羽生さんと、ネットワークなどで用いられるハブをかけて、deep hubという名前をつけていましたが、名前に耐えられるだけの品質に達していないため、現在のゆるい名前に変更しました。
結局、コンピュータ将棋選手権には忙しくて真面目に取り組めない & 海外なので参加を断念しました。とほほ。
原理
- 棋譜の中から、盤面を1つ取得する。この盤面をXとする。
- Xのあとに、棋譜どおりに手が1つ進んだ盤面をYとする。
- Yのあとに、棋譜以外のランダムな着手可能手で手が1つ進んだ盤面をZとする。
- X, Y, Zをディープラーニングのネットワークに流し込む。その結果として得られる盤面の評価値をm(X), m(Y), m(Z)とする。
- m(X)=m(Y)>m(Z)という仮定を置き、そうなるように誤差を設定し、ネットワークを学習させる。
- m(X)は盤面から評価値を得る関数として学習される。
python-shogi
将棋の合法手生成などを行えるライブラリは、別途python-shogiとしてPyPIに公開してあります。
https://github.com/gunyarakun/python-shogi
元ネタは、python-chess。
一応ビットボードに基づいています。Pythonでは81bit超えの整数が扱えるので、何も考えずに81bitでビットボード詰めてます。
コンピュータ将棋協会(CSA)規定のTCP/IPプロトコルも実装してあります。なので、学習したプログラムをfloodgateなどにつなげて対戦することも難しくないはず。
気になるとこ
とりあえず動作しているように見えるものの、どう考えても「動作」しているだけな予感がしている。
- 誤差伝搬のところクソバグっているのでは。同じネットワークを共有しつつ、結果として出た答えに基づいて誤差を伝搬する方法がよーワカラン。
- train setではlossが減っているが、test setではlossが減らなくなってる。
- 学習データが豊富なので、学習はならされて、dropoutは必要ないのでは、という元ネタの仮説のままに実装したが、検証の必要がある。おそらく、仮説は合っているが、学習データが不足しているのではないか。だとすれば、棋譜からのサンプリング数を増やす必要がある。サンプリングの数はgenerate_random_boards_to_hdf5の頭のあたりにある定数をいじれば変えられる。
- 誤差の関数、元ネタの関数は複雑で意味がよくワカランので、単純な誤差関数にしてみた。
- 位置不変性や、飛車・角の効きを学習するために、盤面をConvolution(3x3ごと、筋ごと、段ごと)とかやってみたけど、テキトーにやったので、効いている感じはしなかった。network.pyでコメントアウトされたところに、ほのかな香りが残しておいた。
- 駒の利きも入力として与えるのがよいのでは。
- 元ネタのように学習中にcoefficient_bを減らさないと学習が収束していかないのでは。
まとめ
python-shogiという将棋ライブラリを作成しました。そのpython-shogiと、Chainerというディープラーニングのライブラリを用いて、盤面の評価値を学習し、コンピュータ同士で将棋の対戦ができるGunyanzaを開発しました。
Gunyanzaは、ディープラーニングを用いた将棋AIを作る叩き台として有用です。
ディープラーニングにも将棋にも詳しくなくても、なんとか動くものは出来ました。が、どう見ても激弱です。バグってます。いまいちいけてないです。
みんなでnetwork.py/trainを差し替えて、1) 2) 3)を埋めてください!
Gunyanza、python-shogiともpull requestなどお待ちしております。
ちなみに、社長は「embona - ブラウザで動くBonanzaを作ってみた」というエントリを書いています。こちらもあわせてどうぞ。