Posted at

【将棋AI】「将棋AIで学ぶディープラーニング」を読む♪~モデルを変更する

将棋AIで学ぶディープラーニング

第十三夜は、Networkモデルを変更して、より強い将棋AIに挑戦します。


やったこと

(1)Resnetで学習

(2)対戦してみる

(3)より強い将棋AIを目指す


(1)Resnetで学習

本書ではハイパーパラメータの調整ということで、フィルター枚数の変更、ミニバッチサイズの変更、層数の変更、BatchNormalization、そして最適化手法の変更を実施して結果を示しています。

さらに、resnetが層が深くても収束させられるモデルであることを解説し、ブロックを5層と10層で学習して傾向を示しています。

ということで、ウワンもこのResnetの5層モデルで学習を実施して最初のモデルとの違いを見たいと思います。

※ここでは一応モデルを変更して学習させるということを主目的に実施します

ResnetのNetworkはググるといくつか出てきますが、やはり少し複雑です。本書のモデルはとても教育的なコードで分かり易いと思います。

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も利用しています。

図で表すと以下のように書けます。

resnet.jpg

早速学習してみます。学習は以前のモデルと同じデータを学習します。

>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

figure_1-34resnet_2016_2017.png

以下山岡さんの最近の一致率と比較してみると、案外いい線いってるように見える。


方策(一致率)
価値(一致率)

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です。

resnetvslesserkai.jpg

将棋が下手なウワンには何が悪いか本当のところはわかりませんが、とにかくいいところまで追いつめても、最後のところで積み切れずに負けてしまいます。。。。


(3)より強い将棋AIを目指す

まず、当初のモデルはどこまで強くなったかというと、上記とほぼ同じ学習、つまりfloodgateの2016年と2017年の棋譜で学習したものは以下の一致率になっています。

figure_1-34_3000_2016-2017.png

はっきり言って、先ほどの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です。

lesserkaivs13.jpg

そして、Temperature=75、Depth=1000だと、Gikouの(•レベル1(読みの深さ1手): 将棋倶楽部24の8級相当 (R 800程度)といい勝負。。。もちろん持ち時間多めですが、。。

GikouvsLayer13.jpg

まだまだ将棋AIのモデルは未知数です。

問題は大きく以下二点です。

①特にNetworkに何をどの程度の層で使えばより最適化という大きな問題があります。それはそれを支えるマシンパワーとのバランスもとれていなければなりません。AlphaGoやAlphazeroと同じようなロジックにはできますが、彼らはTPUという計算基盤をフル回転してその威力を最大化した結果でした。

普通のマシン基盤で使えるモデルはまた違ったモデルが最適になる可能性もあると考えています。

②そもそも学習したいが適当な棋譜とはどんなものか、そしてそれを大量に用意するにはどうすべきか。やはり強化学習をする以外に強化できる可能性がないように思う。つまり、将棋AIでは強化学習は当然の帰結である。たぶんこれは将棋に限ったことではなく、最初は人間のまねをしてルールというかドメインの性質を学習して、最後は強化学習という自己学習でより上を目指す。その場合もやはりマシン基盤が重要な役割となる。


まとめ

・より強い将棋AIを目指してResnet5層で学習した

・得られた一致率はあまり変わらないが、Resnet5層は弱かった

・従来の13層のモデルが少し強くなった

・さらに強い将棋AIのモデルを作れる可能性がある