我一直在尝试复制 AlphaGo 按照他们的监督学习协议获得的结果。论文指出,他们使用的网络有两个头:一个预测游戏获胜者的价值头和一个根据棋盘当前状态预测下一步行动的策略头。
对于政策负责人来说,没问题,CNN 学会了预测下一步行动。然而,价值头并没有学到任何东西,并且总是退回到总是预测 0 而不是 -1/1 来表示白/黑胜利。感觉模型还不够复杂,无法理解如何预测游戏的结果,所以它学会了预测 0 来尽量减少损失。
我尝试过但没有用的东西:
将网络分为两部分:一个价值网和一个政策网。但即使在这种情况下,价值网也不会学习。
将获胜者标记为 0/1 而不是 -1/1,因此使用 sigmoid 而不是 tanh 激活函数,但这也不起作用。
不同数量的剩余单元 (3/5/7/11)。
仅使用 2 个通道作为输入,一个用于黑石,一个用于白石。
复制策略网络第一层的权重并冻结它们以强制价值网络使用已经学习的特征。
这是模型:
def residual_block(s):
shortcut = s
s = Conv2D(256, (3, 3), strides=(1, 1), padding='same', kernel_regularizer=l2(0.0001))(s)
s = BatchNormalization()(s)
s = ReLU()(s)
s = Conv2D(256, (3, 3), strides=(1, 1), padding='same', kernel_regularizer=l2(0.0001))(s)
s = BatchNormalization()(s)
s = add([shortcut, s])
s = ReLU()(s)
return s
def model():
inputs = Input(shape=(2, 19, 19, ))
# Convolutional block
x = Conv2D(256, (3, 3), strides=(1, 1), padding='same')(inputs)
x = BatchNormalization()(x)
x = ReLU()(x)
# Residual block
for i in range(11):
x = residual_block(x)
# Value head
x = Conv2D(1, (1, 1), strides=(1, 1), padding='same', kernel_regularizer=l2(0.0001))(x)
x = BatchNormalization()(x)
x = ReLU()(x)
x = Flatten()(x)
x = Dense(256, kernel_regularizer=l2(0.0001))(x)
x = ReLU()(x)
x = Dense(1, activation = 'tanh')(x)
return Model(inputs=inputs, outputs=x)
这是培训:
batch_size = 32
gen_train = generator(batch_size, sgf_paths)
gen_test = generator(batch_size, sgf_paths)
optimizer = SGD(lr=0.01, momentum=0.9, decay=0., nesterov=True, clipnorm=1.)
checkp = ModelCheckpoint(filepath="weights_ValueNet.h5", verbose=1, save_best_only=True)
model = model()
model.compile(loss="mean_squared_error", optimizer=optimizer)
hist = model.fit_generator(
gen_train,
steps_per_epoch = 2048,
epochs = 100,
shuffle = True,
verbose = 1,
validation_data = gen_test,
validation_steps = 300,
callbacks = [checkp])