前回作った囲碁プログラムのプレイアウトで、プロの棋譜から学習したパターンの確率に応じて手を選択するようにしてみた。
はじめ局面全体の合法手について3×3パターンを適用してみたが、まったく強くならない上に、30倍くらい遅くなってしまった。
そこで、直前の手の周辺の手に対してだけパターンを適用したところ、
ランダムプレイアウトとの対戦では、ほぼ100%勝つようになった。
AlphaGoでは、rolloutのpolicyに3×3パターンを静的に適用しているが、
他にも直前の手の周辺の12ポイントのダイアモンドやアタリを防ぐ手なども加えている。
3×3パターンを静的に適用するだけでは効果がないのかもしれない。
時間がかかりすぎるのは自分のプログラムに工夫が足りないせいだろう。
パターンを32bitの数字にして、C++のmapで検索しているがここまで遅くなるとは。
呼吸点の数も特徴量に入っているので、それを調べるのにも時間がかかっていそうである。
AlphaGoでは、rollout policyに、linear softmaxを使用していると書かれているが、
各合法手に対して、一致するパターンの重みを加算して、
全ての合法手の確率の合計が1になるようにsoftmaxを適用するというふうに理解しているが合っているのだろうか。
その前提で、棋譜から学習を行った。
パラメータwの更新は、損失関数を交差エントロピーとして、
棋譜の打ち手と一致した場合、(y - 1) * w を勾配とし、
棋譜の打ち手と一致しない場合、y * w を勾配として
計算した。
(yはsoftmaxの出力)
3×3パターンは、AlphaGoにならって、
各位置の石の色と呼吸点の数を特徴とした。
入手した4万くらいの棋譜から学習した結果、以下のパターンの重みが一番高かった。
●3 | ○2 | |
× | ●1 | |
●3 | ○2 |
黒を基準にして、×は石が打たれた場所、数字は呼吸点の数
真ん中右の黒石の呼吸点の数が1なので、アタリなっているのでそれを助ける手のようだ。
ちなみに、モンテカルロ木探索でパターンを初めて導入したMoGoでは、
アタリを助ける手と、手作りの13パターンを使って直前の手の周囲を調べている。
これで、2006年の大会でGnuGoに勝ったということだが、
自分のプログラムではプレイアウトの改良で強くなったとはいえ、
まだGnuGoにも勝てないレベルである。
アタリを助ける手を調べていないので、その効果が大きいのかもしれない。
次に検証してみようと思う。