AlphaGo是如何实现的

前言


最近看了AlphaGo的论文:Mastering then Game of Go with Deep Nerual Networks and Tree Search。惊异于这些人的创造力和神经网络的强大,能够把围棋这种游戏做到这种地步。写一写论文里的方法和自己的思考吧,这篇文章基本都是论文中的观点,只是以我的视角去解读,有错误的地方欢迎指出。

关于棋盘对弈游戏


还记得在大学的时候,学校举办了一个人工智能挑战赛,题目是要做一个黑白棋的AI,当时运气好得了第一,不过并没有用到很厉害的方法。主要是搜索+估值,围棋和黑白棋一样,是具有完美信息的游戏,对于某一个状态(盘面),如果所有玩家完美发挥,下一步的选择是有一个最优值的,然而,对于人来说,要计算出所有走法是不现实的,对于计算机呢?情况或许会好一点,计算的能力当然比人更强一点,但实际上,还是不能穷举所有可能。

黑白棋的棋盘只有8x8,而围棋却是19x19,这不是几倍的差距,是好几个数量级的差距了。对于围棋来说,如果使用搜索的方法,搜索树大概包括 bd 个走子,其中 b 是搜索的广度(每个状态下的合法走法), d 是搜索的深度,那么 b250,d150 。想要穷举所有可能,以现在计算机的算力,估计得等好几辈子吧~

但是呢,我们可以去简化这个过程,不是去得到一个确定的,最优的结果,而是去寻找一个尽可能好的结果,这是可能的。首先,搜索树的深度可以通过价值函数来减少,价值函数是什么呢?对于某个到达的盘面状态 s ,可以通过一个价值函数 v(s) 来给出当前状态下,得到最终结果的预估值,这样,我们就可以把这个值近似于最终的结果,当搜索到一定深度的时候,就去求 v(s) ,并把它当作最终结果,不再往下搜索,达到减少搜索树深度的目的。其次,搜索的广度可以通过策略函数 p(a|s) 来减少,其实很简单,就是不要去搜索所有可能的走法,只挑一些看起来可能利益比较大的点去寻找,这也是人类下棋时的习惯。

蒙特卡洛树(MCTS)在棋盘搜索中的应用


首先说一下蒙特卡洛方法吧,这其实就是一个通过概率来求解的方法或者说思想。原理是通过大量随机样本,去了解一个系统,进而得到所要计算的值。
它非常强大和灵活,又相当简单易懂,很容易实现。对于许多问题来说,它往往是最简单的计算方法,有时甚至是唯一可行的方法。

举个,简单的例子,求圆周率 π ,就可以通过在下图的正方形区域内,随机 n 个点 (x,y) ,通过计算这些点与中心的距离,判断是否在圆内,最后通过面积公式和这些点在圆内的概率,估算圆周率的值。
这里写图片描述

知道了蒙特卡洛方法,再看蒙特卡洛树,其实就是把它移到树上罢了。它的思想也是通过进行大量的模拟(rollouts),最后想要将答案收敛到某个分支。蒙特卡洛树有四个步骤:
1. 选择(Selection):从根节点开始,不断递归选择最优的子节点,直到达到一个叶结点。选择最优子节点根据公式 vi+C×lnNni ,其中 vi 是节点估计的值, ni 是节点被访问的次数,而 N 则是其父节点已经被访问的总次数, C 是一个常量。
2. 扩展(Expansion):当前节点不是终止节点(游戏未结束),并且访问该节点次数超过某个设定的阈值,则在创建一个或多个子节点。
3. 模拟(Simulation):从当前叶结点开始,通过随机获采用某个走子策略 p ,模拟走子,直到游戏结束。
4. 回传(Backpropagation):根据模拟的最终结果,反向更新搜索树。

蒙特卡洛树就简单介绍到这里吧,有兴趣可以在网上找到别的资料。在AlphaGo出来之前,最强的围棋Ai就是基于MCTS的,AlphaGo也采用了MCTS的方法再加上神经网络的优化,最终完成了战胜人类职业选手的壮举。

结构


在学习AlphaGo的算法之前,对它的结构有一个大概的认知是很有必要的。我们要知道,它用了神经网络做了什么,用了MCTS又做了些什么。
1. 有监督学习策略网络 pσ :通过有监督学习(SL:supervised learning),让神经网络学习专业选手的走子,这个训练通过立即的反馈和高质量的梯度提供了快速有效的学习更新。
2. 可以快速决策的策略网络 pπ :这是为了让在下棋时可以更快地给出走子策略,毕竟大型的网络比较耗时,不过质量上比 pσ 要差一些。
3. 用增强学习训练策略网络 pρ :使用增强学习(RL:reinforcement learning)方法,通过自我对弈来优化策略网络的目的——由提高预测人类走子到提高胜率。
4. 训练价值网络 vθ :这个神经网络是用来预测一个盘面下,使用RL策略网络自我对弈的胜率。
5. MCTS:将策略网络与价值网络有效结合起来,对最优方案进行搜索。
这里写图片描述

策略网络的有监督学习


这个训练实际上是通过深度卷积神经网络和人类棋手的对弈数据,让AI能够预测专业选手的走子。SL策略网络为 pσ(a|s) ,对于输入的棋盘盘面 s ,最后网络输出所有合法动作 a 的概率分布。训练的评判标准就是最大化在状态 s 时与人类选择走子的 a 的似然度。

SL策略网络是一个13层的深度卷积神经网络,网络的输入是由48个特征平面组成的19 x 19 x 48的图像栈,第1个隐藏层把输入处理为23 x 23的图像,边界补0。然后用核为5 x 5,跨度为1的k个滤波器对图像进行卷积。第2-12个隐藏层将前面的输出图像补0成21 x 21的图像,同样用k个滤波器进行卷积(核3 x 3 ,跨度为1),最后的输出应用softmax函数。AlphaGo的比赛版本使用的k=192。

训练用的数据是从KGS服务器上弄下来的2940万个棋盘的盘面数据(KGS是一个围棋服务器:http://www.gokgs.com/)。

训练的方式是将KGS上的2940万个盘面数据,分为测试集(前100万盘)和训练集(剩下的2840万盘),对于训练集,可以通过将棋盘进行反射/旋转操作以扩充为原来的8倍。一个训练步骤是从训练集中随机选择m=16个样例组成一个mini-batch,应用异步随机梯度下降法(SGD)进行训练,学习率最开始为0.03,然后每8000万个训练步骤后学习率减半,一共训练了3亿4千万个训练步骤。一看这数据量……就知道训练是一个很耗时的工作,没有机器的支持,看起来很难训练出一个很好的网络。AlphaGo使用了50个GPU,大概花费了3周。

最终,这个网络预测专业选手的走子的准确率是57.7%(输入全部特征,详细见下一节)。预测的准确性的一点点提高都可以大大提高棋力,提高网络的大小和复杂性可以获得更好的效果,这样的代价就是要花费更多的时间。

关于特征


前面说SL策略网络的时候提到了棋盘的特征,这个是根据棋盘盘面提取的一些额外的数据,实际上包括了人类看棋盘的一些特征,比如气,吃子,眼等等,这里贴上论文中给出的特征表。
这里写图片描述

训练快速决策的策略网络


AlphaGo训练了另一个可以快速决策的策略网络 pπ(a|s) ,这是为了提高搜索时的速度,使用前面的策略网络选择一个动作需要3ms,而这个网络只需要2us。 pπ 策略网络的是基于小模式特征(small pattern features)训练的线性softmax网络,最终预测的准确性是24.2%。虽然比SL策略网络少了一半多,但是胜在速度很快,是它的1500倍,这意味着能搜索更多的点,可以进行更多次的模拟,在这个角度上看,还是利大于弊的。下面附上small pattern的表,这个没看懂,应该是类似围棋里的定势之类的吧。
这里写图片描述

策略网络的增强学习


增强学习(RL)是通过策略网络的自我对弈完成的。RL网络的结构和SL是相同的,训练的开始,把RL的权重设置成SL网络的权重,然后用先前的版本组成一个对手池,每次迭代让当前版本的策略网络 pσ 随机从对手池中选择一个对手进行对抗,每进行500次迭代,就把当前的参数作为新的对手加入对手池。

对于非结束步骤 t<T ,回报函数 r(s) 为0。输出 ZT=±r(sT) 表示在 t 时刻,对于游戏最终结果的预期(+1代表赢,-1代表输)。训练就是使用随机梯度上升法,最大化这个期望。

最终使用RL策略网络对抗SL策略网络,胜率为80%。Pachi是最强的开源围棋程序,在不使用搜索的情况下,对抗Pachi,胜率为85%。由此看来,即使不使用搜索,这个策略网络也足够强了啊。

价值网络的增强学习


价值网络其实要做的就是对棋盘盘面的评估,在最理想的情况下,是存在一个能完美判断当前局面是否能赢的价值函数 v(s) ,但实际上,我们并不能得到这个函数,因此,只能求一个近似的函数。

根据前面的训练结果,我们有一个最强的策略函数 pρ ,再采用这个策略函数取得的价值函数 vp(s) 是当前能得到最优的结果了,因此,可以用它近似最优价值函数,即 vpρ(s)v(s) 。到这里还没完,实际上,我们不能用RL策略函数对每个盘面模拟达到终盘以求出价值函数,这样太耗时了,这个时候就可以使出一只使用的经典手段:用训练一个神经网络来预估使用RL策略网络得到的盘面估值,记作 vθ(s) 。最终近似结果如下:

vθ(s)vpρ(s)v(s)

价值网络的权重是基于盘面-结果对 (s,Z) 来训练的,最终的评判结果是根据预测函数 vθ(s) 和对应的结果Z之间的均方差(MSE : mean squared error)来判定的。对于选用的训练数据,不能直接采用整个比赛来进行,因为一整盘棋的局势是强相关的,每个盘面之间的差距只有一个子,但是结果却是全盘比赛状态共享的,如果使用这种方法,会导致过拟合。

为了减轻这个问题,AlphaGo生成了3千万个比赛结果,并且每个比赛结果都是从单独的比赛采样。每盘比赛,随机一个值作为时间步骤 U(1450) ,然后对于 t=1...U1 步,使用SL策略网络走子,第 U 步选择一个随机走子,剩下就使用RL策略网络走子知道游戏结束,得到最终的结果 ZT 。对于每局比赛,只有一个训练样例 (sU+1,ZU+1) 被加入训练数据集。

结合策略和价值网络的MCTS


有了高质量的策略和价值函数,还需要一个好的算法把它们有效地结合与利用起来。AlphaGo实现了一个异步的策略和价值MCTS算法(APV-MCTS)。搜索树的点表示棋盘的一个盘面 s ,边表示一个合法动作 a
每条边保存了以下信息:
- P(s,a) :先验概率,即策略网络输出的选择当前action的概率。
- Wv(s,a) :在其子树计算的价值网络输出的总和。
- Wr(s,a) :在其子树计算的rollouts结果输出的总和。
- Nv(s,a) : 其子树叶结点用价值网络估值次数的累积。
- Nr(s,a) :其子树叶结点使用rollouts计算结果次数的累积。
- Q(s,a) :这条边的平均动作值(action-value)。

下面简单描述一下搜索的过程,和上面讲MCTS说过的四个步骤是有一些区别的:
1. 选择(Selection):每次mcts的模拟计算都是从树的根开始,在到达叶结点之前的任意时间 t ,选择的下一个子节点是根据当前的搜索树中的统计数据: at=argmaxa(Q(st,a)+u(st,a)) ,其中 u(st,a) 使用了PUCT算法的变种:

u(s,a)=cpuctP(s,a)bNr(s,b)1+Nr(s,a)

上式中的 cpuct 是个常数,决定了探索的级别,这个搜索的策略最开始倾向于选择具有高的先验概率,低访问次数的边,然后随着搜索次数增加,逐渐倾向于具有高动作值的边。
2. 评估(Evaluation):当访问到一个叶结点时,如果这个结点没有被评估过,那么就把它加入到一个队列中,等待用价值网络对其进行评估。与此同时,使用rollout策略,从这个叶结点开使下棋,直到游戏结束,得到最终的计算结果 zt=±r(sT)
3. 回传(Backup):在进行模拟的每一步 t ,在得到结果进行更新之前,我们可以假设它已经输了 nv1 局,这样的好处是降低了它的动作值,可以防止其他线程做同样的选择,也就是进行操作: Nr(st,at)Nr(st,at)+nv1,Wr(st,at)Wr(st,at)nv1 ,当rollout结束,获得结果的时候,再通过回溯,更新每一条边,用真正的结局代替虚拟败局: Nr(st,at)Nr(st,at)nv1+1,Wr(st,at)Wr(st,at)+nv1+zt 。与此同时,当价值网络的估值结束时,第二个回溯过程触发,同样是更新每一条边: Nv(st,at)Nv(st,at)+1;Wv(st,at)Wv(st,at)+vθ(sL) ,价值网络只需要评估一次,因此不需要设置虚拟败局。最终,整个盘面的动作值是价值网络和rollout评估的加权平均,权重参数为 λ
Q(s,a)=(1λ)Wv(s,,a)Nv(s,a)+λWr(s,,a)Nr(s,a)

4. 扩充(Expansion):当一条边的访问次数超过一个阈值 Nr(s,a)>nthr ,那么这条边对应的状态 s 才被加到搜索树中,新的结点的各个action,也就是对应的边,除了先验概率,其他变量都初始化为0。先验概率使用另一个更简单的策略函数(论文里称为tree policy)来计算一个占位用的概率,然后把 s 丢到另一个计算策略网络的队列中进行计算,等计算结果出来后再替换用来占位的概率。另外,阈值 nthr 是动态调整的,确保扩展的速度与计算策略网络结果的速度相适应。
这里写图片描述

搜索的最后,AlphaGo最后会选择访问次数最多的结点,这比使用最大动作值的好处是对于极端情况不会很敏感。在对手进行落子以后,搜索树会将对手选择的子树重用,而其他分支则被抛弃。比赛的时候,在对手想棋的时候,还可以继续搜索。

结束


差不多就到这里了吧,虽然还有很多细节没有说,但剩下的还是仔细读原文吧。这个论文还没有读得很透测,可以好好研究一下,看看这些大神是如何把被认为是至少10年后电脑围棋才能达到的水平实现的,膜拜一下。

发布了443 篇原创文章 · 获赞 149 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/qian99/article/details/69053080
今日推荐