読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

囲碁AIアプリの作り方1

1日遅れですが、一人アドベントカレンダーを始めます。
(ご協力いただける方、お声がけください)


題して「囲碁AIアプリの作り方」です。
念のため、「囲碁AIの作り方」ではありません。囲碁AI自体を作りたい方はAlphaGo論文などを読んで頑張ってください。


とは言っても、アプリのコアになるのは囲碁AIです。なので初日の今日は、お手製AI、「AZ.js」のご紹介です。
まずは以下のURLからAZ.jsで遊んでみてください。

https://new3rs.github.io/AZ.js/index.ja.html



このアプリ、ウェブアプリながら、ELF OpenGoと同じニューラルネットワークを搭載しています。時間さえ与えれば、ELF OpenGoと同じ強さを発揮するはずです。(その時間が問題なのですが)
探索アルゴリズムPyaqJavaScriptに移植したものです。


AZ.jsのコードは以下で見ることが出来ます。

github.com

中身はほぼPyaqですが、多少コードを整理してドキュメンテーションも充実させてあります。
Pyaqは自己対戦から学習するところまで含めてコードが用意されていますが、AZ.jsはエンジンのみです。
なので、ニューラルネットワークの学習部分にも取り組みたければPyaq、エンジンだけみたいという人はAZ.jsという感じでおすすめします。

拙作「囲碁の師匠」のAIエンジンもこのAZ.jsをSwiftに移植することから開発を始めました。

MCTSの部分はAlphaGo Zero論文の素直な実装です。シングルスレッド版なので、マルチスレッドにするにはスレッドの言語的な部分とともにアルゴリズム上バーチャルロスを導入する必要が出てきます。
同じアルゴリズムで並列に走らせると、スレッドが同じノードを探索してしまうのでそれを避ける工夫がバーチャルロスです。探索中の枝は仮にちょっと分が悪い枝に見せることで他のスレッドに別の枝を探索させます。


他にもAlphaGoの論文では明らかにされていない部分がいくつかあって、そういう部分を見つけて工夫してみるのも面白いと思います。
ただ工夫の検証が大変なので…(400局ぐらい対戦させて勝率何%上がるかという評価作業が必要になります)


参考に、「囲碁の師匠」では、Leela Zero界隈でFPUと呼ばれる部分に独自の工夫を入れました。
MCTSを使ったアルゴリズムは元局面がバリュー以上に悪くて一手進めると評価を落とすような局面に出会うと、候補手すべてを探索し始めます。Lizzieをお使いの方は、画面全体が勝率表示で埋まる現象を見たことがあるかと思います。
思ったよりよくないからと言って、生きている石の内側まで探索するのもなんなんで、そういう現象を抑えるようなFPUを実装しました。
意図した局面でも探索の効率を上げることが出来たので「強くなった」と思うのですが、こういう局面の効率を上げても仕方がないようで、勝率はあまり変わらないようです^^;


囲碁AIを動かしたい環境(例えばAndoroidとか)がある方は、まずAZ.jsをその環境に適した言語(AndroidならKotlinとか)に移植してみるといかもしれません。

本日はこのぐらいで。