前回、nnue-pytorchをWindowsとLinuxで動作確認した。
今回は、前回説明したqsearchで動く局面を除外した場合としない場合で精度の比較を行った。
qsearch除外の実装
Stockfishのnnue-pytorchの--smart-fen-skippingは、学習の実行時に指し手が駒をとる手と王手の局面を除くようになっているが、epochごとに繰り返し実行されるため学習時に実行するのは効率が悪い。
そこで、事前にすべての訓練データに対してqsearchを実行して、qsearchのPVが1以上の局面を除く処理を実装した。
(実行時に除くにはqsearchをマルチスレッドで動くようにするのが面倒だったという理由もある。)
filter_psvというツールを実装した。
nnue-pytorch/filter_psv at develop · TadaoYamaoka/nnue-pytorch · GitHub
シングルスレッドで実装しているが、ファイル単位でマルチプロセスで実行することで効率を上げることができる。
Linuxでは、xargsを使うと便利である。
コマンド例:
ls *.evalfix.psv.bin | xargs -n 1 -P 128 -i sh -c '/work/nnue-pytorch/filter_psv/filter_psv {} $(basename {} .psv.bin).filtered.psv.bin'
シャッフルの実装
nnue-pytorchは、訓練データをシャッフルする処理が実装されていない。
PyTorchのデータローダの機能で1epochごとにシャッフルを行うのが一般的だが、nnue-pytorchはバッチデータの作成を独自に実装しているため、標準のシャッフル処理が実行できない。
また、epochの概念がファイルのデータを使い切る単位ではなく、100000000局面を1epochとしている。
訓練データの局面は、epochとは関係なく順番に読み込み、使い切ったら初めから読み直す。
シャッフルは、学習実行前に、別のツールで行うことを想定している。
事前にシャッフルを行うのが手間がかかるのと、ファイルを使い切るごとに再シャッフルを行う方がよいため、nnue-pytorchにシャッフル処理を実装した。
訓練データの局面数分のインデックスの配列を作成し、シャッフルを行い、シャッフルしたインデックスの順にデータを使うようにする。
データを使い切ったら再シャッフルする。
ファイルのランダムアクセスが必要になるため、システムコールを減らすため事前に全て読み込むようにした。
実行環境のメモリが十分にないと実行できないが、全データを読み込めるメモリが十分にある環境で実行する想定である。
(最近のOSは、ページファイルをキャッシュするので、ファイルをランダムアクセスしてもそれほど性能劣化しないとは思うが。)
使用データ
訓練データには、最新のdlshogiの20ブロックのモデルの自己対局で生成した4.5億局面を、テストデータには、floodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用した。
qsearchのフィルタ処理
訓練データにqsearchのフィルタ処理を実行した結果、約3億局面(65%)が残った。
実行結果
100epoch訓練した結果、訓練損失と評価損失は、以下の通りになった。
青がqsearchのフィルタ処理なし、赤がqsearchのフィルタ処理ありである。
train_loss
val_loss
訓練損失(train_loss)の考察
訓練損失は、qsearchのフィルタ処理ありの方が、明確に低くなっている。
qsearchのフィルタ処理ありの方が、学習が進みやすいことがわかった。
評価損失(val_loss)の考察
しかし、floodgateの棋譜に対する評価損失は、どちらも上昇しており、訓練データに過剰適合している。
qsearchのフィルタ処理ありの方が、損失が高くなっており、訓練損失とは逆の結果になった。
テストデータにfloodgateの棋譜を使った理由は、訓練データを生成した方法とは異なるデータで評価した方がより強さと相関が見られると考えたためである。
しかし、NNUEの学習では、訓練データとは性質が異なるデータでは評価ができないようだ。
dlshogiの学習では、floodgateの棋譜との一致率と強さに相関があることを確かめているので、同じ方法をとったが、NNUEの評価には使えないようである。
強さを確認するには、実際に対局して確かめる必要がありそうである。
強さの確認
実際に対局を行い強さを確認した。
1手3秒、8スレッドで、互角局面集を使用して計測した。
基準ソフトとして、1手100ms、2スレッドの水匠5をリーグに追加している。
結果は以下の通りとなった。
# PLAYER : RATING ERROR POINTS PLAYED (%) CFS(%) W D L D(%) 1 suisho5-2th : 324.8 20.4 2228.0 2370 94 100 2228 0 142 0 2 qsearch-8th : -118.8 13.2 828.5 2375 35 100 825 7 1543 0 3 normal-8th : -206.0 14.8 505.5 2379 21 --- 502 7 1870 0
qsearch-8thがqsearchのフィルタあり、normal-8thがqsearchのフィルタなしである。
qsearchのフィルタありの方が、R+87.2だけ強くなることが確認できた。
なお、4.5億局面を100epoch学習しただけでは、水匠5とは相当レーティングの差がある。