NNUE評価関数の学習方法について

やねうら王でNNUE評価関数の学習をする方法について解説記事がなかったのでざっとまとめておきます。

教師局面の生成

gensfenコマンドを使います。KPPT型のときと同じなので割愛。

学習用の実行ファイルのビルド(MSYS2)

OpenBlasという行列演算などが速くなるライブラリを有効にしてビルドします。(OpenBlasが有効でないと学習に倍以上時間がかかります。)

MSYS2上でビルドするとき、pacmanでOpenBlasをインストールします。(32bit版のときは、OpenBlasを用いないので以下の操作は不要)

64bit版
$ pacman -S mingw-w64-x86_64-clang mingw-w64-x86_64-toolchain mingw-w64-x86_64-openblas

あとはMakefileを使って、そのままビルドできるかと思います。

$ mingw32-make clean YANEURAOU_EDITION=YANEURAOU_2018_TNK_ENGINE
$ mingw32-make -j8 evallearn COMPILER=g++ YANEURAOU_EDITION=YANEURAOU_2018_TNK_ENGINE

学習用の実行ファイルのビルド(Visual Studio)

Visual Studio上でビルドする場合、USE_BLASを定義してやります。これはプロジェクトの設定のほうでやってもいいですし、extra/config.hに

#define USE_BLAS

などと追加しても良いです。次に、”libopenblas.dll.a”というファイルをlibとして追加して、実行ファイルの配置されるフォルダにlibopenblas.dll , libgcc_s_seh-1.dll , libgfortran-3.dll , libquadmath-0.dll を配置します。

このへんの手順の解説は以下の記事に譲ります。

[VC++] OpenBLASを使ってみた : https://qiita.com/t–k/items/69c43a667a1283578012

libgcc_s_seh-1.dll , libgfortran-3.dll , libquadmath-0.dllは、MSYS2のなかにあるようですが、私はOpenBlasのサイトからダウンロードしてきて配置しました。

※ https://sourceforge.net/projects/openblas/files/v0.2.12/mingw64_dll.zip/download

学習時オプション


を参考に。

KPPT型との違い
・eta 1.0 ぐらいにすべき(KPPTのときのように32とかにすると発散する)
・mirror_percentage 50 : これを指定しておくとミラーの次元下げをするのか学習効率が少しよくなる
・batchsize 1000000 : これで最初のうちは問題なさげ。これを変更してもあまり強さは変わらないっぽい
・lambda 0.5 : lambdaの最適値はよくわかっていない 0.5とか1.0とかで正常に学習できることは確認済み。
・nn_batch_size 1000 : とりあえずデフォルトのまま
・eval_limit 32000 : これの最適値もよくわかっていない
・validation_set_file_name (検証データファイルパス) : 学習のときのlossの計算をするために検証用のデータセットは別のものにしたほうが良いということで別の教師ファイルを指定できるようになっている(指定しなくとも学習自体はできる)
・newbob_decay 0.5 : これを指定すると学習のスケジューラーの挙動が変わる。eval_save_interval局面学習させるごとに前回のロスの値と比較して、ロスが下がっていない場合は、一旦前回の結果にロールバックし、内部的なetaの値をnewbob_decay倍したうえで学習を続行する。

あと、SkipLoadingEvalは、初回はtrueにしておかないと評価関数を読み込もうとして失敗するような。2回目以降はEvalDirオプションで評価関数の配置しているフォルダを指定すると良い。

学習コマンドの例)

$ YaneuraOu2018NNUE_LEARN.exe , evaldir eval\zero , evalsavedir yanehome\eval\learn_777 , threads 80 , hash 16 , evalshare false , skiploadingeval true , learn newbob_decay 0.5 mirror_percentage 50 nn_batch_size 1000 loop 1 basedir yanehome batchsize 1000000 eta 1 lambda 0.5 eval_limit 32000 save_only_once no_shuffle targetdir learn_sfen\sfen2018D10 , quit

学習時間・学習効率

40コアのPCで教師局面1億局面につき1時間程度。KPPT型の時の数倍ぐらいかかるようです。

以前公開していた月刊教師局面(depth 8で生成)、2億局面を用いて、ゼロから上の設定で学習させた場合、elmo(WCSC27)よりR200程度弱いものができました。

その他

NNUEの学習に関して、何か質問があればコメント欄にどうぞ。

ちなみに、NNUEは駒割(駒の価値)も全くのゼロから学習しているので、ゼロから棋譜を生成してそこから学習を繰り返すような場合、KPPT型に比べて時間がかかるかも…。

 

NNUE評価関数の学習方法について” への18件のコメント

  1. validation_set_fileとnewbob_decayについては使い方が非常に難しいですね。
    etaの値次第でeval_save_intervalの時に毎回rejectedされて全然学習が進まない事がよくあります。
    newbob_num_trialsがデフォルトでは2なので、2回rejectedされると次で学習が強制終了してしまうので、多めの数字にする必要があります。
    newbob_decayを1.0にしつつ、eta可変絞りを上手く設定してやった方が良いかもしれません。
    その場合はlogの中のlossを見比べて良かった物を選び出して採用する必要はありますね。

        • ほほー!これは実装が簡単でそこそこ期待できそうな手法ですね!
          (lossが下がることが確認できる “1 step” が小さくて済む場合ならば。NNUEでこの条件を満たすかは…わかりません。まあ、EvalSaveIntervalを1000万ぐらいに設定して、newbob_decay 0.5とかにしておけば、こまめにセーブして、そのときにloss下がってなからったらetaを1/2にしていくので、これくらいの挙動でもいいような気はしますけども。)

  2. これってShivorayのコードを弄ってできちゃったりします?その場合どこをどう弄ればいいんですかね

    • Shivorayで出来ないですし、やねうら王にはそのようなコマンドも用意してないです。ニューラルネットは単純には合成できない(合成しても意味がない)ので。
      ニューラルネットの研究を専門にしている人なら何らかアクロバティックな技で合成できるのかな?程度の意味です。

  3. すみません。やねうら王で教師局面を作っていたのですが、まったく進まなくなってしまいました。どうすれば良いでしょうか?
    YaneuraOu2018NNUE_learn_sse42.exe threads 4 , hash 4000 , bookmoves 32 , bookfile no_book , evaldir eval , gensfen depth 8 loop 1000000000 random_move_count 0 write_minply 1 write_maxply 160 eval_limit 3000 output_file_name generated_sfens.bin , quit

    • hashが小さすぎ&開始局面が1手目なので、初期局面に対応する置換表エントリーに詰みのスコアの局面が偶然書かれていて(hash衝突)、それで詰みのスコアなので即座に詰みのスコアが返ってくるのですが、eval_limit 3000になっているため、その情報はスキップされて…ということなのではないでしょうか。(´ω`) 以前は置換表、スレッドごとにわけてたのですが、これやると置換表効率落ちるので、それをやめた影響ですね。

      1秒間、教師情報の生成がなければ、TT.clear()を呼び出すなどすれば回避できます。あるいはply==1でabs(value)>=3000 みたいな値が返ってきたらTT.clear()を呼び出すだとか。

      まあ、しかし定跡なしで教師生成するのはお勧めしません…。

  4. やねうら王のhash 〇〇〇〇の設定についてですが、これを今余っているメモリをすべて使うような時はどのようにすればよいのでしょうか?hash 99999とかに設定すれば良いのでしょうか?

    • その機能はついてないです。
      (2エンジンでの対局ができなくなる、使っているうちに物理メモリが少し足りなくなってえらいことになる等が懸念されるため)

korokoro にコメントする コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です