![将棋AIで学ぶディープラーニング](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F233744%2Fded117b9-37c7-1b41-033d-960e63ca5fe1.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=935ba98476ebc61c2169e698c737d5cf)
from chainer import Chain
import chainer.functions as F
import chainer.links as L
from pydlshogi.common import *
ch = 192
fcl = 256
class Block(Chain):
def __init__(self):
super(Block, self).__init__()
with self.init_scope():
self.conv1 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1, nobias=True)
self.bn1 = L.BatchNormalization(ch)
self.conv2 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1, nobias=True)
self.bn2 = L.BatchNormalization(ch)
def __call__(self, x):
h1 = F.relu(self.bn1(self.conv1(x)))
h2 = self.bn2(self.conv2(h1))
return F.relu(x + h2)
class PolicyValueResnet(Chain):
def __init__(self, blocks = 5):
super(PolicyValueResnet, self).__init__()
self.blocks = blocks
with self.init_scope():
self.l1=L.Convolution2D(in_channels = 104, out_channels = ch, ksize = 3, pad = 1)
for i in range(1, blocks):
self.add_link('b{}'.format(i), Block())
# policy network
self.policy=L.Convolution2D(in_channels = ch, out_channels = MOVE_DIRECTION_LABEL_NUM, ksize = 1, nobias = True)
self.policy_bias=L.Bias(shape=(9*9*MOVE_DIRECTION_LABEL_NUM))
# value network
self.value1=L.Convolution2D(in_channels = ch, out_channels = MOVE_DIRECTION_LABEL_NUM, ksize = 1)
self.value1_bn = L.BatchNormalization(MOVE_DIRECTION_LABEL_NUM)
self.value2=L.Linear(9*9*MOVE_DIRECTION_LABEL_NUM, fcl)
self.value3=L.Linear(fcl, 1)
def __call__(self, x):
h = F.relu(self.l1(x))
for i in range(1, self.blocks):
h = self['b{}'.format(i)](h)
# policy network
h_policy = self.policy(h)
u_policy = self.policy_bias(F.reshape(h_policy, (-1, 9*9*MOVE_DIRECTION_LABEL_NUM)))
# value network
h_value = F.relu(self.value1_bn(self.value1(h)))
h_value = F.relu(self.value2(h_value))
u_value = self.value3(h_value)
return u_policy, u_value
以下のblocks=5を変更すればブロック数を自由に変更できます。
※ここでは収束時間が早い5層とします
def __init__(self, blocks = 5):
また、このモデルでは、BatchNormalizationも利用しています。
図で表すと以下のように書けます。
早速学習してみます。学習は以前のモデルと同じデータを学習します。
>python train_policy_value_resnet.py kifulist3000_train.txt kifulist3000_test.txt --eval_interval 1000
2018/09/04 21:35:05 INFO read kifu start
2018/09/04 21:35:25 INFO load train pickle
2018/09/04 21:35:27 INFO load test pickle
2018/09/04 21:35:27 INFO read kifu end
2018/09/04 21:35:27 INFO train position num = 1892246
2018/09/04 21:35:27 INFO test position num = 208704
2018/09/04 21:35:27 INFO start training
2018/09/04 21:36:00 INFO epoch = 1, iteration = 1000, loss = 6.252685, accuracy = 0.171875, 0.60546875
2018/09/04 21:36:31 INFO epoch = 1, iteration = 2000, loss = 5.033235, accuracy = 0.17773438, 0.5859375
2018/09/04 21:37:01 INFO epoch = 1, iteration = 3000, loss = 4.5309515, accuracy = 0.25585938, 0.6035156
。。。
2018/09/04 22:07:20 INFO epoch = 1, iteration = 59132, train loss avr = 3.3427236, test accuracy = 0.34475157, 0.67265373
2018/09/04 22:07:20 INFO save the model
2018/09/04 22:07:20 INFO save the optimizer
。。。
2018/09/05 02:55:51 INFO epoch = 10, iteration = 591320, train loss avr = 1.9026536, test accuracy = 0.40383473, 0.6531782
2018/09/05 02:55:51 INFO save the model
2018/09/05 02:55:52 INFO save the optimizer
。。。
2018/09/06 01:51:48 INFO epoch = 18, iteration = 1292000, loss = 1.8666146, accuracy = 0.390625, 0.6816406
2018/09/06 01:52:19 INFO epoch = 18, iteration = 1293000, loss = 1.8751647, accuracy = 0.43945312, 0.6816406
2018/09/06 01:52:49 INFO epoch = 18, iteration = 1294000, loss = 1.8839896, accuracy = 0.46484375, 0.6933594
2018/09/06 01:53:19 INFO epoch = 18, iteration = 1295000, loss = 1.8709311, accuracy = 0.45507812, 0.6953125
2018/09/06 01:53:23 INFO validate test data
2018/09/06 01:55:48 INFO epoch = 18, iteration = 1295110, train loss avr = 1.8446575860697083, test accuracy = 0.4195995, 0.6717752
以下山岡さんの最近の一致率と比較してみると、案外いい線いってるように見える。
- | 方策(一致率) | 価値(一致率) |
---|---|---|
Resnet5layer | 0.4195995 | 0.6717752 |
yamaoka19 | 0.4090266 | 0.68762606 |
yamaoka38 | 0.437221587 | 0.706173778 |
注意;yamaoka19と38のデータは異なるデータに対する方策の一致率と価値の一致率 | ||
【参考】 | ||
・将棋AIの進捗 その25(自己対局による強化学習の経過) | ||
###(2)対戦してみる | ||
ということで、対戦してみます。ここでは昨夜のmcts_playerを使います。 | ||
結果は。。。惨敗。。Lesserkai(レイティング700位)に全く歯が立ちません。ちなみにパラメータは、Temperature=100、Depth=300です。 | ||
![]() |
||
将棋が下手なウワンには何が悪いか本当のところはわかりませんが、とにかくいいところまで追いつめても、最後のところで積み切れずに負けてしまいます。。。。 | ||
###(3)より強い将棋AIを目指す | ||
まず、当初のモデルはどこまで強くなったかというと、上記とほぼ同じ学習、つまりfloodgateの2016年と2017年の棋譜で学習したものは以下の一致率になっています。 | ||
![]() |
||
はっきり言って、先ほどのResnetの場合とほとんど同じような学習曲線になっています。 | ||
表にすると以下のとおりです。 |
- | 方策(一致率) | 価値(一致率) |
---|---|---|
13layer | 0.4204578 | 0.67033803 |
Resnet5layer | 0.4195995 | 0.6717752 |
yamaoka19 | 0.4090266 | 0.68762606 |
yamaoka38 | 0.437221587 | 0.706173778 |
しかし、学習したものは少し異なっているようです。
すなわち、こちらの方が断然強いんです。
以下のようにLesserKaiに8:2で勝っています。
※最後は大ゴマ渡して勝手に投了しちゃってますが、。。
ちなみにパラメータは上記のResnetと同じTemperature=100、Depth=300です。
そして、Temperature=75、Depth=1000だと、Gikouの(•レベル1(読みの深さ1手): 将棋倶楽部24の8級相当 (R 800程度)といい勝負。。。もちろん持ち時間多めですが、。。
まだまだ将棋AIのモデルは未知数です。
問題は大きく以下二点です。
①特にNetworkに何をどの程度の層で使えばより最適化という大きな問題があります。それはそれを支えるマシンパワーとのバランスもとれていなければなりません。AlphaGoやAlphazeroと同じようなロジックにはできますが、彼らはTPUという計算基盤をフル回転してその威力を最大化した結果でした。
普通のマシン基盤で使えるモデルはまた違ったモデルが最適になる可能性もあると考えています。
②そもそも学習したいが適当な棋譜とはどんなものか、そしてそれを大量に用意するにはどうすべきか。やはり強化学習をする以外に強化できる可能性がないように思う。つまり、将棋AIでは強化学習は当然の帰結である。たぶんこれは将棋に限ったことではなく、最初は人間のまねをしてルールというかドメインの性質を学習して、最後は強化学習という自己学習でより上を目指す。その場合もやはりマシン基盤が重要な役割となる。
###まとめ
・より強い将棋AIを目指してResnet5層で学習した
・得られた一致率はあまり変わらないが、Resnet5層は弱かった
・従来の13層のモデルが少し強くなった
・さらに強い将棋AIのモデルを作れる可能性がある