機械学習周りのプログラミング中心。 イベント情報
ポケモンバトルAI本電子書籍通販中

将棋AIの評価値を勝率に変換する係数を求める

将棋AIで、NNUE系とDL系ソフトを合議させることに挑戦しています。同じ局面を複数のソフトに思考させた結果を統合した合議結果を計算するアルゴリズムとして、楽観合議が知られています。この手法では、各ソフトが最善手とその評価値を出力し、その中で評価値が最も高かった指し手を合議結果とします。ここで問題となるのが、ソフト間で評価値のスケールが異なる点です。例えば評価値500という出力でも、ソフトAでは勝率70%、ソフトBでは勝率80%に相当するといった差異が生じます。竹内の手法*1では、評価値を勝率に変換する関数を求め、評価値の代わりに勝率で楽観合議を行う手法が提案されています。

本記事では、実際に複数のソフトの棋譜を用いて評価値を勝率に変換する関数を求めます。結果として、ソフトにより係数が異なるだけではなく、同じソフトであっても対局相手により係数が変化することがわかりました。

実験方法

ソフト同士を対局させ、棋譜を収集します。対局数は1000、開始局面はたややん互換局面集を用いて36手目の局面から思考を開始します。思考時間はノード数を指定します。評価値が-1000以下になった時点でそのソフトの負けとして対局を打ち切りますが、dlshogiの場合は逆転が多いため詰みまで対局させました。棋譜からソフトの評価値と、対局の勝敗(勝ち=1,負け=0,引き分けは除外)のペアを抽出します。ただし、評価値の絶対値が1000を超えているサンプルは除外します。評価値 xと勝率 yの関係はシグモイド曲線で近似できることが知られているため、パラメータ a, bを最適化してシグモイド関数 y=\frac{1}{1+exp(-(ax+b))}にフィッティングさせます。損失関数は、竹内の手法で用いられている、勝敗とのMean Squared Errorを用いました。今回のデータでは、Binary Cross Entropyを用いても求まるパラメータにほとんど変化はありませんでした。

使用ソフトとその設定は以下の通りです。

  • 水匠5 (NNUE系)
    • ノード数100万 (Suisho 1M)、ノード数10万 (Suisho 100k)
  • dlshogi (DL系)
    • ノード数1000 (dlshogi 1k)
    • 評価関数は、「強い将棋ソフトの創りかた」のサンプルコードで学習させたもの
    • エンジンはふかうら王を利用
  • elmo (WCSC27) (KPPT系、系統の異なるソフトとして比較用)
    • ノード数100万 (elmo 1M)

回帰の実装はPyTorchを用い、ミニバッチSGDで最適化しました。以下のようなきわめて単純なモデルを定義しています。scikit-learnではロジスティック回帰+Mean Squared Errorという設定が見当たらなかったためです。

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(1, 1)
        torch.nn.init.constant_(self.fc.weight, 1)
        torch.nn.init.constant_(self.fc.bias, 0)
        self.normalize = 1 / 1200

    def forward(self, x):
        x = x * self.normalize
        x = self.fc(x)
        x = torch.sigmoid(x)
        return x

実験結果

評価値から勝率への回帰関数を求めた結果

実験で求まった回帰関数をプロットした結果を図に示します。例えば「Suisho 100k (vs elmo 1M)」は、水匠を10万ノード、elmoを100万ノードの設定で対局させた際に、水匠側の評価値と勝敗を用いて回帰を行った結果を示します。水匠を10万ノード、elmoを100万ノードに設定した場合、水匠側の勝率は47%となっています。Suisho 1M (vs Suisho 1M)とdlshogi 1k (vs dlshogi 1k)を比較すると、ソフトによって評価値と勝率の対応関係に大きな差があることがわかります。また、評価値0が必ずしも勝率50%を表しているわけではないことがわかります。そのため、回帰のパラメータとしてオフセット bが必要と考えられます。さらに、Suisho 1M (vs Suisho 1M)とSuisho 100k (vs Suisho 100k)でも違いがみられました。Suisho 1Mのほうが同じ評価値でも勝率が0%または100%に近づいています。読みが深いと、評価値に差がついた後に逆転することが難しいことを表現していると考えられます。また、Suisho 100k (vs Suisho 100k)とSuisho 100k (vs elmo 1M)は全く同じ設定のソフトですが、対局相手が自分自身であるか、異なるソフトであるかによって回帰結果に若干の差異が生じています。異なるソフトとの対局のほうが予想外の手を指されて逆転する確率が高まることを示していると考えられます。以上のように、ソフト間で評価値のスケールに差異が存在するだけでなく、同一ソフトであってもその設定や対局相手によって評価値と勝率の対応関係には違いが生じることがわかりました。パラメータ調整の際には、対局相手に対する仮定を置くことは難しいですが、できるだけ実際の対局に近い設定での棋譜を生成する必要があることが示唆されます。

ソフト詳細

水匠5

https://github.com/mizar/YaneuraOu/releases/tag/v7.5.0 より入手。exeファイルに水匠5の評価関数が埋め込まれている。

Suisho5-YaneuraOu-v7.5.0-windows\YaneuraOu_NNUE-tournament-clang++-avx2.exe

オプション Threads:1

dlshogi

YaneuraOu-Deep-TensorRT-V761\YaneuraOu-Deep-TensorRT.exe

eval/model.onnx = model_resnet10_swish-072.onnx (「強い将棋ソフトの創りかた」の本のサンプルそのままで学習させたもの)

オプション Threads:1,DNN_Batch_Size1:8

elmo (WCSC27)

https://mk-takizawa.github.io/elmo/howtouse_elmo.html より入手。

YaneuraOu2019V489all_kppt\YaneuraOu_KPPT_avx2.exe

起動時の表示

info string Eval Check Sum = c9e81cef72b , Eval File = elmo(WCSC27)

オプション Threads:1

対局プログラム

呼び出しコマンドの例

python -m cshogi.cli path\to\YaneuraOu2019V489all_kppt\YaneuraOu_KPPT_avx2.exe path\to\Suisho5-YaneuraOu-v7.5.0-windows\YaneuraOu_NNUE-tournament-clang++-avx2.exe --draw 256 --debug --resign 1000 --keep-process --games 1000 --byoyomi 30000 30000 --opening path\to\taya36.sfen --options1 NodesLimit:1000000,Threads:1 --options2 NodesLimit:100000,Threads:1 --pgn elmo_1m_suisho_100k.pgn > elmo_1m_suisho_100k.log

*1:竹内聖悟. 異種プログラム間における楽観合議について. 情報処理学会研究報告, Vol.2018-GI-40 No.8.