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

【将棋AI】「将棋AIで学ぶディープラーニング」を読む♪~Networkモデルの拡張;モデュレーション

将棋AIで学ぶディープラーニング
第十八夜は、少しモデルをいじってみた。

やったこと

(1)今までのモデルで総当たり戦をやってみた
(2)Resnetの繰り返しを2層から3層にしてみた
(3)さらなるNetworkモデルの拡張できるように層をモデュレートしてみた

(1)今までのモデルで総当たり戦をやってみた

Networkモデルとして、Resnetの23層と13層を追加しました。これでResnetにおける層の深さの比較ができます。今回の記事全体のモデルは以下のとおりです。

名称 loss 一致率(方策) 一致率(価値) 備考
policy 1.682677 0.4226734 - 方策ネットワークのみ
Policy_Value;Layer13 2.016 0.4204578 0.67033803 13層の方策・価値ネットワークでMCTS
ResnetSimple40※ 2.29075 0.4325099 0.6906338 Resnet20block43層
ResnetSimple20  2.308355 0.4326057 0.6941468 Resnet10block23層
ResnetSimple10 2.360802 0.42507267 0.6948055 Resnet5block13層
ResnetTry30 2.27104 0.43431032 0.6986858 ResnetTri10block33層
ResnetVGGLike5 2.279315 0.43526843 0.69514084 ResnetVGGLike5block19層

※前回の対戦と使用したパラメータが異なっています

下二つのモデルを除く結果は以下のようになりました。つまり、ここまでは層が深いほどよさそうです。が、Resnet無しが頑張っています。
S102040MctsPolLkai.jpg

(2)Resnetの繰り返しを2層から3層にしてみた

モデルは以下のとおり、今までBlockとして二層ずつ追加したものを三層ずつ追加するように変更してみました。

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)
            self.conv2 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)
            self.conv3 = L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1)

    def __call__(self, x):
        h1 = F.relu(self.conv1(x))
        h2 = self.conv2(h1)
        h3 = self.conv3(h2)
        return F.relu(x+h3)

10Blockにしたので、モデルは全部で33層になります。
上記の結果もあるので、効果としてResnetとNormalとの中間の効果が出るといいなぁ~という程度です。
一致率等は上記の表のとおりです。
そして、結果は以下のようになりました。
※記事書いていて気が付いたけど、これh2 = F.relu(self.conv2(h1))のミスですね
Try3sen.jpg
Try3sen2.jpg
ミスはあったが、とりあえず、層の深さに依存して強さの順位となりました。

(3)さらなるNetworkモデルの拡張できるように層をモデュレートしてみた

これらの延長として簡単にできるNetworkモデルの拡張をやってみた。本当はVGGNetに近づけたいが、テンソル計算の辻褄をつけるのが難しいのでとりあえずの拡張です。
【参考】
Chainerにおけるグラフ構造をループで書いてみる。

ch = 192
fcl = 256
class RoopBlock(Chain):
    def __init__(self,n_in,n_out,stride=1):
        super(RoopBlock,self).__init__()
        with self.init_scope():
            self.conv1 = L.Convolution2D(in_channels = n_in, out_channels = n_out, ksize = 3, pad = 1)
            self.conv2 = L.Convolution2D(in_channels = n_out, out_channels = n_out, ksize = 3, pad = 1)
            self.conv3 = L.Convolution2D(in_channels = n_out, out_channels = n_in, ksize = 3, pad = 1)
    def __call__(self,x):
        h = F.relu(self.conv1(x))
        h = F.relu(self.conv2(h))
        h = F.relu(self.conv3(h)+x)
        return h    

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)
            links = [("root0",RoopBlock(ch,ch))]
            n_in = ch
            n_out = 256
            for index in range(1,5,1):
                links += [("root{}".format(index),RoopBlock(n_in,n_out))]
                n_in *= 1
                n_out *= 1
            for link in links:
                self.add_link(*link)
            self.forward = links    
            # policy network
            self.policy=L.Convolution2D(in_channels = n_in, 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 = n_in, out_channels = MOVE_DIRECTION_LABEL_NUM, ksize = 1)
            self.value2=L.Linear(9*9*MOVE_DIRECTION_LABEL_NUM, fcl)
            self.value3=L.Linear(fcl, 1)

    def __call__(self, x):
        x = F.relu(self.l1(x))
        for name,func in self.forward:
            x = func(x)
        # policy network
        u_policy = self.policy(x)
        u_policy = self.policy_bias(F.reshape(u_policy, (-1, 9*9*MOVE_DIRECTION_LABEL_NUM)))
        # value network
        h_value = F.relu(self.value1(x))
        h_value = F.relu(self.value2(h_value))
        u_value = self.value3(h_value)
        return u_policy, u_value

そして、強さは以下のようにResnetS40と4:1:5とほぼ互角という結果であった。
VGGvsS40.jpg
このモデルは層も19層であり、それほど深くもなく、かつ1epoch当たりの時間は、以下のとおり予測どおりである。

model time/epoch
S43 57:10 43層
VGGL19 45:19 19層
S23 37:59 23層
S13 30:30 13層

まとめ

・層は深いほど強い
・同じ層を重ねるより、モデュレーションをかけた方が強くなる可能性がある

・まだまだNetworkモデルを工夫できる可能性がある