前回学習した価値ネットワークの予測精度はお世辞にも高くはなく,実際に対戦してみてもとても弱かったです. これでは流石にあんまりなので,マルチタスク学習で予測精度が上がらないか試します. 結論から言ってしまうと,この方法は精度が上がりませんでした. Tensorflowによるマルチタスク学習の実装例程度にお考え下さい.
関連性のある複数の問題を同時に学習することでモデルの汎化性能を向上させます. 例えばスマホの顔認証システムを作ることを考えます. このモデルを作るときに与えられた顔写真とある人物が同一人物かを学習するだけでなく,顔の角度 人種 鼻の形なども同時に学習することで 重要な情報がモデルから抜け落ちることを防ぎます.
今回は畳み込み層を共有して与えられた局面に対する「勝率」と「次の一手」を予測させます. つまり,方策ネットワークの学習と価値ネットワークの学習を共有する畳み込み層と個別の出力層で学習します. 価値ネットワークも方策ネットワークも勝利を目指すという点では関連性のあるタスクであるといえます. また,次の一手予想では与えられた局面に対して合法手が何通りあるかをある程度予測できています. オセロでは「打てる手が多いほうが有利」という通説(?)もあるらしいので方策ネットワークと価値ネットワークとの関連性は強いと予想できます.
from sklearn.model_selection import train_test_split
import tensorflow as tf
import numpy as np
from tensorflow import keras
import copy
from keras.callbacks import EarlyStopping
import random
##### target_policy の読み込み #####
target_policy = []
f = open("target_policy.txt","r")
for x in f:
num = int(x.rstrip("\n"))
target_policy.append(num)
f.close()
target_policy = np.array(target_policy)
#####################################
##### target_value の読み込み #######
target_value = []
f = open("target_value.txt","r")
for x in f:
num = float(x.rstrip("\n"))
target_value.append(num)
f.close()
target_value = np.array(target_value)
#####################################
######## imageの読み込み ############
image = np.zeros((len(target_action),2,8,8),"float32")
image = np.load("image.npy")
image = np.array(image,"float32")
#####################################
target = []
for i in range(len(target_policy)):
target.append((target_policy[i],target_value[i]))
# 訓練データ 性能評価用データ テストデータの3つに分割する
x_train, x_test, y_train, y_test = train_test_split(image,target)
x_train, x_valid, y_train, y_valid = train_test_split(x_train,y_train)
policy_train = []
value_train = []
for data in y_train:
policy,value = data[0],data[1]
policy_train.append(policy)
value_train.append(value)
policy_train = np.array(policy_train)
value_train = np.array(value_train)
policy_test = []
value_test = []
for data in y_test:
policy,value = data[0],data[1]
policy_test.append(policy)
value_test.append(value)
policy_test = np.array(policy_test)
value_test = np.array(value_test)
# 出力が1つの従来のモデル
inputs = keras.layers.Input(shape=(2,8,8))
x = keras.layers.Permute((2,3,1), input_shape=(2,8,8))(inputs)
for i in range(12):
x = keras.layers.Conv2D(128, kernel_size=3,padding='same',activation='relu')(x)
x = keras.layers.Conv2D(1, kernel_size=1,use_bias=True)(x)
x = keras.layers.Flatten()(x)
# 出力はpolicy と value の2つ
policy = keras.layers.Dense(64, activation='softmax',name="policy")(x)
value = keras.layers.Dense(1, activation='sigmoid',name="value")(x)
model = keras.Model(inputs=inputs, outputs=[action,value])
# モデルをcompileする
model.compile(optimizer='adam',
loss={'policy': 'sparse_categorical_crossentropy',
'value': 'mean_squared_error'},
loss_weights={'policy': 0.5,
'value': 0.5},
metrics=['accuracy'])
それでは実際に学習をさせてみます. 学習にはGeForce RTX 2080を利用して30分ほどかかります.
# EaelyStoppingの設定
early_stopping = EarlyStopping(
monitor='val_loss',
min_delta=0.0,
patience=2,
)
print("start train")
# 学習
history = model.fit(
x_train,
[policy_train, value_train],
epochs=30,
batch_size=1024,
validation_data=[x_test, [policy_test, value_test]],
callbacks=[early_stopping] # CallBacksに設定
)
model.save('MultiTask_network')
model.evaluateで性能評価をします.
value_test2 = value_test[value_test!=0.5]
policy_test2 = policy_test[value_test!=0.5]
x_test2 = x_test[value_test!=0.5]
model.evaluate(x_test2,[policy_test2,value_test2])
今回はマルチタスク学習を試してみました. 次回は8×8のオセロについて試してみたことや失敗例をいくつか紹介します.