Python
DeepLearning
データ分析
ディープラーニング
コンピュータ将棋

【将棋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のモデルを作れる可能性がある