上一节,我们使用基于蒙特卡洛树搜索的机器人来自我对弈,同时我们把机器人落子方式和落子时的棋盘编码记录下来,本节我们就使用上一节数据来训练神经网络,让网络学会如何在给定棋盘下进行精确落子。

神经网络的运行原理如下:

当网络训练好后,我们把棋盘编码对应的二维矩阵转换为一维矩阵输入网络,网络给出大小与棋盘对应的一维向量,每个向量对弈一个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%,虽然高于随机落子,但是准确率依然低得令人毛骨悚然。

对于了解神经网络或者上过我的课程用神经网络构造图像和语言识别系统的同学会知道卷积网络特别适用于识别图像,图像本质就是一个二维矩阵,在识别图像时,网络会将图像转换为灰度图,并将每个像素点预处理成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%,相对于原来是一个巨大提升,当然结果还是不尽如人意,后面我们会不断改进网络结构,不断提升判断准确率。

接下来我们看看具体代码实现,我们将上节存储的数据加载,进行预处理,准备输入网络进行训练:

import  numpy as np
from keras.models import Sequential
from keras.layers import Dense#加载棋盘编码
np.random.seed(234)
X = np.load('content/gdrive/My Drive/features-40k.npy')
Y = np.load('content/gdrive/My Drive/labels-40k.npy')
#棋盘个数
samples = X.shape[0]
board_size = 9*8#将棋盘编码对应的三维向量转换为二维向量
X = X.reshape(samples, board_size)
Y = Y.reshape(samples, board_size)#将数据分成两部分90%作为训练数据,剩下10%作为测试数据
train_samples = int(0.9 * samples)
X_train, X_test = X[:train_samples], X[train_samples:]
Y_train, Y_test = Y[:train_samples], Y[train_samples:]

对于一个9*9的棋盘,上面有81个落子位置,如果我们闭着眼睛随便选一个位置,选中最优落子点的概率是1/81,也就是1.2%,因此我们的网络预测最佳落子位置的准确概率比1.2%越大就意味着网络预测效果越好,我们构造一个含有两层的全连接层网络,看看用数据训练后效果如何:

model = Sequential()
model.add(Dense(1000, activation = 'sigmoid', input_shape = (board_size, )))
model.add(Dense(500, activation = 'sigmoid'))
#第三层输出9*9=81个结果,由此对应棋盘上每个落子位置
model.add(Dense(board_size, activation = 'sigmoid'))
model.summary()model.compile(loss = 'mean_squared_error', optimizer = 'sgd',metrics = ['accuracy'])model.fit(X_train, Y_train, batch_size = 64, epochs = 15,verbose = 1, validation_data = (X_test, Y_test))score = model.evaluate(X_test, Y_test, verbose = 0)
print('Test loss:', score[0])
print('Test accuracy: ', score[1])

上面代码运行后,得到网络预测的正确性是2.6%,虽然高于随机概率1.2%,但是准确性依然非常低,这意味着我们还有很大的改进空间。我们使用的全连接网络并不是很合适与分析像棋盘这样的二维数据结构,因为它要把二维向量压缩成一维后才能进行解析,但压缩成一维就失去了落子点的空间信息,该信息显然对于判断走法好坏非常重要。

善于捕捉二维向量空间排列信息的莫过于卷积网络莫属。同时网络中的激活函数以及成本损失函数还有很大的改进空间。接下来我们要使用卷积网络替代前面过于简单的全连接网络,以便提高预测的准确性。

首先我们将数据预处理成符合卷积网络的输入格式:

#加载棋盘编码
np.random.seed(234)
X = np.load('/content/gdrive/My Drive/features-40k.npy')
Y = np.load('/content/gdrive/My Drive/labels-40k.npy')
#棋盘个数
samples = X.shape[0]
size = 9
input_shape = (size , size, 1)#将多个棋盘编码转换为四维向量
X = X.reshape(samples, size, size, 1)#将数据分成两部分90%作为训练数据,剩下10%作为测试数据
train_samples = int(0.9 * samples)
X_train, X_test = X[:train_samples], X[train_samples:]
Y_train, Y_test = Y[:train_samples], Y[train_samples:]

接着我们构造一个卷积网络,代码如下:

from keras.layers import Conv2D, Flattenmodel = Sequential()
'''
我们把棋盘切分成3*3小块,用48个不同卷积向量与3*3小块做运算,
通常情况下,卷积运算后得到的二维向量会比原向量小,但设置padding='same',
框架会用0拓展二维向量的宽和高,使得最终做卷积后得到的二维向量与原向量大小相同
'''
model.add(Conv2D(filters = 48, kernel_size = (3,3), activation = 'sigmoid',padding = 'same', input_shape = input_shape))
model.add(Conv2D(48, (3,3), padding = 'same', activation = 'sigmoid'))#把输出结果压平成一维向量
model.add(Flatten())model.add(Dense(512, activation = 'sigmoid'))
model.add(Dense(size * size, activation = 'sigmoid'))model.summary()

然后我们启动训练流程:

model.compile(loss = 'categorical_crossentropy',optimizer = 'sgd',metrics = ['accuracy'])model.fit(X_train, Y_train, batch_size = 64,epochs = 100, verbose = 1, validation_data = (X_test, Y_test))score = model.evaluate(X_test, Y_test, verbose = 0)
print('Test loss: ', score[0])
print('Test accuracy: ', score[1])

上面代码运行后,得到准确率为8%左右,相比于前一个网络有很大提升,但力度还是不够,下一节我们会做进一步的改进。

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:

打爆李世石第一步:使用神经网络设计人工智能围棋机器人相关推荐

  1. 从零开始再造打爆李世石的AlphaGo:创造能下围棋的机器人

    我们在上节完成了围棋规则和棋盘状态监测功能,本节我们在基于上节的基础上,设计一个能自己下棋的围棋机器人.首先我们设计一个类叫Agent,它的初始化代码如下: class Agent:def __ini ...

  2. 互联网产品设计第一步,账户设计之个人实名认证

    背景 政策要求 根据<中华人民共和国网络安全法>.<互联网信息服务管理办法>.<互联网新闻信息服务管理规定>等法律法规要求. <互联网新闻信息服务管理规定&g ...

  3. 创业第一步:如何写好商业计划书

    即使你的项目不需要融资,你也把标准商业计划书作为一个工具模板来应用,帮助更全面的盘点你要做的事情. 撰写一份性感的商业计划书如同造房子:第一步是科学设计,打好结构(有清晰的撰写逻辑):第二步是寻找合适 ...

  4. Lesson 11.1-11.5 梯度下降的两个关键问题反向传播的原理走出第一步:动量法开始迭代:batch和epochs在Fashion—MNIST数据集熵实现完整的神经网络

    在之前的课程中,我们已经完成了从0建立深层神经网络,并介绍了各类神经网络所使用的损失函数.本节课开始,我们将以分类深层神经网络为例,为大家展示神经网络的学习和训练过程.在介绍PyTorch的基本工具A ...

  5. 初学架构设计的第一步:需求、愿景与架构

    初学架构设计的第一步:需求.愿景与架构 了解<需求>.<愿景>与<架构>三者的关系.也就是<需求分析>.<观想愿景>与<架构设计> ...

  6. aws搭建java项目_AWS 创建开源 UI 项目:这是新开源设计系统的第一步

    Amazon Web Services 发布了 AWS UI 以及 Porting Assistant for .NET UI,后者使用了前者的组件,并且已公开源代码仓库.而 AWS UI 项目根据 ...

  7. 领域建模——架构设计的第一步(下)

    领域建模--架构设计的第一步(下) 正如上一篇所述,在领域驱动设计中策略设计侧重于子域的拆分和集成,其结果是合理划分的子域以及它们之间的交互关系.当系统已经被拆分成子域之后,领域驱动设计中的技术维度则 ...

  8. 领域建模——架构设计的第一步(上)

    领域建模--架构设计的第一步(上) <深入剖析架构师角色>中我们提到,架构师需要能够从问题领域出发推导出满足业务需求的架构体系,同时又能够从实现方法入手设计出能够满足业务架构需求的技术架构 ...

  9. (求老师啊,求同伴啊)php 生命数字密码设计第一步:数据库基本连接

    第一步;建设自己的数据库,建立最基本的数据库. 1.新建设表大表;gigital  ,在建设小表:destiny -- phpMyAdmin SQL Dump -- version 4.1.12 -- ...

最新文章

  1. html页面显示用户在线统计,在HTML页面中实现点击数统计
  2. python2.7 Cheetah You don't have the C version of NameMapper installed
  3. Android 快速选择联系人
  4. 模板网站建设过程中需要注意哪些细节问题?
  5. 160个Crackme019
  6. [BZOJ 1001] 狼抓兔子
  7. 电压3.3V的ESD静电保护器件型号大全
  8. php根据汉字首字母分组,利用PHP获取汉字首字母并且分组排序详解
  9. 【推荐】英国金融时报推荐的数据可视化图表分类图
  10. Lucene 3.0 Field类(自己学习)
  11. python创建树结构、求深度_Python实现二叉树的最小深度的两种方法
  12. 基于 Flink 打造的伴鱼实时计算平台 Palink 的设计与实现
  13. Linux中关机,重启,注销命令
  14. 什么样的终端才是最合适桌面虚拟化的呢?
  15. 【CRC】CRC推导(二)模二除法
  16. Angluar编译过程中出现的TS2339问题
  17. Mybatis 大于小于符号解决
  18. 老子哲学与太极拳技击
  19. 【Unity】【PC】【错误上报】Bug上报插件 Trello Bug Tracker 使用介绍 (一):用户上报部分
  20. 解读ConnectBot-1 telnet、ssh常识

热门文章

  1. 一个五位数取前三位matlab,【有五个小球,分别是1,2,3,4,5号,有放回的从中取三次,每次取一个,...-前三后五取一颗-数学-关偈邓同学...
  2. Windows API 函数大全
  3. Novamind 5 安装+和谐----请在补丁前关闭文件,和谐不成功
  4. 了解流式加密(CK)(二)
  5. the way of DPL
  6. python可变数据类型和不可变数据类型_python 可变数据类型和不可变数据类型
  7. 实测:合宙ESP32C3开发板可以直接用Arduino开发
  8. 微信小程序中weui的正确打开方式
  9. 世界地球日 | 成功解锁首件烤仔时尚单品
  10. 非侵入式负荷matlab程序,非侵入式负荷分解之BLUED数据集