TadaoYamaokaの開発日記

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

千日手を予測する

昨年11月に行われた第2回電竜戦では、A級リーグでは先手勝率が70%と高かったことがコンピュータ将棋関係者の間で話題になった。
また、戦型は相掛かりが多かった。
角換わりは後手が千日手を狙いやすく、有利な先手で後手に千日手にされないように定跡で角換わりを避けるチームが多かったためである。
dlshogiも、先手で定跡を用いない場合、角換わりを選択してしまうため、定跡作成時に序盤数手以内で角換わりになる手を2番目の候補と入れ替えて、角換わりを避けるようにした。
コンピュータ将棋では千日手が戦略において重要になりつつある。

現状の先手の千日手の回避方法と問題点

現在、dlshogiでは探索中に千日手になる場合は、千日手になった局面の価値をUSIオプションのDraw_Value_BlackとDraw_Value_Whiteで設定した値にしている。
Draw_Value_Blackは、先手の千日手の価値で、これを0.5より小さくし、後手の千日手の価値のDraw_Value_Whiteを0.5より大きくすることで、先手が千日手を選ぶことを回避している。

しかし、角換わりでは、80手を超えて千日手になる場合があり、序盤の探索では、上記の千日手の価値が探索結果に反映されない。

千日手を予測する

DL系チェスAIのLeela Chess Zeroでも、WDLヘッドと呼ばれる方法で、勝ち、引き分け、負けを別々に予測して、探索時に利用することを行っている。
コンピュータチェスでは引き分けが多く、引き分けが戦略において重要なため、2019年の段階で取り入れられている。

コンピュータ将棋でも千日手が重要になりつつあるため、ディープラーニングのモデルで、千日手を予測するようにして、その予測を探索に活かすことを考える。

Leela Chess Zeroでは、勝ちと負けも別々の出力にしているが、将棋では千日手の割合が勝ち、負けになる場合より低いため、勝ち、千日手、負けを合計1とする確率とすると、データの偏りの影響が大きくなる。
そこで、千日手のみを別の出力にして、勝ち、負けは従来通り2値分類とする。

千日手の予測を利用した探索方法

局面の千日手の予測値を[0, 1]の確率として出力し、勝敗の確率と同様にノードにバックアップする。

UCBを計算する際に、千日手の予測値に合わせて、価値の中心を0.5から、USIオプションDraw_Value_BlackとDraw_Value_Whiteに応じてずらすように線形に変換する。
こうすることで、先手の千日手の予測値が高い手の価値を、0.5から下げることができる。
同じ価値が0.5の手でも千日手の予測が低い場合は、そのまま値は0.5になる。

従来は、同じ価値が0.5と予測していた手でも、千日手になりやすさによって、差を付けることができる。

実験

千日手を予想できるか実験を行った。

ニューラルネットワークの変更

現在のdlshogiのResNet15ブロックのモデルに、千日手を2値分類で出力するヘッドを追加した。

教師データ

序盤の価値を学習したいため、初期局面集にはfloodgateの8手目までの頻出局面を使用し、そこから36手までランダム性あり(最善手から勝率差2.5%までを訪問回数に温度を適用した確率分布で選択)で自己対局を行い、1万プレイアウトで1億局面を生成した。

学習

バッチサイズ4096、学習率0.04、平均化あり、評価値補正ありで1エポック学習した結果は以下の通り。

2022/01/03 18:06:05     INFO    epoch = 1, steps = 16797, train loss avr = 1.8192283, 0.5921775, 0.5903943, 0.1420839, 2.5528958, test loss = 1.7488920, 0.5522317, 0.6426893, 0.0382176, 2.3694636, test accuracy = 0.4484011, 0.7039824, 0.9992594, test entropy = 1.6746912, 0.5955356

train loss avrと、test lossのカンマ区切りの3番目の値が千日手の損失、test accuracyの3番目の値が千日手の正解率である。

千日手の正解率は、ほとんどが千日手ではないため、1.0に近くなる。
データの比率に応じて重み付けする方がよいかもしれないが、一旦重みなしで学習した。

MCTSバックアップの結果

UCBの計算は従来のままで、300万プレイアウトを行い、千日手の予測をノードにバックアップした際、ルートノードの各子ノードの千日手の確率を確認した。
dlshogiのDebugMessageを有効にして各手の情報を出力した。

  • 平手開始局面
0:1g1f move_count:11735 nnrate:0.0611579 win_rate:0.495021 draw:0.0668833
1:2g2f move_count:2337361 nnrate:0.287791 win_rate:0.547377 draw:0.0605795
2:3g3f move_count:541 nnrate:0.00382443 win_rate:0.476003 draw:0.0561522
3:4g4f move_count:287 nnrate:0.00191426 win_rate:0.479923 draw:0.0649844
4:5g5f move_count:327 nnrate:0.00257173 win_rate:0.467597 draw:0.0595138
5:6g6f move_count:987 nnrate:0.007876 win_rate:0.46671 draw:0.0766365
6:7g7f move_count:538516 nnrate:0.324734 win_rate:0.542494 draw:0.0603726
7:8g8f move_count:65 nnrate:0.00160816 win_rate:0.29254 draw:0.0354054
8:9g9f move_count:14821 nnrate:0.0561628 win_rate:0.509682 draw:0.064395
9:1i1h move_count:5 nnrate:7.3459e-05 win_rate:0.41165 draw:0.0580017
10:9i9h move_count:10 nnrate:9.67965e-05 win_rate:0.437868 draw:0.0565541
11:3i3h move_count:8370 nnrate:0.0216606 win_rate:0.521986 draw:0.0585203
12:3i4h move_count:8654 nnrate:0.0308613 win_rate:0.511935 draw:0.0658712
13:7i6h move_count:6128 nnrate:0.0318323 win_rate:0.495197 draw:0.0689616
14:7i7h move_count:1807 nnrate:0.0188768 win_rate:0.441253 draw:0.0548807
15:2h1h move_count:81 nnrate:0.00134084 win_rate:0.378411 draw:0.0542994
16:2h3h move_count:182 nnrate:0.00286659 win_rate:0.387395 draw:0.0504418
17:2h4h move_count:100 nnrate:0.00153019 win_rate:0.391744 draw:0.0553084
18:2h5h move_count:154 nnrate:0.00280101 win_rate:0.362751 draw:0.0516878
19:2h6h move_count:990 nnrate:0.0179083 win_rate:0.362621 draw:0.0516561
20:2h7h move_count:850 nnrate:0.0142273 win_rate:0.376696 draw:0.0535907
21:4i3h move_count:1 nnrate:1.83503e-05 win_rate:0.432962 draw:0.0596469
22:4i4h move_count:9 nnrate:6.20836e-05 win_rate:0.478401 draw:0.061416
23:4i5h move_count:819 nnrate:0.00338495 win_rate:0.506092 draw:0.0677877
24:6i5h move_count:15 nnrate:0.000211752 win_rate:0.410581 draw:0.0539416
25:6i6h move_count:39 nnrate:0.000263822 win_rate:0.480577 draw:0.0599286
26:6i7h move_count:65700 nnrate:0.0991663 win_rate:0.533101 draw:0.0671388
27:5i4h move_count:23 nnrate:0.000307105 win_rate:0.415958 draw:0.0624212
28:5i5h move_count:90 nnrate:0.00054318 win_rate:0.487062 draw:0.0569803
29:5i6h move_count:1401 nnrate:0.00432681 win_rate:0.516858 draw:0.0522245

draw:の後の数値がバックアップされた千日手の確率である。
2g2f (二六歩)と、7g7f (7六歩)の訪問回数(move_count)が多く、千日手の確率は、それぞれ0.0605795、0.0603726になっている。
2g2f (二六歩)の方が、わずかに千日手の確率が高いが、ほぼ同じである。
平手開始局面では、千日手の予測が妥当かどうか判断できない。

  • 先手が角換わりを選択できる局面
position startpos moves 2g2f 8c8d 7g7f 4a3b 2f2e 8d8e

f:id:TadaoYamaoka:20220103210853p:plain
|

先手が、7七角を指せば角換わりになる局面である。
この局面の各手の千日手の確率は以下の通り。

0:1g1f move_count:2921 nnrate:0.0149358 win_rate:0.484744 draw:0.0418013
1:2e2d move_count:52186 nnrate:0.0935355 win_rate:0.519303 draw:0.0472217
2:3g3f move_count:65 nnrate:0.000483536 win_rate:0.461186 draw:0.030724
3:4g4f move_count:11 nnrate:7.75115e-05 win_rate:0.469704 draw:0.0343168
4:5g5f move_count:12 nnrate:0.000155746 win_rate:0.40977 draw:0.0342723
5:6g6f move_count:54 nnrate:0.00044754 win_rate:0.452436 draw:0.0493007
6:7f7e move_count:187 nnrate:0.00260336 win_rate:0.393394 draw:0.0356545
7:8g8f move_count:7 nnrate:0.000263042 win_rate:0.179321 draw:0.0152975
8:9g9f move_count:6224 nnrate:0.029359 win_rate:0.488845 draw:0.0395514
9:1i1h move_count:5 nnrate:6.23639e-05 win_rate:0.416613 draw:0.0355014
10:9i9h move_count:14 nnrate:0.000117823 win_rate:0.446026 draw:0.035784
11:8i7g move_count:88 nnrate:0.0010974 win_rate:0.409444 draw:0.0314612
12:3i3h move_count:8498 nnrate:0.0226585 win_rate:0.510202 draw:0.0393935
13:3i4h move_count:955 nnrate:0.00526842 win_rate:0.480586 draw:0.0402083
14:7i6h move_count:1125 nnrate:0.0103155 win_rate:0.442541 draw:0.0411338
15:7i7h move_count:6359 nnrate:0.0299131 win_rate:0.488991 draw:0.0421639
16:8h3c+ move_count:20 nnrate:0.000875257 win_rate:0.101496 draw:0.0101548
17:8h4d move_count:11 nnrate:0.000294209 win_rate:0.270423 draw:0.0333792
18:8h5e move_count:59 nnrate:0.000736953 win_rate:0.406358 draw:0.0420949
19:8h6f move_count:432 nnrate:0.0028955 win_rate:0.46818 draw:0.0415992
20:8h7g move_count:2844361 nnrate:0.514368 win_rate:0.536125 draw:0.079909
21:2h1h move_count:3 nnrate:7.4672e-05 win_rate:0.330184 draw:0.0343858
22:2h2f move_count:528 nnrate:0.0036502 win_rate:0.465786 draw:0.0422589
23:2h2g move_count:8 nnrate:6.99477e-05 win_rate:0.45394 draw:0.0345064
24:2h3h move_count:1 nnrate:2.32848e-05 win_rate:0.281208 draw:0.0316188
25:2h4h move_count:1 nnrate:6.51619e-06 win_rate:0.270866 draw:0.0322223
26:2h5h move_count:2 nnrate:6.07541e-05 win_rate:0.309892 draw:0.0335276
27:2h6h move_count:15 nnrate:0.00035687 win_rate:0.296944 draw:0.0279614
28:2h7h move_count:12 nnrate:0.000279252 win_rate:0.306955 draw:0.0295265
29:4i3h move_count:3 nnrate:2.59912e-05 win_rate:0.452154 draw:0.0369317
30:4i4h move_count:12 nnrate:7.84216e-05 win_rate:0.474661 draw:0.0381489
31:4i5h move_count:223 nnrate:0.00124876 win_rate:0.479916 draw:0.0421533
32:6i5h move_count:2 nnrate:2.07389e-05 win_rate:0.437223 draw:0.0396998
33:6i6h move_count:75 nnrate:0.000477541 win_rate:0.47053 draw:0.039563
34:6i7h move_count:119816 nnrate:0.230684 win_rate:0.517926 draw:0.0460936
35:5i4h move_count:141 nnrate:0.000790783 win_rate:0.479209 draw:0.04173
36:5i5h move_count:8859 nnrate:0.0241661 win_rate:0.509562 draw:0.0415073
37:5i6h move_count:3423 nnrate:0.00752173 win_rate:0.515073 draw:0.0401955

8h7g(7七角)、6i7h(7八金)の順に訪問回数が大きい。
それぞれの千日手の確率は、0.079909、0.0460936となっており、8h7g(7七角)の方が千日手になる確率が高いと予測している。
8h7g(7七角)は角換わりになる可能性が高いため、妥当な予測ができていそうである。

探索時のUCBの計算で千日手の予測を考慮することで、千日手を避けた探索ができそうである。

まとめ

ディープラーニングのモデルで千日手を予測し、探索時に利用することで、序盤から千日手を避ける手を選択できそうということがわかった。
次回は、実際に探索時に千日手の予測を利用した探索の検証を行う予定。