TadaoYamaokaの日記

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

optunaで探索パラメータの最適化

optunaを使って将棋プログラムの探索パラメータの最適化を行うツールを作成した。
Pythonで実装しており、任意のUSIエンジンの間で指定した回数対局を行い、勝率が最大となるように探索パラメータを最適化する。

DeepLearningShogi/mcts_params_optimizer.py at master · TadaoYamaoka/DeepLearningShogi · GitHub

最適化するパラメータ

探索パラメータは、USIオプションで変更可能としておく。
パラメータの値の範囲などを設定ファイルで設定可能にすることも考えたが、汎用性はあまり必要ないのでスクリプトに直接記述することにした。
パラメータを最適化するのは、1つのエンジン(オプションのcommand1)のみである。

optuna

パラメータの最適化には、optunaを使用した。
hyperoptという選択もあったが、試したところ、hyperoptよりも収束が速く、見込みがない試行を枝刈りする機能もあるのでoptunaにした。
optunaは、現バージョンでは最小化にしか対応していないため、勝率に-1を掛けて負の値を返す必要がある。

回数の指定

勝率の測定は、デフォルトで100回(optunaの単位ではステップ)対局して行う。
それを、デフォルトで100回試行して最適化を行う。
それぞれ、オプションで回数を指定できる。

枝刈り

optunaで枝刈りを有効にすると、各試行の同じステップでの中央値を基準として枝刈りが行われる。
デフォルトでは、0ステップから比較が行われるため、たまたま初めの2局連続で負けるとすぐに枝刈りになってしまうため、オプションで枝刈り開始を20ステップ目以降とした。

対局条件

秒読み(デフォルト1秒)のみで、時間切れ負けの判定は行っていない。
最大手数(デフォルト256)に達すると、引き分けとする。

勝敗の条件

終局まで対局すると時間がかかるため、どちらかのエンジンが詰みを見つけた時点で相手を強制的に投了させるようにした。
エンジンの詰みの判定が誤っていると正しく動作しないため、エンジンにバグがない前提である。
また、エンジン自体に投了の閾値の設定がある場合は、設定を行う(スクリプトに直書きしてある)。

開始局面

sfenファイルから、ランダムに開始局面を選んで、先後入れ替えて対局できるようにした。
やねうら互角局面集などが使用できる。

ログ

対局中の情報やoptunaの最適化の結果は、ログに出力する。
デフォルトではコンソールに出力し、オプションを指定した場合はファイルに出力する。

棋譜の保存

後で棋譜を確認できるように1対局ごとに、.kifファイルで保存するようにした。
(.kifフォーマットは、人には見やすいが、プログラムには優しくなかった・・・)

使用例

python mcts_params_optimizer.py --command1 "C:\DeepLearningShogi\x64\Release\usi.exe" --command2 "C:\gpsfish\gpsfish.exe" --byoyomi 1000 --model "D:\model\model_rl_val_wideresnet10_selfplay_078" --batch_size 168 --initial_positions "D:\shogi\gokaku\records2016_10818.sfen" --kifu_dir D:\kifu\param_opt --log D:\log\param_opt.txt

※オプションmodel、batch_sizeは、dlshogiに特化したオプションなので他のエンジンには不要

出力例

2019/01/06 20:49:38	INFO	Finished a trial resulted in value: -0.3854166666666667. Current best value is -0.3854166666666667 with parameters: {'C_init': 128, 'C_base': 38360}.

※パラメータC_initと、C_baseを最適化している。valueは-1を掛けた勝率となっている。


ということで、optunaで探索パラメータを最適化したい方は、パラメータに応じた変更が必要ですが、ご自由にどうぞ。