教你用 Python 和 Keras 建立自己的 AlphaZero

2018-03-16 10:45:01 浏览数 (1)

作者David Foster。 翻译 | 黄伟聪 董星 校对 | 凡江

在这篇文章,我会试着阐明三件事:

  1. AlphaZero之所以是人工智能前进一大步的两个答案
  2. 怎样生成一个 AlphaZero方法论的副本使其能玩Connect4
  3. 怎样改代码能使其插入其他游戏仍然有用

AlphaGo → AlphaGo Zero → AlphaZero

在2016年三月,Deepmind 公司的 AlphaGo ,在超过2亿人次观看的比赛中,4比1打败了18次世界冠军的围棋选手李世石。一个机器学会远超人类的下围棋策略,以前认为是不可能做到的,或者退一步,当时认为至少也要10年完成的。

AlphaGo vs 李世石 比赛第三场

这本就是一个卓越的成就。但是,在 2017年10月18日,DeepMind 取得了更大的飞跃性成就。

在一篇名为 ‘Mastering the Game of Go without Human Knowledge(无师自通围棋)’的论文公布了一种新的算法,AlphaGo Zero 用其 100–0 大败AlphaGo。不可思议的是,它仅仅靠自我博弈做到如此,从零开始并且逐渐找方法打败旧版本。构建一个超越人类的人工智能不再需要专家博弈时的数据库。

图表来自 ‘Mastering the Game of Go without Human Knowledge’

仅仅48天之后,在2017年12月5日,DeepMind 放出另一篇论文 ‘Mastering Chess and Shogi by Self-Play with a General Reinforcement Learning Algorithm(通过使用通用的强化学习算法,自我博弈来掌握国际象棋和日本象棋)’ ,文章展示了 AlphaGo Zero 如何成长,并最终能在国际象棋和日本象棋分别打败世界冠军程序StockFish和Elmo。整一个学习过程,AlphaGo Zero从第一次观看比赛到成为世上最强象棋程序不到24小时。

由此,AlphaZero横空出世 —而这个通用算法,无需人类专家的先验策略便能让它快速掌握某些知识。

关于这个成就令人惊奇的两点:

1. AlphaZero 无需以人类知识作为输入

这点是非常重要的。这意味着 AlphaGo Zero 根本的方法论能适用于 任何 完全信息的游戏(游戏台面总是完全公开可见)因为它除游戏规则外无需知道其他专业的知识。

这就是DeepMind 为什么能在原 AlphaGo Zero论文发表仅48天后,又发表国际象棋和日本象棋论文的原因。毫不夸张的说,要做得只是改变阐述博弈机制的输入头文件和调整与神经网络和蒙特卡洛搜索有关的超参数。

2. 这个算法出人意料的简洁

如果AlphaZero用的是世界上只有少数人能理解的超级复杂算法,那么这将是令人难以置信的成就。而让它特别的是,实际上论文中许多理念远没有以前的版本复杂。它的核心思路正是下面简单的学习口诀:

通过模拟演绎可能的未来场景,优先考虑有前景的路径,同时考虑其他人对你行为最有可能做出的反应并继续探索未知情况。 在到达一个陌生的场景后,评估所选位置有利程度并通过模拟路径级联先前位置的得分。 完成对未来可能性思考后,采取探索的最多次的行动。 游戏结束,退回并且评估哪一步错判了对未来的影响由此来更新认知。

这听起来不像你当时学习玩游戏的的过程? 当你下一步坏着,可能你错判了着后位置对未来的影响,或者你错误预测了对手的某个行动,所以你没有去想这种可能性。而这正是AlphaZero在游戏中学习训练的两个方面。

怎样构建你自己的AlphaZero

首先,为了得到较深层次AlphaGo Zero工作原理的理解,需要认真看AlphaGo Zero背后的文档。当我们过代码的每个部分时这很值得参考。这里同样有一篇好文章更详细解释 AlphaZero如何工作。

代码

套用这个包含我将引用代码的Git库。

开始学习流程之前,在Jupyter notebook顶部两个面板运行run.ipynb 。一旦它建立了足够的游戏位置的来填补它的记忆,神经网络就会开始训练。通过额外的自我博弈和训练,它会逐渐在预测上变好,从而做出更好的决策和使总体游戏行动更智能。

现在我们来更深入地了解代码,并且展示一些AI随着时间变强大的成果。

注意— 这是我自己基于上面参考文献对AlphaZero工作原理的理解.。如果以下有任何错误,我请求原谅并且会尽力改正!

Connect4

我们算法学习的游戏是 Connect4 (或者Four In A Row)。远没有围棋复杂… 但总计仍有 4,531,985,219,092种位置情况。

connect 4

游戏规则很简单。玩家在棋盘轮流从有空位列的顶部放一个他们颜色的棋子。第一个达到同色四珠相串的玩家即赢(包括水平,竖直,对角线)。如果棋盘放满也没有四珠相串,则游戏平局。

以下是组成代码库的核心文件总览:

game.py

每个方块被分配了一个从0到41的数字, 如下:

这个文件包含了connect4的游戏规则。

Connect4的行动方格

这个 game.py 文件提供了从一个游戏状态移动到另一个的逻辑,给出可选的动作。例如,给出一个空棋盘并进行放置38号空位,这个行动返回一个新的游戏台面,就是开始玩家的这枚棋子将在中间列底部。

你能用任何游戏文件替换game.py文件,只要它适用于相同的API,并且算法会在你给定的规则上通过自我博弈学会策略。

run.ipynb

这个文件包含了启动学习过程的代码。首先它会加载游戏规则,然后迭代算法的主循环,其中包含三个阶段:

  1. 自我博弈
  2. 神经网络再训练
  3. 神经网络评估

这个循环涉及到两个智能体,最强玩家和当前玩家。

最强玩家拥有表现最优的神经网络,用来产生自我博弈的学习记忆。当前玩家在这些记忆的基础上重新训练它的神经网络,然后再与最强玩家进行比赛。如果它赢了,最强玩家内部的神经网络就会被切换到当前玩家的神经网络,再开启新一轮循环。

agent.py

这段程序包含了智能体类(游戏中的一个玩家)。初始时,每个玩家都有自己的神经网络和蒙特卡罗搜索树。

模拟方法会运行蒙特卡罗树搜索过程。具体地说,智能体将移动到树的叶节点,用它的神经网络对节点进行评估,然后沿着树向上填充节点的值。

行动方法会多次重复模拟方法,从而获得从当前位置最有利的移动方式。接着,它将所选操作返回到游戏中,并执行这个动作。

重玩方法利用以前游戏中的记忆重新训练神经网络。

model.py

使用Keras构建的残差卷积网络样本

这个文件包含了Residual_CNN(残差卷积神经网络)类,它定义了如何构建一个神经网络的实例。

它使用AlphaGoZero论文中神经网络架构的压缩版-即一个卷积层,紧跟着是许多残差层,然后分裂成一个数值和策略头。

卷积滤波器的深度和数量可以在配置文件中设置。

Keras库用来构建网络,它的后端是Tensorflow。

想要查看神经网络中的单个卷积滤波器和紧密相连的层,运行下面run.ipynb文本中的程序。

current_player.model.viewLayers()

神经网络中的的卷积滤波器

MCTS.py

这段代码包含节点、边和MCTS类,构成了一个蒙特卡罗搜索树。

MCTS类包含前面提到的moveToLeaf和backFill方法,并且Edge类的实例储存了每个潜在移动方式的统计数据。

config.py

这段程序用来定义影响算法的关键参数。

调整这些变量将影响运行时间、神经网络的准确性和算法整体的成功。上面的参数生成了一个高水平Connect4玩家,但这要花很长时间才能做到。为了加快算法的速度,请尝试以下步骤。

funcs.py

这段程序包含了 playMatches 和 playMatchesBetweenVersions 函数,可以进行两个智能体之间的比赛。

为了和你创造的玩家进行比赛,运行下面的代码(它也在run.ipynb文本中)

initialise.py

当你运行该算法的时候,所有的模型和内存文件都保存在根目录的run文件夹中。

之后想要从这个节点重新启动算法,需要将run文件夹转移到run_archive文件夹,并在文件夹名称中添加一个运行编号。接着将运行号、模型版本号和内存版本号输入到initialise.py文件,与run_archive文件夹中的相关文件位置相对应。正常运行算法后将会从这个节点开始启动。

memory.py

内存类的一个实例,存储了之前的游戏记录,算法可以用它来训练当前玩家的神经网络。

loss.py

这份文件包含一个自定义的损失函数,在传递到交叉熵损失函数之前,它掩盖了非法移动的预测。

settings.py

定义了run和run_archive文件夹的位置。

loggers.py

日志文件保存在run文件夹中的log文件夹中。

想要启动日志记录,将文件中的logger_disabled 变量值设置为False。

查看日志文件可以帮助你理解算法是如何工作的,并且参透它的“思想”。例如这里有一个log.mcts文件的样本。

logger.mcts 文件输出

在评估阶段,同样从logger.tourney文件中,可以看到每次移动的概率:

logger.tourney 文件输出

结果

经过几天的训练,我们得到了下面的损失vs小批量迭代次数关系图。

损失vs小批量迭代次数关系图

最上面的线形图是策略头中的错误(MCTS移动概率的交叉熵vs神经网络的输出)。最下面线图是值头的误差(实际游戏值和神经网络推测值之间的平均平方误差)。中间线图是这两者的平均值。

显而易见,神经网络在预测每个游戏状态值和下一步可能动作方面表现越来越优异。为了展示它如何培养出一个逐步强大的玩家,我参加了17个玩家之间的一场联赛,逐步使用神经网络的第1次到49次迭代。

每场比赛都进行两次,双方都有机会走第一步。

这是最后的排名:

可以看出,神经网络后期版本赢得了大部分比赛,表现明显要优于前期版本。同时,我们可以发现学习还没有达到饱和——随着训练时间的增加,玩家将会逐步变强,学习越来越复杂的策略。

例如,尽早抢占中间列是神经网络一直偏爱的一个清晰策略。让我们观察一下算法的第1个版本和第30个版本之间的区别:

神经网络第一次迭代

神经网络第30次迭代

这是一个很好的策略,因为很多棋子相连成线都需要占有中心列——抢先占领它可以确保你的对手失去优势。这是没有任何人为输入的情况下,由神经网络自己学会的策略。

学习一种不同的游戏

在games文件夹中有一个game.py 文件,它是 ‘Metasquares’ 的游戏文件。这个游戏需要在网格中放置X和O标记,以形成不同大小的正方形。大方块比小方块得分更多,当网格被填满时,得分最多的玩家获胜。

如果你将Connect4的game.py文件替换成Metasquares游戏的 game.py文件,同样的算法也可以用来学习如何玩Metasquares。

博客原址 https://medium.com/applied-data-science/how-to-build-your-own-alphazero-ai-using-python-and-keras-7f664945c188

0 人点赞