TadaoYamaokaの開発日記

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

【将棋AI】N駒関係をMulti-Head Self-Attentionで学習する 続き

前回考察した将棋AIへのMulti-Head Self-Attentionの適用を試してみた。

実装を簡単するために、dlshogiで使用している入力特徴量と出力をそのまま使用した。

入力特徴量

  • 各駒の配置
  • 持ち駒の枚数
  • 駒の種類ごとの利き
  • マスごとの効き数

※王手の特徴量は除いた

これらを、位置ごとの特徴としてMulti-Head Self-Attentionに入力する。

位置は、盤上の81マスと、持ち駒の種類と枚数ごと×2(先後)として、各位置を自然言語処理の各単語のようにして扱う。
各位置には、その位置での上記の特徴量を表すベクトルを入力する。
14の駒の種類は先後で分けて、効きも先後に分けた駒ごと、効き数は3つまで、合計62次元となる。
ヘッド数で割り切れる必要があるため、パディングして64次元とする。

例えば、以下の局面の、
f:id:TadaoYamaoka:20200716213025p:plain
5五の位置の特徴ベクトルは、
f:id:TadaoYamaoka:20200716213354p:plain
となる。

持ち駒の位置は、歩の持ち駒は8枚までとして、先後合わせて持っている枚数と位置を対応させて、(8(歩)+4(香)+4(桂)+4(銀)+4(金)+2(角)+2(飛))×2=56個の位置で表す。
対応する持ち駒を持っていればすべて1のベクトルとする。

自然言語処理に例えると、64次元の埋め込みベクトルで表した単語を81+56=137個並べた文を入力するイメージとなる。

出力

指し手(方策)と勝率(価値)を出力する。
指し手は、移動先×移動方向(10方向+持ち駒の種類)で表す。
勝率は、[0, 1]のスカラ値とする。

モデルの実装

Multi-Head Self-Attentionは、PyTorchのTransformerEncoderと TransformerEncoderLayerを使用して実装した。
Multi-Head Self-Attentionの層数は1で、ヘッド数は8とした。
Multi-Head Self-Attentionの出力を、方策と価値に分岐させて、それぞれ全結合層(256ユニット)をつなげて出力層につなげた。

TransformerEncoderは、入力と出力の次元が、畳み込み層や全結合層などと異なり、(単語数, バッチサイズ, 特徴ベクトルの次元)となるので注意が必要である。
全結合層につなげる前に、permuteで、次元を交換する必要がある。

学習方法

dlshogiと同じ学習則とした(SWAを除く)。
MomentumSGD、学習率0.1、バッチサイズ1024で最適化した。

学習結果

dlshogiの強化学習で生成した2,048,000局面で訓練して、floodgateの棋譜からサンプリングした856,923局面で評価を行った。

比較のために、dlshogiの10ブロックのResnetで同一条件で学習した結果も記載する。

モデル 訓練平均損失(方策, 価値, 評価値, 合計) 評価損失(方策, 価値, 評価値, 合計) 正解率((方策, 価値)
Multi-Head Self-Attention 1.961, 0.438, 0.464, 2.408 1.687, 0.653, 0.714, 2.361 0.244, 0.622
Resnet(10ブロック) 1.071, 0.406, 0.435, 1.487 1.202, 0.606, 0.670, 1.829 0.328, 0.651

方策の正解率24%、価値の正解率62%となっており、ある程度学習できている。

Resnet(10ブロック)の方が、精度が高くなっているが、Multi-Head Self-Attentionの方が層数は少ない。
学習時間も短くなっている。

学習時間の比較
モデル 学習時間
Multi-Head Self-Attention 0:04:46
Resnet(10ブロック) 0:13:42
層数

Multi-Head Self-Attentionの層数を2に増やした場合についても測定した。

モデル 訓練平均損失(方策, 価値, 評価値, 合計) 評価損失(方策, 価値, 評価値, 合計) 正解率((方策, 価値)
Multi-Head Self-Attention(2層) 1.859, 0.430, 0.456, 2.298 1.608, 0.632, 0.697, 2.262 0.263, 0.633
モデル 学習時間
Multi-Head Self-Attention(2層) 0:07:07

2層にした方が少し精度が上がっている。
しかし、学習時間は約1.5倍に増える。

考察

Resnet(10ブロック)よりも精度が低いが、Multi-Head Self-Attentionでも将棋の学習ができることが確かめられた。
1層のMulti-Head Self-Attentionでも効果がある。

今回dlshogiの特徴量をそのまま使用したが、入力特徴量は、Multi-Head Self-Attentionに合わせて変更した方がよいと考える。

Positional Encorder

各位置の特徴ベクトルには、位置の情報を含んでおらず、同じ特徴ベクトルが異なる位置にあっても同じ出力ベクトルになる。
全結合層では各ユニットと位置が対応するので、モデル全体としては完全に位置を無視しているわけではない。

しかし、位置により駒の価値も異なるので、Multi-Head Self-Attentionへの入力にも位置を表す情報があった方がよいと考える。
Transformerでは、Positional Encorderの出力と単語の埋め込みベクトルの和を入力している。
将棋では9×9の座標で位置を表せるため、段と筋をそれぞれワンホットベクトルで表して連結するのが良さそうである。

持ち駒の特徴ベクトル

持ち駒の特徴ベクトルは、枚数に対応する位置の特徴ベクトルをすべて1にしたが、1枚目の歩、2枚目の歩で価値は異なるので、それらをワンホットベクトルで表した方が良いかもしれない。

これらを変更して精度が上がるか後日、検証してみたい。

検証に使用したソースコード

github.com