AlphaZero 实战:从零学下五子棋(附代码)_alphazero: mastering chess and shogi by self-play -程序员宅基地

技术标签: RL  

雷锋网(公众号:雷锋网) AI 科技评论按,本文作者一缕阳光,本文首发于知乎专栏强化学习知识大讲堂,雷锋网 AI 科技评论获其授权转载。

2 个多月前,AlphaGo Zero 横空出世,完全从零开始,仅通过自我对弈就能天下无敌,瞬间刷爆朋友圈,各路大神分分出来解读,惊叹于其思想的简单、效果的神奇。很快就有大神放出了开源版的 AlphaGo Zero,但是只有代码,没有训练出来的模型,因为据大神推算,在普通消费级的电脑上想训练出 AlphaGo Zero 的模型需要 1700 年!然而 DeepMind 在 AlphaGo Zero 的论文里只强调运行的时候需要 4 个 TPU,而完全没有提及训练过程的最大计算需求在于生成 self-play 数据,还引起了一点小争议。

还好,过了不到两个月,在 12 月初,DeepMind 就在 Arxiv 上低调放出了更加通用的 AlphaZero 的论文。AlphaZero 几个小时就征服围棋、国际象棋和日本将棋的壮举再次惊叹世人,但同时 DeepMind 大方公开的 self-play 阶段使用的 5000 个 TPU 也让大家纷纷感叹,原来是“贫穷限制了我们的想象力”!

扯得有点远了,让我们回到这篇文章的正题:AlphaZero 实战,通过自己动手从零训练一个 AI,去体会 AlphaZero 自我对弈学习成功背后的关键思想和一些重要技术细节。这边选择了五子棋作为实践对象,因为五子棋相对比较简单,大家也都比较熟悉,这样我们能更专注于 AlphaZero 的训练过程,同时也能通过亲自对阵,来感受自己训练出来的 AI 慢慢变强的过程。

经过实践发现,对于在 6*6 的棋盘上下 4 子棋这种情况,大约通过 500~1000 局的 self-play 训练(2 小时),就能训练出比较靠谱的 AI;对于在 8*8 的棋盘上下 5 子棋这种情况,通过大约 2000~3000 局自我对弈训练(2 天),也能得到比较靠谱的 AI。所以虽然贫穷,但我们还是可以去亲身感受最前沿成果的魅力!完整代码以及 4 个训练好的模型已经上传到了 github:https://github.com/junxiaosong/AlphaZero_Gomoku

我们先来看两局训练好的 AI 模型(3000 局 self-play 训练得到)对弈的情况,简单感受一下:

每一步棋执行 400 次 MCTS 模拟

每一步棋执行 800 次 MCTS 模拟

从上面的对局样例可以看到,AI 已经学会了怎么下五子棋,知道什么时候要去堵,怎么样才能赢,按我自己对阵 AI 的感受来说,要赢 AI 已经不容易了,经常会打平,有时候稍不留神就会输掉。

这里有一点需要说明,上面展示的两局 AI 对弈中,AI 执行每一步棋的时候分别只执行了 400 次和 800 次 MCTS 模拟,进一步增大模拟次数能够显著增强 AI 的实力,参见 AlphaZero 论文中的 Figure 2(注:AlphaZero 在训练的时候每一步只执行 800 次 MCTS simulations,但在评估性能的时候每一步棋都会执行几十万甚至上百万次 MCTS 模拟)。

下面,我结合 AlphaZero 算法本身,以及 github 上的具体实现,从自我对局和策略价值网络训练两个方面来展开介绍一下整个训练过程,以及自己实验过程中的一些观察和体会。

自我对局(self-play) self-play过程示意图

完全基于 self-play 来学习进化是 AlphaZero 的最大卖点,也是整个训练过程中最关键也是最耗时的环节。这里有几个关键点需要说明:

1. 使用哪个模型来生成 self-play 数据?

在 AlphaGo Zero 版本中,我们需要同时保存当前最新的模型和通过评估得到的历史最优的模型,self-play 数据始终由最优模型生成,用于不断训练更新当前最新的模型,然后每隔一段时间评估当前最新模型和最优模型的优劣,决定是否更新历史最优模型。

而到了 AlphaZero 版本中,这一过程得到简化,我们只保存当前最新模型,self-play 数据直接由当前最新模型生成,并用于训练更新自身。直观上我们可能会感觉使用当前最优模型生成的 self-play 数据可能质量更高,收敛更好,但是在尝试过两种方案之后,我们发现,在 6*6 棋盘上下 4 子棋这种情况下,直接使用最新模型生成 self-play 数据训练的话大约 500 局之后就能得到比较好的模型了,而不断维护最优模型并由最优模型生成 self-play 数据的话大约需要 1500 局之后才能达到类似的效果,这和 AlphaZero 论文中训练 34 小时的 AlphaZero 胜过训练 72 小时的 AlphaGo Zero 的结果也是吻合的。

个人猜测,不断使用最新模型来生成 self-play 数据可能也是一个比较有效的 exploration 手段,首先当前最新模型相比于历史最优模型一般不会差很多,所以对局数据的质量其实也是比较有保证的,同时模型的不断变化使得我们能覆盖到更多典型的数据,从而加快收敛。

2. 如何保证 self-play 生成的数据具有多样性?

一个有效的策略价值模型,需要在各种局面下都能比较准确的评估当前局面的优劣以及当前局面下各个 action 的相对优劣,要训练出这样的策略价值模型,就需要在 self-play 的过程中尽可能的覆盖到各种各样的局面。

前面提到,不断使用最新的模型来生成 self-play 数据可能在一定程度上有助于覆盖到更多的局面,但仅靠这么一点模型的差异是不够的,所以在强化学习算法中,一般都会有特意设计的 exploration 的手段,这是至关重要的。

在 AlphaGo Zero 论文中,每一个 self-play 对局的前 30 步,action 是根据正比于 MCTS 根节点处每个分支的访问次数的概率采样得到的(也就是上面 Self-play 示意图中的 

3. 始终从当前 player 的视角去保存 self-play 数据

在 self-play 过程中,我们会收集一系列的 

4. self-play 数据的扩充

围棋具有旋转和镜像翻转等价的性质,其实五子棋也具有同样的性质。在 AlphaGo Zero 中,这一性质被充分的利用来扩充 self-play 数据,以及在 MCTS 评估叶子节点的时候提高局面评估的可靠性。但是在 AlphaZero 中,因为要同时考虑国际象棋和将棋这两种不满足旋转等价性质的棋类,所以对于围棋也没有利用这个性质。

而在我们的实现中,因为生成 self-play 数据本身就是计算的瓶颈,为了能够在算力非常弱的情况下尽快的收集数据训练模型,每一局 self-play 结束后,我们会把这一局的数据进行旋转和镜像翻转,将 8 种等价情况的数据全部存入 self-play 的 data buffer 中。这种旋转和翻转的数据扩充在一定程度上也能提高 self-play 数据的多样性和均衡性。

策略价值网络训练 策略价值网络训练示意图

所谓的策略价值网络,就是在给定当前局面 

1. 局面描述方式

在 AlphaGo Zero 中,一共使用了 17 个 

在我们的实现中,对局面的描述进行了极大的简化,以 

其实在最开始尝试的时候,我只用了前两个平面,也就是双方的棋子的位置,因为直观感觉这两个平面已经足够表达整个完整的局面了。但是后来在增加了后两个特征平面之后,训练的效果有了比较明显的改善。个人猜想,因为在五子棋中,我方下一步的落子位置往往会在对手前一步落子位置的附近,所以加入的第三个平面对于策略网络确定哪些位置应该具有更高的落子概率具有比较大的指示意义,可能有助有训练。同时,因为先手在对弈中其实是很占优势的,所以在局面上棋子位置相似的情况下,当前局面的优劣和当前 player 到底是先手还是后手十分相关,所以第四个指示先后手的平面可能对于价值网络具有比较大的意义。

2. 网络结构

在 AlphaGo Zero 中,输入局面首先通过了 20 或 40 个基于卷积的残差网络模块,然后再分别接上 2 层或 3 层网络得到策略和价值输出,整个网络的层数有 40 多或 80 多层,训练和预测的时候都十分缓慢。

所以在我们的实现中,对这个网络结构进行了极大的简化,最开始是公共的 3 层全卷积网络,分别使用 32、64 和 128 个 

3. 训练目标

前面提到,策略价值网络的输入是当前的局面描述 

根据上面的策略价值网络训练示意图,我们训练的目标是让策略价值网络输出的 action 概率 

从优化的角度来说,我们是在 self-play 数据集上不断的最小化损失函数: 

下图展示的是一次在 

在训练过程中,除了观察到损失函数在慢慢减小,我们一般还会关注策略价值网络输出的策略(输出的落子概率分布)的 entropy 的变化情况。

正常来讲,最开始的时候,我们的策略网络基本上是均匀的随机输出落子的概率,所以 entropy 会比较大。随着训练过程的慢慢推进,策略网络会慢慢学会在不同的局面下哪些位置应该有更大的落子概率,也就是说落子概率的分布不再均匀,会有比较强的偏向,这样 entropy 就会变小。

也正是由于策略网络输出概率的偏向,才能帮助 MCTS 在搜索过程中能够在更有潜力的位置进行更多的模拟,从而在比较少的模拟次数下达到比较好的性能。

下图展示的是同一次训练过程中观察到的策略网络输出策略的 entropy 的变化情况。

另外,在漫长的训练过程中,我们最希望看到的当然是我们训练的 AI 正在慢慢变强。所以虽然在 AlphaZero 的算法流程中已经不再需要通过定期评估来更新最优策略,在我们的实现中还是每隔 50 次 self-play 对局就对当前的 AI 模型进行一次评估,评估的方式是使用当前最新的 AI 模型和纯的 MCTS AI(基于随机 rollout)对战 10 局。

pure MCTS AI 最开始每一步使用 1000 次模拟,当被我们训练的 AI 模型 10:0 打败时,pure MCTS AI 就升级到每一步使用 2000 次模拟,以此类推,不断增强,而我们训练的 AlphaZero AI 模型每一步始终只使用 400 次模拟。在上面那次 3050 局自我对局的训练实验中,我们观察到:

经过 550 局,AlphaZero VS pure_MCTS 1000 首次达到 10:0

经过 1300 局,AlphaZero VS pure_MCTS 2000 首次达到 10:0

经过 1750 局,AlphaZero VS pure_MCTS 3000 首次达到 10:0

经过 2450 局,AlphaZero VS pure_MCTS 4000 取得 8 胜 1 平 1 负

经过 2850 局,AlphaZero VS pure_MCTS 4000 取得 9 胜 1 负。

OK,到这里整个 AlphaZero 实战过程就基本介绍完了,感兴趣的小伙伴可以下载我 github 上的代码进行尝试。为了方便大家直接和已经训练好的模型进行对战体验,我专门实现了一个纯 numpy 版本的策略价值前向网络,所以只要装了 python 和 numpy 就可以直接进行人机对战啦,祝大家玩的愉快!^_^

参考文献:

AlphaZero: Mastering Chess and Shogi by Self-Play with a General Reinforcement Learning Algorithm

AlphaGo Zero: Mastering the game of Go without human knowledge

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/AMDS123/article/details/79092978

智能推荐

什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?_成员内部类和局部内部类的区别-程序员宅基地

文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别

分布式系统_分布式系统运维工具-程序员宅基地

文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具

用Exce分析l数据极简入门_exce l趋势分析数据量-程序员宅基地

文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量

宁盾堡垒机双因素认证方案_horizon宁盾双因素配置-程序员宅基地

文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置

谷歌浏览器安装(Win、Linux、离线安装)_chrome linux debian离线安装依赖-程序员宅基地

文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖

烤仔TVの尚书房 | 逃离北上广?不如押宝越南“北上广”-程序员宅基地

文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...

随便推点

java spark的使用和配置_使用java调用spark注册进去的程序-程序员宅基地

文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序

汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用_uds协议栈 源代码-程序员宅基地

文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码

AUTOSAR基础篇之OS(下)_autosar 定义了 5 种多核支持类型-程序员宅基地

文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型

VS报错无法打开自己写的头文件_vs2013打不开自己定义的头文件-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件

【Redis】Redis基础命令集详解_redis命令-程序员宅基地

文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令

URP渲染管线简介-程序员宅基地

文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线