上一节,我们使用基于蒙特卡洛树搜索的机器人来自我对弈,同时我们把机器人落子方式和落子时的棋盘编码记录下来,本节我们就使用上一节数据来训练神经网络,让网络学会如何在给定棋盘下进行精确落子。
神经网络的运行原理如下:
![屏幕快照 2019-04-04 下午5.49.46.png](https://upload-images.jianshu.io/upload_images/2849961-22a44fe22df8e06d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
当网络训练好后,我们把棋盘编码对应的二维矩阵转换为一维矩阵输入网络,网络给出大小与棋盘对应的一维向量,每个向量对弈一个0到1之间的值,该值表示落子在对应位置上的赢率,我们只要从输出的一维矩阵中选择值最大那个分量对应的位置落子即可。
一开始我们会构造一个简单的双层全连接网络,第一层有1000个神经元,第二层有500个神经元,最后一层有81个神经元,它对应9*9棋盘上的每个落子位置,最后一层输出结果中,值最大的节点就对应网络预测应该落子之处,我们将要开发的第一个网络层次结构如下:
```
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 1000) 82000
_________________________________________________________________
dense_2 (Dense) (None, 500) 500500
_________________________________________________________________
dense_3 (Dense) (None, 81) 40581
=================================================================
Total params: 623,081
Trainable params: 623,081
Non-trainable params: 0
```
结构简单到只有两层的全连接网络却拥有62万多个参数需要训练。由于一个9\*9棋盘总共有81个落子位置,如果我们随便选一个位置,那么选中最佳位置的概率是1/81 = 1.2%,因此网络预测的准确率必须要高于1.2%才算有效。上面全连接网络训练后得到的准确率为2.3%,虽然高于随机落子,但是准确率依然低得令人毛骨悚然。
对于了解神经网络或者上过我的课程[用神经网络构造图像和语言识别系统](https://study.163.com/provider/7600199/course.htm?share=2&shareId=7600199)的同学会知道卷积网络特别适用于识别图像,图像本质就是一个二维矩阵,在识别图像时,网络会将图像转换为灰度图,并将每个像素点预处理成0到1之间的值,这不就跟我们现在对棋盘编码的二维向量没有差别了吗!因此后面我们会使用卷积网络去识别棋盘编码后的二维向量,由此能大大提高预测准确率。
卷积神经网络在识别输入时一个特点是,它会把二维向量切割成多份,每份对应一个规模更小的二维向量,例如把n\*n规格的二维向量切分成多个3*3规格的二维向量组合,然后分别识别这些小规格二维向量,最后把识别结果综合起来,因此卷积网络特别擅长于抓出图像中的某些特征部位。
对于棋盘而言,棋子所形成的局部模式对落子判断非常重要,某些局部地区的棋子摆放模式甚至决定了整部棋局的最终走向,因此网络必须能有效抓住局部棋盘的变化,由此卷积网络非常契合这种需求。
于是在进一步改进中,我们构造如下结构的卷积网络:
```
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_8 (Conv2D) (None, 9, 9, 48) 480
_________________________________________________________________
dropout_2 (Dropout) (None, 9, 9, 48) 0
_________________________________________________________________
conv2d_9 (Conv2D) (None, 9, 9, 48) 20784
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 4, 4, 48) 0
_________________________________________________________________
dropout_3 (Dropout) (None, 4, 4, 48) 0
_________________________________________________________________
flatten_2 (Flatten) (None, 768) 0
_________________________________________________________________
dense_3 (Dense) (None, 512) 393728
_________________________________________________________________
dropout_4 (Dropout) (None, 512) 0
_________________________________________________________________
dense_4 (Dense) (None, 81) 41553
=================================================================
Total params: 456,545
Trainable params: 456,545
Non-trainable params: 0
```
卷积网络能把预测准确率提升到8%,相对于原来是一个巨大提升,当然结果还是不尽如人意,后面我们会不断改进网络结构,不断提升判断准确率。