上一节,我们从围棋服务器中下载大量棋谱,并将其转换成网络可以解析的数据格式,在神经网络的开发中完成了最繁琐的一步,也就是数据准备。接下来我们将创建一个神经网络,对数据进行解读,使得网络具备6到7段的围棋专业水平,它尚未具备打败柯洁或李世石这些顶级高手的能力,但打败业余级高手则绰绰有余。
我们要完成的网络有三种形态,一种是小型网络,一种是中型网络,一种是大型网络,其能力由弱到强,当然训练的耗时也由少到多。网络的基本结构是,前4层我们都使用卷积层,最后一层是一个含有19*19个神经元的全连接层。这里我们将引入一种新的网络层叫ZeroPadding2D层。卷积网络在处理图像时,它会把图像分割成多个小块后分别识别,识别所得的结果在规格上,也就是宽和高上相对于输入时的数据而言会有所缩小,如果卷积层较多,那么图片在层层处理后,规格会严重减小。
为了防止规格缩小得太严重,我们在将图片输入卷积网络前,会给它填充若干行和列,假设我们要处理的图片规格为19*19,如果我们执行下面语句:
ZeroPadding2D(padding = 2, input_shape = input_shape, data_format='channel_first')
那意味着我们在1919的二维数组左边和右边分别添加2列,在上面和底部分别添加2行,这些列和行全部使用0来填充,于是就能得到一个2323的二维数组。当我们把输入数据先扩大,经过卷积网络处理后就不会严重缩水。
同时我们还得注意,在卷积层,我们会用多个过滤器对图片进行扫描,图片被一个过滤器扫描后就得到一个二维数组作为扫描结果,如果多个过滤器就会得到多个二维数组,如下图:
过滤器的个数,我们也叫做channel,上面代码中channel_first,表示卷积网络输出结果中,把过滤器的数值放在扫描结果对应的二维数组前面,假设卷积层网络有N个过滤器,每个过滤器扫描图片后得到的结果二维数组为W和H,于是上面‘channel_first’指定卷积层输出的结果为:[N, W, H],也就是把过滤器的个数放在结果向量的前面。
有了上面的基本解释后,我将用代码构造如下结构的神经网络:
Layer (type) Output Shape Param #
=================================================================
zero_padding2d_5 (ZeroPaddin (None, 1, 25, 25) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, 48, 19, 19) 2400
_________________________________________________________________
activation_6 (Activation) (None, 48, 19, 19) 0
_________________________________________________________________
zero_padding2d_6 (ZeroPaddin (None, 48, 23, 23) 0
_________________________________________________________________
conv2d_6 (Conv2D) (None, 32, 19, 19) 38432
_________________________________________________________________
activation_7 (Activation) (None, 32, 19, 19) 0
_________________________________________________________________
zero_padding2d_7 (ZeroPaddin (None, 32, 23, 23) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, 32, 19, 19) 25632
_________________________________________________________________
activation_8 (Activation) (None, 32, 19, 19) 0
_________________________________________________________________
zero_padding2d_8 (ZeroPaddin (None, 32, 23, 23) 0
_________________________________________________________________
conv2d_8 (Conv2D) (None, 32, 19, 19) 25632
_________________________________________________________________
activation_9 (Activation) (None, 32, 19, 19) 0
_________________________________________________________________
flatten_2 (Flatten) (None, 11552) 0
_________________________________________________________________
dense_3 (Dense) (None, 512) 5915136
_________________________________________________________________
activation_10 (Activation) (None, 512) 0
_________________________________________________________________
dense_4 (Dense) (None, 361) 185193
=================================================================
Total params: 6,192,425
Trainable params: 6,192,425
Non-trainable params: 0
有了上面网络后,我们再通过上节实现的数据加载方法,将棋盘数据输入网络进行训练,完成后网络就具备了能打败业余高手的能力。通过上面网络加上人类棋谱的训练,网络对棋手下一步走法的预测率能高达85%作用,注意到网络预测的是专业六段和七段棋手的走法,因此它能轻易打败业余级的高手。