在 2016 年 3 月, Deepmind 研发的 AlphaGo 以 4:1 的成绩, 击败了曾荣获 18 次世界冠军的围棋选手, 李世石 (Lee Sedol) 超过 2 亿观众见证了这一历史时刻一台机器已经学会了一种超越人类的围棋策略这在以前被认为是一项不可能完成的任务, 或者至少需要十年之功
AlphaGo 与李世石的第 3 场比赛
这已是一项了不起的成就然而, 在 2017 年 10 月 18 日, DeepMind 又再次取得了突破
论文无需人类知识就能称霸围棋(Mastering the Game of Go without Human Knowledge), 揭示了一种新的算法 AlphaGo Zero, 它以 100:0 的惊人成绩打败了 AlphaGo 更令人难以置信的是, 它从零开始, 通过自我博弈, 逐渐学会了能打败自己之前的策略至此, 开发一个超级 AI 不再需要依赖人类专家的游戏数据库了
仅 48 天后的 2017 年 12 月 5 日, DeepMind 又发布了另一篇论文通过一种通用的强化学习算法称霸国际象棋和日本象棋 (Mastering Chess and Shogi by Self-Play with a General Reinforcement Learning Algorithm), 它展示了 AlphaGo Zero 如何能够学会国际象棋(StockFish 和 Elmo) 和象棋整个学习过程, 从第一次参与游戏到成为世界上最厉害的计算机程序, 只用了 24 小时
就这样, AlphaZero 华丽丽地诞生了它无需储备任何人类棋谱, 就可以以通用算法完成快速自我升级
关于这个成就, 有两点最让人称奇:
AlphaZero 对人类游戏经验根本就不需要
这点的重要性怎么说都不过分也就是说, 对于任何有充分信息的游戏(对阵双方对游戏状态都全程掌握),AlphaGo Zero 的方法论都可以得到完美应用! 因为除了游戏规则之外, 人类任何游戏经验值都是不需要的
AlphaGo Zero 的基础方法可以应用于任何具有完美信息的游戏(游戏状态在任何时候, 双方玩家都完全知道的), 因为在游戏规则之外, 不需要事先的专家知识
这就是 DeepMind 能在发表 AlphaGo Zero 论文 48 天后, 马上就能发表第二篇论文毫不夸张地说, 所需要改变的仅仅是新游戏规则, 及与神经网络和蒙特卡罗树搜索相关的超参数
这个算法的优雅程度秒杀众生
即便 AlphaZero 使用的是世界上只有极少数人能够看懂的超复杂算法, 它仍然是项了不起的成就同它相比, 之前的算法可谓不复杂不成活, 这才是它真正的魅力究其核心, 无非是以下极简而美的学习逻辑:
脑补各种场景, 挑能赢的路走, 想想别人会怎么应对, 并不断探索未知
在思考未来可能的情景时, 优先考虑有前途的路径, 同时考虑其他人最有可能如何对你的行动作出反应, 并继续探索未知
遇到不熟悉的状况, 评估它的利害程度, 把它同之前的各种让你走到今天这一步的场景作比较
穷尽你对未来的想象, 用你试过最多的招数来应对
在你考虑了未来的可能性之后, 采取你已经探索过的行动
游戏结束时, 回头看看在哪里犯过错, 然后洗心革面更新认知
在游戏结束时, 回过头来评估你在哪里错误地判断了未来的位置, 并相应地更新你的理解
这听起来是不是很像你学玩游戏的方式? 当做错一个动作时, 要么是因为你误判了这个动作会带来的结果, 要么是你误判了对手可能会采取的行动这两点正是 AlphaZero 学会如何玩游戏的法门
如何构建自己的 AlphaZero
首先, 我们需要学习和理解 AlphaGo Zero 的原理我之前写过一篇 AlphaGo Zero 的知识点速查手册可供参考:
https://medium.com/applied-data-science/alphago-zero-explained-in-one-diagram-365f5abf67e0
Tim Wheeler 的博客中一篇文章也讲的很详细:
http://tim.hibal.org/blog/alpha-zero-how-and-why-it-works/
代码
基于下面这个代码库进行讲解:
https://github.com/AppliedDataSciencePartners/DeepReinforcementLearning
从运行 Jupyter notebook 中 run.ipynb 的前两个 panel 开始一旦它完成了游戏的足够回合, 那么神经网络将开始训练通过随后的自我对弈和训练, 它将逐渐在预测胜率和下一步行动上做得越来越好, 从而做出更好的决策
现在, 我们需要更详细地看看面前的代码, 并且展示下 AI 是怎样随着时间的增加变得越来越厉害的
四子连珠(Connect4)
我们的算法将要学习如何玩这个游戏虽然不如围棋那样复杂, 但也有 4531985219092 种游戏走位
四子连珠
游戏规则很简单玩家轮流在任何一栏的顶部布置自己的颜色最先在垂直水平或对角线上放置一排同一种颜色棋子的玩家获胜, 如果这种情况没有出现, 那游戏就是平局
下面是组成代码库的关键文件:
game.py 这个文件包含四子连珠的游戏规则
每个正方形都被分配了一个从 0 到 41 的数字, 如下图所示:
game.py 文件给出了从一种游戏状态到另一种状态的逻辑, 并且给出了一个选择的动作比如, 考虑到 empty board 和 38 号动作, takeAction 方法返回到一个新的游戏状态, 也就是底部一行的中心位置
你可以将 game.py 文件用任何符合相同 API 和算法的游戏文件替换掉, 根据你给它的规则, 通过自我对弈的方法学习
run.ipynb 这个文件包含开启学习过程的代码
它通过算法中的主要环节加载游戏规则, 并且由三个阶段组成:
1 自我对弈
2 重新训练神经网络
3 评估神经网络
有两个智能体也参与到这个环节中, 他们分别为 best_player 和 current_player
best_player 包含执行最佳的神经网络, 并且可以用于生成自我对弈的记忆然后, current_player 在这些记忆上重新训练它的神经网络, 然后再与 best_player 对弈如果它赢了, best_player 内部的神经网络被转换为 current_player 内部的神经网络, 然后循环再次启动
agent.Py 这个文件包含游戏中的一个玩家 Agent class
在游戏中, 每个玩家都是用自己的神经网络和蒙特卡罗搜索树进行初始化的
我们需要用模拟的办法运行蒙特卡罗树搜索过程具体地说, 智能体移动到树的叶节点, 用它的神经网络对节点进行评估, 然后通过树将节点的值返回
之后, 我们还需要用 act method 多次重复模拟, 让智能体理解从当前位置出发的最有利的移动然后它将最终选择的动作返回到游戏中, 以执行动作
最后, replay method 利用以前游戏的记忆, 重新训练神经网络
model.py 这个文件包括 residual_cnn 类, 它定义了如何建立神经网络的实例
用 keras 搭建残差卷积网络示例
它采用的是 AlphaGoZero 论文中浓缩版的神经网络结构即一个卷积层, 接着是许多剩余层, 然后分成一个数值和指挥中枢
可以在 config 文件中指定卷积筛选器的深度和数量
Keras 库是用来与后台的 tensorflow 建立网络
查看个人的卷积滤波器和浓密连接层的神经网络, 在 run.ipynb 笔记本运行以下代码:
current_player.model.viewLayers()
神经网络中的卷积核
MCTS.py 这个文件包含节点 (Node), 边(Edge) 和 MCTS 类, 构成了蒙特卡洛树搜索
MCTS 类包含了前文提到的 moveToLeaf 和 backFill 方法, 以及 Edge 类的实例存储有关每个潜在移动的统计信息
config.py 这是你设置影响算法的关键参数的地方
调整这些变量会影响运行时间, 神经网络的准确性和整体算法的成功以上参数产生一个高品质的四子连珠选手, 但要花很长时间才能做到为了加快算法的速度, 请尝试以下参数
funcs.py 包含可以在两个智能体之间进行比赛的 playMatches 和 playMatchesBetweenVersions 函数
如果你想挑战之前创建的智能算法, 可以运行下面的代码(在 run.ipynb 笔记本)
- from game import Game
- from funcs import playMatchesBetweenVersions
- import loggers as lg
- env = Game()
- playMatchesBetweenVersions(
- env
- , 1 # the run version number where the computer player is located
- , -1 # the version number of the first player (-1 for human)
- , 12 # the version number of the second player (-1 for human)
- , 10 # how many games to play
- , lg.logger_tourney # where to log the game to
- , 0 # which player to go first - 0 for random
- )
initialise.py 当你运行该算法, 所有的模型和存储文件保存在 runfolder 的根目录下
稍后要从此检查点重新运行算法, 请将运行文件夹传输到 run_archive 文件夹, 并将运行编号附加到文件夹名称然后, 将运行编号, 型号版本号和内存版本号输入到 initialise.py 文件中, 对应于 run_archive 文件夹中相关文件的位置像往常一样运行算法, 然后从这个检查点开始
memory.py
Memory 类的一个实例存储以前游戏的记忆, 该算法用于重新训练 current_player 的神经网络
loss.py
该文件包含一个自定义损失函数, 在传递到交叉熵损失函数之前, 屏蔽了来自非法移动的预测
settings.py
run 和 run_archive 文件夹的位置
loggers.py
日志文件保存到运行文件夹内的日志文件夹中
要打开日志记录, 请在此文件中将 logger_disabled 变量的值设置为 False
查看日志文件将帮助你了解该算法的工作原理, 并在其头脑中查看 例如, 下面是 logger.mcts 文件中的示例
logger.mcts 文件的输出
同样从 logger.tourney 文件, 你可以在评估阶段看到每个移动的概率:
logger.tourney 文件的输出
训练出的结果让人惊喜
通过几天的训练, 得到以下小批量迭代次数与损失的关系图:
小批量迭代次数与损失的关系图
最上面的线是策略头中的误差 (MCTS 移动概率的交叉熵, 相对于神经网络的输出) 底部的线是价值头 (实际游戏数值和神经网络预测值之间的均方误差) 中间的线是两者的平均值
显然, 神经网络在预测每个游戏状态的值以及可能的下一步移动方面正在变得更好为了说明这个结果如何变得越来越强大, 我让 17 个参与者组成联赛, 从神经网络的第 1 次迭代到第 49 次每一组比赛两次, 两个玩家都有机会先玩
这是最后的排名:
显然, 神经网络的最新版本比早期版本更胜一筹, 赢得了大部分的游戏 这也似乎表明学习过程没有达到极限 - 随着训练时间的进一步延长, 玩家将会继续变得更强大, 学习越来越复杂的策略
作为一个例子, 随着时间的推移, 一个神经网络挑选的策略较早的占据了中间列观察算法的第一个版本与第三十个版本之间的区别:
这是一个很好的策略, 因为很多线路都需要中间列 尽早占领这一列可以确保你的对手无法利用这一优势 神经网络已经在没有人类指导下, 学到了这一点
学习其他游戏
在游戏文件中有一个称为 Metasquares 的 game.py 文件其中的 X 和 O 用于形成不同大小的正方形较大的方格意味着要落更多的棋子, 当棋盘布满时, 落子多的一方获胜
如果你将 Connect4 (四子连珠) 的 game.py 文件替换成 Metasquares 的 game.py 文件, 同样算法将会用于学习玩 Metasquares 游戏
来源: https://yq.aliyun.com/articles/485243