TadaoYamaokaの日記

山岡忠夫Homeで公開しているプログラムの開発ネタを中心に書いていきます。

将棋でディープラーニングする その52(自己対局で教師局面生成)

AlphaZeroと同様の方式で、自己対局で教師局面を生成するプログラムを作成した。

自己対局の仕様

以下の仕様はAlphaZeroと同じとした。

  1. 自己対局を行う双方のプレイヤーは、同一のモデルを使用する。
  2. プレイアウトは固定プレイアウト数

以下の点は変更した。

  1. 開始局面は、Aperyと同じようにroots.hcpからランダムで選択し、1手ランダムムーブを行う。
  2. 常に、ルート局面でのプレイアウト数が最大の手を選択する(グリーディー戦略)。

1点目は、AlphaZeroでは、初期局面から一定の手数まではルートノードの合法手のプレイアウト数に応じた確率分布に従って指すことで序盤の手をばらけさせている。
Aperyと同様にroots.hcpを使用した方が手をばらけさせることができるので、roots.hcpを使うように変更した。
教師局面がroots.hcpの質に影響してしまうので、roots.hcpは十分なバリエーションを持たせる必要がある。

2点目は、1点目と関連するが、AlphaZeroは序盤は確率分布に応じて手を選択するが、一定の手数以上になるとグリーディー戦略に切り替える。
roots.hcpを使うので始めからグリーディー戦略とした。

教師データの仕様

AlphaZeroの教師データは、ルートノードの合法手のプレイアウト数に応じた確率分布となっているが、グリーディー戦略の場合、選択した1手のみがあればよいので、教師局面はApery及びelmoと同様にhcpeフォーマットとした。
elmo_for_learnで生成したデータと同じフォーマットなので、これまで使用していた学習プログラムを変更しないで学習に使用できる。

ランダム性

AlphaZeroでは、ルートノードでは方策ネットワークの確率分布にディリクレノイズを加えている。
同様にルートノードではノイズを加える。
以前にdlshogiにディリクレ分布を使うと弱くなってしまったので、dlshogiで使っているのと同じノイズ方式とした。
dlshogiでは、一定の確率で選択した1手の方策ネットワークの確率に対して
{ \displaystyle
p \leftarrow (p + 1) / 2
}
という操作を行い、確率をあげている。

ハッシュ再利用

前の手番で探索した結果は、ハッシュに残っているが、ハッシュを再利用することで探索を高速化できる。
しかし、上述の通りルート局面にはノイズを加えているが、ハッシュに残っている局面にはノイズが加わっていないので、ハッシュは再利用しないことにした。

自己対局の効率化

自己対局を1局ずつ行うのでは、マルチスレッドで実行しても、少ないプレイアウト数ではMCTSの性質上、ほとんどのスレッドが同一局面を調べてしまう。
教師局面を大量に生成するためには、プレイアウト数はあまり増やせない。
そこで、1つの対局は1スレッドで実行するようにし、複数の対局を並列で実行するようにする。

各対局の探索でニューラルネットワークの計算を行うが、それらはキューにためてミニバッチで処理することで、ボトルネックとなるニューラルネットワークの計算を効率化する。

実験結果

以上のように実装した自己対局プログラムで教師局面の生成を行った。

32スレッドで実行して、プレイアウト数を1000とすると、1秒間で平均2.62個の教師局面が生成できた。

AlphaGo Zeroでは1回のイテレーションで、25,000局を実行している。
囲碁の平均手数を200とすると、1イテレーションで、5,000,000局面を生成している。

AlphaGo Zeroと同様に1イテレーションを5,000,000局面とすると、1イテレーションの実行には、530時間=22日かかる。

これでは時間がかかりすぎなので、プレイアウト数と1イテレーションの局面数を減らして、モデルを強くできるか今後実験してみたい。

↓自己対局のソースを公開しました。
github.com