TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

【dlshogi】dlshogiモデルでNNUEの評価値を付け替える その7

前回、dlshogiの最新モデルで、自己対局して生成した教師データを、同じモデルで推論した結果に付け替えることで、モデルサイズによらず精度が上がる傾向があることを確かめた。

今回は、dlshogiの最新モデルではなく、既存の教師データを使い、そのデータを学習したモデルで、同じ教師データの付け替えを行って、再度初期から学習した場合に精度が上がるか確認する。
これにより、モデルの推論結果が、学習した教師データ以上に、精度を上げる効果があるかがわかる。

また、学習に使用していない局面の付け替えを行って、学習に使用したデータに追加して学習した場合に精度が上がるかも確認する。

既存の教師データ

dlshogiの探索ありで自己対局して生成した50,878,296局面を学習する。

比較パターン

  1. 既存の教師データを学習したモデル
  2. 1.のモデルで、既存の教師データの付け替えを行ったデータを学習したモデル
  3. 1.のモデルで、新規のデータの付け替えを行って、既存の教師データに加えて学習したモデル
  4. 1.のモデルで、新規のデータの付け替えを行って、2.と同様に既存の教師データの付け替えを行ったデータに加えて学習したモデル

新規のデータには、nodchip氏が公開しているtanuki-の教師データから抽出した63,965,555局面を使用する。

付け替え

方策、価値、勝敗を係数1で完全に推論結果に付け替える。

学習条件

  • バッチサイズ: 4096
  • エポック数: 8
  • 評価値と結果の加重平均の按分係数(val_lambda): 0.333
  • 学習率: 0.04から1エポックごとに半減
  • オプティマイザ: MomentumSGD
  • 同一局面は平均化
  • モデル: ResNet 20ブロック256フィルタ

評価精度

テストデータに、2017年~2018年6月のfloodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用して、評価した結果は以下の通り。

パターン 方策損失 価値損失 方策正解率 価値正解率
1 1.6481 0.5526 0.4716 0.7021
2 1.6960 0.5343 0.4708 0.7143
3 1.6811 0.5270 0.4793 0.7195
4 1.5988 0.5296 0.4858 0.7172


パターン1(既存の教師データを学習)とパターン2(付け替えたデータを学習)を比較すると、パターン1の方が方策の精度が高く、パターン2の方が価値の精度が高い。
方策と価値の精度は、学習が進む過程で、どちらかに一時的に偏ることがあるため、どちらが良いとも言い難い。
少なくとも価値に関しては、モデルの推論結果に付け替えを行ったデータで、元の学習に使用したデータ以上の精度を出せるようだ。

パターン3(新規の付け替えたデータを既存データに加えて学習)とパターン4(新規の付け替えたデータを既存データを付け替えたデータに加えて学習)は、パターン1とパターン2と比較して、はっきりと方策、価値ともに精度が上がっている。
新規データはモデルの推論結果に完全に付け替えているため、局面さえあれば差し手や評価値、対局結果は不要である。
つまり、生成コストがかからないデータを使用することができ、それを付け替えたデータを加えることで、精度を向上できるということである。

パターン3とパターン4の比較では、方策損失はパターン4が小さくで、価値損失はパターン3の方が少しだけ小さい。
新規の付け替えたデータを加える場合、既存データも付け替えた方がよさそうである。

大きなサイズのモデル

ResNet 30ブロック384フィルタのモデルでも検証した。

パターン 方策損失 価値損失 方策正解率 価値正解率
1 1.6482 0.5961 0.4757 0.6871
2 1.6824 0.5313 0.4768 0.7160
3 1.7229 0.5293 0.4819 0.7176
4 1.5860 0.5432 0.4914 0.7105

各パターンの傾向は、ResNet 20ブロック256フィルタの場合と同じである。

まとめ

既存の教師データを学習したモデルで、学習に使用したデータの付け替えを行って、初期から再度学習した場合に、学習した教師データ以上に、精度を上げる効果があるか確認した。
結果、少なくとも価値については、推論結果に付け替えた場合、元の教師データ以上の精度になった。

また、新規の付け替えたデータを、元の教師データに加えて学習した場合、大きく精度が向上することが確認できた。
新規のデータは、局面さえあればよく、生成コストがかからないため、少ないコストでモデル精度を向上できる。

前回の記事でも書いたが、画像認識の分野では、ラベルなしデータに疑似ラベルを付けて学習する半教師あり学習の手法は以前から行われている。
それと同様の効果が将棋AIの学習でも得られることが分かった。

強化学習の課題でもあるサンプル効率の低さを、ある程度解決できる手法が発見できたかもしれない。

自己対局で生成したデータ+疑似ラベルを付けたデータで学習するという手法は、今後将棋AIの学習で主流になりそうである。

【dlshogi】dlshogiモデルでNNUEの評価値を付け替える その6

前回、dlshogiのモデルの自己対局で生成した教師データの方策、価値、勝敗を、同一モデルで推論した結果に付け替えた場合、精度が上がることを観測した。
自己対局で探索した教師データより、探索なしで推論した結果の方が精度が上がるのは予想外の結果だった。

前回は、ResNet 20ブロック256フィルタのモデルを学習したが、より大きなサイズでも同じ傾向になるか検証する。

モデルサイズ

今回は、最新のdlshogiと同じResNet+Transformerの40ブロック512ブロックのモデルを学習する。

精度が教師データを学習のしやすさに関連するのであれば、サイズの大きなモデルであれば、探索ありの教師データを学習できるはずである。

精度評価

付け替え条件

加重平均の係数0.9、0.1、0.05、0.01で、方策、評価値、勝敗を付け替える。

比較のために、付け替えない条件でも学習する。

データ数

前回と同じ、自己対局で生成した教師データの同一局面を平均化した50,878,296局面を学習する。

学習条件

前回と同じ条件とする。

  • バッチサイズ: 4096
  • エポック数: 8
  • 評価値と結果の加重平均の按分係数(val_lambda): 0.333
  • 学習率: 0.04から1エポックごとに半減
  • オプティマイザ: MomentumSGD
  • 同一局面は平均化
  • モデル: ResNet 20ブロック256フィルタ
  • 評価値の付け替えに使用するモデル: dlshogiの40ブロック512フィルタのモデル
学習結果

テストデータに、2017年~2018年6月のfloodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用して、評価した結果は以下の通り。

今回(ResNet+Transformer 40ブロック512フィルタ):

加重平均の係数 方策損失 価値損失 方策正解率 価値正解率
0.9 1.5676 0.4880 0.5053 0.7471
0.1 1.6538 0.5754 0.4818 0.6950
0.05 1.6674 0.5812 0.4809 0.6945
0.01 1.6865 0.5972 0.4806 0.6917
0 1.6829 0.6057 0.4789 0.6877

前回(ResNet 20ブロック256フィルタ):

加重平均の係数 方策損失 価値損失 方策正解率 価値正解率
0.9 1.6183 0.5150 0.4846 0.7300
0.1 1.6400 0.5388 0.4733 0.7096
0.05 1.6521 0.5488 0.4708 0.7032
0.01 1.6517 0.5531 0.4712 0.7014
0 1.6481 0.5526 0.4716 0.7021

付け替えなし(係数0)では、前回の方が精度が高い。
サイズの大きなモデルは探索ありの教師データをより学習できると考えたが、そのような結果にならなかった。

付け替え(係数0.9)を行ったデータでは、サイズの大きなモデルの方が精度が高い。
付け替えを行うと精度が上がるという事象は、サイズの大きなモデルでより顕著になった。

まとめ

探索ありの教師データを、同一モデルの推論結果に付け替えると精度があがる事象は、サイズの大きなモデルでも同じ傾向になった。

探索なしのデータで精度が上がる理由ははっきりしないが、画像認識の分野では、ラベルなしデータに疑似ラベルを付けて学習する半教師あり学習の手法は以前から行われているので、それと同様の効果があるのかもしれない。

これまで、将棋AIの強化学習では、モデルを改善するには、探索をして自己対局した教師データが必要と考えられていたが、単に学習済みモデルで推論しただけのデータを学習することで精度があるのであれば、サンプル効率の高い学習方法が見つかったと言える。


今回の検証に使用したデータ量は5千万局面と少なく、収束するまで学習できていないので、より多くのデータ量で収束するまで学習するとどうなるかは別途検証したい。

今回は、最新のdlshogiのモデルで付け替えを行ったが、モデルを訓練した後に同じモデルで付け替えて、同じサイズのモデルが学習した場合にも効果があるか検証したい。
また、訓練に使用していない新規の局面を加えて付け替えして学習した場合どうなるか検証したい。

【dlshogi】dlshogiモデルでNNUEの評価値を付け替える その5

前回、NNUE系のtanuki-で生成した教師データを使用して、dlshogiのモデルで方策と評価値、勝敗を付け替えた場合に、dlshogiの推論結果で付け替えた方が精度が上がることが確認できた。

今回は、dlshogiの最新モデルの自己対局で生成したデータに対して、同一モデルで付け替えを行った場合、どうなるか追加で検証したい。
データの質は下がるはずだが、加重平均の係数0.1など小さい値であれば、ラベルスムージングの効果が得られるかもしれない。

自己対局データ

dlshogiの最新のモデルで、平均で約7500ノード探索して自己対局した教師データを使用する。
探索ノード数は、探察打ち切りや延長を行っているため、局面により異なっている。
開始局面は、dlshogの定跡に登録されている局面から抽出している。

精度評価

付け替え条件

加重平均の係数0.9、0.1、0.05、0.01で、方策、評価値、勝敗を付け替える。

比較のために、付け替えない条件でも学習する。

データ数

同一局面を平均化した後で50,878,296局面を学習する。

データ数は、前回の77%程である。

学習条件

前回と同じ条件とする。

  • バッチサイズ: 4096
  • エポック数: 8
  • 評価値と結果の加重平均の按分係数(val_lambda): 0.333
  • 学習率: 0.04から1エポックごとに半減
  • オプティマイザ: MomentumSGD
  • 同一局面は平均化
  • モデル: ResNet 20ブロック256フィルタ
  • 評価値の付け替えに使用するモデル: dlshogiの40ブロック512フィルタのモデル
学習結果

テストデータに、2017年~2018年6月のfloodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用して、評価した結果は以下の通り。

加重平均の係数 方策損失 価値損失 方策正解率 価値正解率
0.9 1.6183 0.5150 0.4846 0.7300
0.1 1.6400 0.5388 0.4733 0.7096
0.05 1.6521 0.5488 0.4708 0.7032
0.01 1.6517 0.5531 0.4712 0.7014
0 1.6481 0.5526 0.4716 0.7021

同一モデルで探索して生成したデータを、探索なしで推論した結果に付け替えるので、精度は下がると予想していたが、加重平均の係数0.9で付け替えた場合が最も精度が高くなった。

学習の精度は、教師データの学習しやすさと関係しているかもしれない。
探索して生成したデータは、局面を先読みした結果なので、読むことができないモデルには学習が難しいのかもしれない。

教師データは、必ずしも深く探索したデータがよいとは限らないという仮説が成り立ちそうである。

まとめ

dlshogiの最新モデルの自己対局で生成したデータに対して、同一モデルで付け替えを行った場合、精度がどうなるか検証した。
結果、同一モデルで生成したデータでも付け替えを行った方が精度が上がるという結果になった。
データの質は下がるはずなので、精度が下がると予想したが、予想に反する結果になった。
学習の精度は、データの学習のしやすさと関連している可能性がある。

より大きなパラメータ数のモデルで学習した場合は、読みの結果を反映できるのか追加で検証したい。

【dlshogi】dlshogiモデルでNNUEの評価値を付け替える その4

前回、NNUE系で生成した教師データの方策と評価値に加えて、勝敗もdlshogiのモデルで推論した結果に付け替えた方が精度が上がることを確かめた。

前回までは、2020年にNNUE系で生成した教師データを使用したが、nodchip氏が公開している最近のNNUEで生成した教師データでも同じ傾向になるか追加で検証する。

nodchip氏が公開している教師データ

最新のtanuki-で深さ9で生成した80億局面を公開している。

前回までの検証に使用したデータは、100万ノードで探索しているのに比べ、深さ9で生成したデータは、局面により探索ノード数が異なるが、多くても数万ノードくらいであり、探索ノード数は少ない。

精度評価

付け替え条件

前回までの検証結果を踏まえ、加重平均の係数0.9、0.95で、方策、評価値、勝敗を付け替える。

比較のために、付け替えない条件でも学習する。

データ数

前回の条件に近づけるため、公開されているデータの9ファイル分を使用して、70,689,473局面、同一局面を平均化した後で65,802,717局面を学習する。

前回までデータは、平均化した後、63,965,555局面である。前回より少し多い。

学習条件

前回と同じ条件とする。

  • バッチサイズ: 4096
  • エポック数: 8
  • 評価値と結果の加重平均の按分係数(val_lambda): 0.333
  • 学習率: 0.04から1エポックごとに半減
  • オプティマイザ: MomentumSGD
  • 同一局面は平均化
  • モデル: ResNet 20ブロック256フィルタ
  • 評価値の付け替えに使用するモデル: dlshogiの40ブロック512フィルタのモデル

評価値と結果の加重平均の按分係数が1/3になっているが、訓練するキャッシュデータを作成する時点でモデルの推論結果を反映している。

学習結果

テストデータに、2017年~2018年6月のfloodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用して、評価した結果は以下の通り。

加重平均の係数 方策損失 価値損失 方策正解率 価値正解率
0.95 1.5930 0.4902 0.4921 0.7426
0.9 1.5774 0.4924 0.4926 0.7414
0 1.6888 0.5587 0.4644 0.7120

加重平均の係数0は、モデルの推論結果を使わないことを意味する。

加重平均の係数0.9のとき方策の損失が最小になり、加重平均の係数0.95のとき価値の損失が最小になっている。

いづれにしろ、付け替えを行った方が精度が高くなっている。


前回の結果と比較すると、付け替え後の精度は近い精度になっている。

\lambda_{val} 方策損失 価値損失 方策正解率 価値正解率
0.95 1.5841 0.4913 0.4894 0.7419
0.9 1.5735 0.4892 0.4917 0.7435

付け替え前のデータ(元データ)では、前回までのデータの方が精度が高い。

加重平均の係数 方策損失 価値損失 方策正解率 価値正解率
0 1.6446 0.5151 0.4732 0.7272

tanuki-のデータは探索ノード数が少ないため、2020年のNNUE系で100万ノードで生成したデータの方が質が良いようである。

まとめ

nodchip氏が公開している最近のNNUEで生成した教師データを使用して、dlshogiのモデルで方策と評価値、勝敗を付け替えた場合に、前回までと同じ傾向になるか検証した。
結果、前回までと同じくdlshogiの推論結果で付け替えた方が精度が上がることが確認できた。

dlshogiの最新モデルの自己対局で生成したデータに対して、同一モデルで付け替えを行った場合、どうなるか追加で検証したい。
データの質は下がるはずだが、加重平均の係数0.1など小さい値であれば、ラベルスムージングの効果が得られるかもしれない。

【dlshogi】dlshogiモデルでNNUEの評価値を付け替える その3

前回、NNUE系で生成した教師データの方策と評価値をdlshogiのモデルで推論した結果に付け替えることで、方策と評価値ともに精度が上がることを確認した。

今回は、学習の損失の勝敗項についても、モデルで推論した価値に付け替えることで、精度が上がるか試した。

勝敗項

学習の損失は、方策の交差エントロピーと評価値(Q値)の交差エントロピーと勝敗の交差エントロピーの3つの項の重み付き和で計算する。

評価値の項 L_{val} と勝敗の項 L_{result} は、パラメータ \lambda_{val} を使用して、
 \lambda_{val} L_{val} + (1 - \lambda_{val}) L_{result}
で、按分する。

dlshogiのデフォルトでは、\lambda_{val} = 1/3 に設定されており、評価値の項より勝敗の項の方が重視されている。

勝敗項の付け替え

前回作成した方策と評価値を付け替えたデータを流用して、\lambda_{val} の値を変更して、勝敗項の重みを減らした場合に、精度が上がるか確認する。
\lambda_{val} = 1 の場合、勝敗項を使わないことを意味する。

精度評価

教師データ

前回同様、2020年にNNUE系で生成した教師データ65,267,650局面を使って検証する。
キャッシュを作成する際に、同一局面の平均化を行うので、訓練データ数は、63,965,555局面になる。

学習条件

前回と同じ条件とする。

  • バッチサイズ: 4096
  • エポック数: 8
  • 学習率: 0.04から1エポックごとに半減
  • オプティマイザ: MomentumSGD
  • 同一局面は平均化
  • モデル: ResNet 20ブロック256フィルタ
  • 評価値の付け替えに使用するモデル: dlshogiの40ブロック512フィルタのモデル
学習結果

テストデータに、2017年~2018年6月のfloodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用して、評価した結果は以下の通り。

\lambda_{val} 方策損失 価値損失 方策正解率 価値正解率
1 1.5752 0.4888 0.4932 0.7438
0.95 1.5841 0.4913 0.4894 0.7419
0.9 1.5735 0.4892 0.4917 0.7435
0.7 1.5778 0.4883 0.4923 0.7428
0.5 1.5819 0.4910 0.4918 0.7411
0 1.6117 0.7419 0.4830 0.7006

\lambda_{val} = 0.9 のとき、方策の損失が最小になり、\lambda_{val} = 0.7 のとき、価値の損失が最小となった。
\lambda_{val} = 1 のとき、方策、損失がバランスよく小さくなっている。

\lambda_{val} = 0 のとき、つまり評価値の項を使わず勝敗の項のみを使用した場合が最も精度が低かった。

勝敗の項についても付け替えを行った方がよいことが分かった。

まとめ

NNUE系で生成した教師データの勝敗の項もモデルの推論結果で付け替えた方がよいか検証した。
結果、勝敗の項も付け替えた方が、方策と価値ともに精度が上がることが確認できた。

今回までの一連の実験では、2020年にNNUE系で生成した教師データを使用したが、nodchip氏が公開している最近のNNUEで生成した教師データでも同じ傾向になるか追加で検証したい。

【dlshogi】dlshogiモデルでNNUEの評価値を付け替える その2

前回、NNUE系で生成した教師データの評価値をdlshogiのモデルで推論した評価値に付け替えることを試した。

今回は、方策についてもモデルの推論結果に付け替えることを検討する。

方策の付け替え

NNUE系で生成した教師データは、最善手のみが記録されているが、モデルの推論結果はすべての差し手について確率が出力される。
最善手1手のみよりも、すべての差し手の確率を使用した方が、情報量が多いため学習の効率が良い。
よって、方策は差し手の確率を使用することにする。

教師データフォーマット

hcpe形式の教師データは差し手1手のみしか記録できないため、hcpe3のキャッシュフォーマットを使用する。

hcpe3形式でも記録できるが、局面の入力特徴量を作成するのに棋譜の再生を行う必要があるため、モデルで推論する際に、バッチ処理が行いにくい。
キャッシュフォーマットは、局面単位に記録しているので、バッチ処理が行いやすい。

方策のフィルタ

方策は、非合法手も含む2187次元のベクトルになる。
すべての差し手を記録するとデータ量が膨大になる。
そのため、合法手でフィルタして、最善手から勝率の低下が一定範囲、かつ上位N件のみを記録することにする。

以下の実験では、50%低下、10件までとする。

加重平均

教師データの評価値を付け替える手法は、加重平均の係数=1でモデル蒸留するのと行っていることは同じである。
モデル蒸留と同様に加重平均の係数も設定できるようにする。

精度評価

教師データ

前回同様、2020年にNNUE系で生成した教師データ65,267,650局面を使って検証する。
キャッシュを作成する際に、同一局面の平均化を行うので、訓練データ数は、63,965,555局面になる。

学習条件

前回と同じ条件とする。

  • バッチサイズ: 4096
  • エポック数: 8
  • 評価値と結果の加重平均の係数(val_lambda): 0.333
  • 学習率: 0.04から1エポックごとに半減
  • オプティマイザ: MomentumSGD
  • 同一局面は平均化
  • モデル: ResNet 20ブロック256フィルタ
  • 評価値の付け替えに使用するモデル: dlshogiの40ブロック512フィルタのモデル

加重平均の係数を、1、 0.95、 0.9、0.5、0に変えて比較する。
1.0は付け替えを意味して、0は付け替えないこと(元の教師データのまま)を意味する。

また、価値のみを付け替えた場合とも比較する。

学習結果

テストデータに、2017年~2018年6月のfloodgateのR3500以上の棋譜からサンプリングした856,923局面(重複なし)を使用して、評価した結果は以下の通り。

係数 方策損失 価値損失 方策正解率 価値正解率
1 1.6132 0.5088 0.4848 0.7311
0.95 1.5841 0.5044 0.4906 0.7338
0.9 1.5987 0.5062 0.4864 0.7319
0.5 1.5955 0.5063 0.4840 0.7312
0 1.6446 0.5151 0.4732 0.7272
価値のみ 1.6454 0.5093 0.4725 0.7294

今回計測した係数では、0.95のときに方策損失、価値損失が最小になった。

前回と同様に価値のみを付け替えた場合と比較して、方策も付け替えた場合、方策、価値ともに精度が向上している。

まとめ

NNUE系で生成した教師データの評価値に加えて方策もdlshogiのモデルで推論した方策に付け替えて学習することで精度が向上するか検証した。
結果、方策も付け替えることで、方策、価値ともに精度が上がることを確認できた。

勝敗項についても、元の教師データの値を使わない方がよいか追加で検証したい。

【dlshogi】軽量価値ネットワーク その2(Stockfishの探索)

前回試した軽量価値ネットワークをStockfishの探索に組み込むことを検討している。
最終的には、dlshogiのMCTSベースの探索とStockfishベースの探索を組み合わせることを構想しているが、まずは、単体で動作するStockfishベースのプログラムを作りたい。

実装方針

今後、dlshogiの探索と組み合わせる際に、効率的に組み合わせるには、一つのプログラムで局面の情報を共有したいため、現在のAperyベースのdlshogiの局面管理(Positionクラス)や、指し手生成(MoveListクラス)などは、共通化したい。

既存のPositionやMoveListなどは、Stockfishの探索部にそのまま適用することができない部分があるため、接合する仕組みが必要になる。

その方法として、以下の案を考えた。
1. 既存のクラスをStockfishベースに置き換える
2. まったく別に作成して、情報を受け渡す際の変換処理を実装する
3. 既存のクラスを継承して、不足部分と置換する部分のみを開発する

1.は、今後Stockfishのソースを流用しやすくなるメリットがあるが、将棋特有の処理を一から実装する必要があり、既存のdlshogiにも影響するので、作業量が多い。
2.は、既存のdlshogiには影響しないが、やはり将棋特有の処理を実装するのが大変である。
3.は、不足部分と置換する部分のみを開発すれば良く、既存のdlshogiへの影響も小さい。

作業量を優先して、3.の方法で実装することにする。

既存のクラス・構造体を継承して実装する場合、既存のクラス・構造体のメモリ配置は変えられないため、既存のクラス・構造体に一部フィールドを追加することになる。
dlshogi側のメモリ消費が無駄に増えるため、できれば影響がない方法で実装したいが、いったん気にせず後で考えることにする。

既存のクラス継承したクラス

Stockfishの名前空間で、既存のクラスを継承して同名のクラスを定義する。
いったん継承しただけのクラスを定義して、Stockfishから流用した探索の処理で、コンパイルエラーになる箇所について、追加実装する。

名前のみの違いの場合は、Stockfishのコードを修正しないで良いように、別名で定義し直す。
追加で必要なメソッドは追加で実装する。

Positionクラスの例:

class Position : public ::Position {
    ...

    // Doing and undoing moves
    void do_move(Move m, StateInfo& newSt) { doMove(m, newSt); } // 名前変換
    void undo_move(Move m) { undoMove(m); } // 名前変換
    void do_null_move(StateInfo& newSt, const TranspositionTable& tt); // 追加実装
    void undo_null_move(); // 追加実装

    // Static Exchange Evaluation
    bool see_ge(Move m, int threshold = 0) const; // 追加実装

    ...
};

Stockfishのコード流用

Stockfishのコードをコピーして、既存クラスから継承したクラスに置き換えたことで、コンパイルエラーになる箇所を修正する。
また、チェス固有の処理を将棋固有の処理に置き換える。

推論処理

前回試した軽量の畳み込みニューラルネットワークの推論を効率的に探索に組み込には、NNUEのように入力層の差分更新を行おうとすると、実装が大変になる。
いったん、差分更新は実装しないで、毎回特徴量を作成して、入力層を計算することにする。
入力層はEmbeddingを使うので、辞書引きと加算なので、そこまで遅くはならない見込みである。

推論処理は、いったんLibTorchを使って独自実装を省くことにする。
CPUで高速に推論するには量子化が必要なため、PyTorchで量子化認識トレーニング量子化する。
torch.compileでモデルを最適化して、MKLをバックエンドに使えば、独自実装するよりも速い可能性もあるが、パフォーマンスがでなければ後で考える。

実装

実装に着手したが、1日、2日では終わらない作業量である。
将棋固有の処理は、やねうら王の実装も参考にしながら実装している。

実装中に、やねうら王のバグを見つけて、PRを上げた。
最下位ビット以外が1になる場合があるバグ修正 by TadaoYamaoka · Pull Request #297 · yaneurao/YaneuraOu · GitHub

SEE (Static Exchange Evaluation)の処理で、連続した駒の交換を評価する際に、桂馬の交換時に2枚以上の桂馬の効きがあると1つしか考慮されない場合があるというバグである。
PRマージ後に、やねうらお氏が計測したところ、頻度が少ないため棋力にはほぼ影響はなかったようである。

まとめ

軽量価値ネットワークをStockfishの探索に組み込むために、Stockfishベース探索の実装を始めた。
最小限の作業量でいったん完成させるつもりだが、それでもまだ時間はかかりそうである。
Stockfishの探索について理解を深めたいという目的もあるので、実装しながら理解していくつもりである。