上一节,我们构造了如下结构的神经网络:
Layer (type) Output Shape Param #
=================================================================
conv2d_59 (Conv2D) (None, 192, 19, 19) 91392
_________________________________________________________________
conv2d_60 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_61 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_62 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_63 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_64 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_65 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_66 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_67 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_68 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_69 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_70 (Conv2D) (None, 192, 19, 19) 331968
_________________________________________________________________
conv2d_71 (Conv2D) (None, 1, 19, 19) 193
_________________________________________________________________
flatten_5 (Flatten) (None, 361) 0
_________________________________________________________________
dense_7 (Dense) (None, 256) 92672
_________________________________________________________________
dense_8 (Dense) (None, 1) 257
=================================================================
Total params: 3,836,162
Trainable params: 3,836,162
Non-trainable params: 0
它将作为工具,用于分析环境,以便帮助Agent做出正确选择。我们将构造一个Agent对象,真正的主角是它,它将执行我们制定的策略算法,然后不断调教网络,让它深入分析环境特性,以便提供准确的数据给Agent做决策。
首先要做的是使用上一节说明的棋盘编码方法对大量棋盘数据进行编码后训练网络,其基本流程如下:
接下来我们首先加载训练网络所需要的数据,这些数据跟我们前面拥有从围棋服务器上下载的棋盘数据一模一样:
f = open('AlphaGoEncoder', 'rb')
my_encoder = pickle.load(f)
f = open('GoDataProcessor', 'rb')
my_processor = pickle.load(f)
rows, cols = 19, 19
num_classes = rows * cols
num_games = 10000
generator = my_processor.load_go_data('train', num_games, use_generator = True)
test_generator = my_processor.load_go_data('test', num_games, use_generator = True)
为了不用把相关类的代码加载到本地文件,我将它们序列化成二进制文件,使用时直接读取,要不然我们需要在本地添加很多相关类的实现代码,这会造成本地代码凌乱从而难以控制,在运行上面代码时,要在本地目录建立一个名为”data”的文件夹,因为load_go_data会将围棋服务器上的棋盘数据下载到该文件夹下。接下来我们初始化上一节完成的神经网络:
#代码用于参考,我们没有算力因此很难训练出网络,所以我们直接加载已经训练好的网络
input_shape = (my_encoder.num_planes, rows, cols)
alphago_s1_policy = alphago_model(input_shape, is_policy_net = True)
alphago_s1_policy.compile('sgd', 'categorical_crossentropy', metrics = ['accuracy'])
epochs = 200
batch_size = 128
#先用数据训练网络,让网络具备一定的下棋能力
alphago_s1_policy.fit_generator(generator = generator.generate(batch_size, num_classes),
epochs = epochs, steps_per_epoch = generator.get_num_samples() / batch_size,
validation_data = test_generator.generate(batch_size, num_classes),
validation_steps = test_generator.get_num_samples() / batch_size,
callbacks = [ModelCheckpoint('alphago_s1_policy_(epoch).h5')])
如果没有GPU硬件,那么我们就不可能有足够的算力去训练网络,因此上面代码运行时将很难在短时间内结束,为了节省时间,我们使用下面代码将已经训练好的网络直接加载:
model.save('alphago_networks.h5')
已经训练好的网络其所有参赛存储在alphago_networks.h5文件中,之间加载已经训练好的网络,如此我们就不用耗费大量的时间在网络训练上。上面的网络使用了人类棋手生成的棋盘数据进行训练,因此已经具备了一定的下棋能力,但是还不够强大,远远达不到AlphaGo的地步,要实现AlphaGo的水平,网络必须能够自我对弈,然后不断提升,这个过程分三步走,首先创建两个Agent,每个Agent都包含上面训练好的网络,2,让这两个Agent相互对弈,Agent利用上面网络来进行落子预测;3,收集对弈结果,用这些结果再次训练网络;4,评估训练结果。
我们在前面章节已经展示过两个机器人自我对弈的过程,本节大同小异,只不过对弈过程的处理要比前面章节复杂得多。我们的Agent需要在一个不断变化的环境中提升自己,这个环境就是棋盘上落子变化。一次episode就相当于两个机器人下完一盘棋,如果我们的agent赢了,那么这盘棋中Agent每次落子获得的回报就是1,如果输了,那么每次落子的回报就是-1,如此agent就可以从每次落子中获得环境的反馈。