深度强化学习:基于像素的Pong游戏

徐大白
2周前 阅读 182 点赞 4

这是一个迟来的强化学习(Reinforcement Learning,RL)的博客帖子。RL很热!您可能已经注意到,计算机现在可以自动(从游戏原始像素中)学习玩ATARI游戏,他们还在围棋比赛中击败了世界冠军,正在学习模拟四足动物跑步和跳跃,机器人正在学习如何执行复杂的违反显示编程的操作任务。事实证明,所有这些进步都以RL研究为保护伞。在过去的一年里,我也对RL产生了兴趣:我读了理查德·萨顿的书,学习了大卫·西尔弗的课程,看了约翰·舒尔曼的讲座,用Javascript编写了一个RL库,在DeepMind的深层RL小组实习了整个夏天,最近一次是在OpenAI Gym的设计/开发中做了一个新的RL基准测试工具包。所以,我当然已经参加这个活动至少一年了,但是直到现在,我还没有抽出时间写一篇短文,说明为什么RL如此重要,它是什么,是如何发展的,以及它可能走向何方。

RL举例。从左到右:深度Q-Learning网络玩ATARI游戏,Alpha-Go,Berkeley机器人堆乐高积木,物理模拟四足跳过地形

回顾RL的最新进展是很有意思的,我大体上分析出了四个推动AI发展的独立因素:

  1. 计算(最明显的一个因素:摩尔定律,GPU,ASICs);
  2. 数据(良好的数据,如:ImageNet);
  3. 算法(研究和想法,例如反向传播,CNN,LSTM);
  4. 基础架构(Linux,TCP/IP,Git,ROS,PR2,AWS,AMT,TensorFlow等)。

与计算机视觉类似,RL的最新进展并不是被想当然的新奇又合理的假设所驱动的。在计算机视觉中,2012 AlexNet很大程度上只是20世纪90年代的ConvNets的一个扩展(更深、更宽)。类似地,2013年的ATARI深Q学习论文只是标准的Q-Learning算法的实现(带函数逼近的Q-Learning,您可以在Sutton 1998的标准RL书中找到),其中函数逼近器碰巧是ConvNet。AlphaGo使用蒙特卡洛树搜索(Monte Carlo Tree Search,MCTS)的策略梯度——这些也是标准组件。当然,要让它起作用还需要很多技巧和耐心,并且在旧算法的基础上做了多个巧妙的调整。但是对于一阶近似来说,最近进展的主要驱动力不是算法,而是(类似于计算机视觉)计算、数据、以及基础架构。

现在回到RL。每当出现看似神奇其实简单的东西时,我都会感到心烦意乱,想为它写一篇文章。在这个例子中,我见过很多人,他们始终不相信我们能够通过一套算法,从简单的像素开始、从零开始自动学会玩大多数ATARI游戏的——这太不可思议了,我曾经也是这样认为的!但是,从本质上说,我们使用的方法也是比较笨的(尽管有点马后炮)。无论如何,我想带您浏览一下策略梯度(Policy Gradients,PG),这是我们目前最喜欢的用于处理RL问题的一个默认选项。

如果你是个门外汉,你可能会好奇我为什么不提出DQN(Deep Q Net,深度Q网络),毕竟这是一个可选择的更为知名的RL算法,在ATARI游戏论文中很受欢迎。事实证明Q-Learning并不是一个很棒的算法。事实上,大多数人更喜欢使用策略梯度,就连DQN原始论文的作者也证明了策略梯度在调优时能比Q-Learning取得更好的效果。

策略梯度的优势在于它是端到端的:存在一个显性的策略和方法直接优化预期的回报。无论如何,作为一个运行的例子,我们将学习玩一个使用策略梯度、从零开始、从像素到深层神经网络的ATARI游戏(Pong),整个过程是130行Python代码,只使用Numpy作为依赖项(Gist链接)。让我们开始吧。

基于像素的Pong游戏

上:Pong游戏。下:Pong是马尔科夫决策过程的一个特殊情况:一个图,其中每个节点都是特定的游戏状态,并且每个边都是可能转换的(概率问题)。每个边也给予奖励,目标是计算在任何状态下的最佳方式来最大化奖励。

Pong游戏是一个简单的RL任务的非常好的例子。在ATARI 2600版本中,我们将让您控制球拍之一(另一个由AI控制),并且您必须将球弹过另一个球员。在低级别上,游戏的工作原理如下:我们获得一个图像帧(210x160x3字节数组(从0到255给出像素值的整数)),然后决定向上或向下移动球拍(即二元选择)。在每次选择之后,游戏模拟器都会执行该动作并给我们一个奖励:如果对方没有接住球,奖励+1,如果对方接住了球,奖励-1,其他情况计0分。当然,我们的目标是移动球拍,这样我们就能得到很多奖励。

在我们讨论解决方案时,请记住,我们将尝试对Pong做出很少的假设,因为我们实际上并不关心Pong;我们关心的是复杂的、高维的问题,如机器人操作、装配和导航。Pong只是一个有趣的玩具测试用例,我们玩这个游戏的时候要去思考如何编写一个日后可以完成实际任务的通用AI系统。

策略网络

首先,我们将定义一个策略网络,用来实现我们的玩家(或“媒介”)。这个网络将根据当前游戏的状态,决定我们应该做什么(向上或向下移动)。简单起见,我们将使用一个2层神经网络,它获取原始图像像素(总数为100800个数字(210*160*3)),并生成一个指示上升概率的数字。注意,使用随机策略是标准的,这意味着我们只产生向上移动的概率。每一次迭代,我们将从这个分布中取样(即掷一个有偏的硬币)来得到实际的移动。一旦我们谈论训练,其原因将变得更加清楚。

我们的策略网络是一个2层完全连接的网络

这里要具体说明的是如何在Python或Numpy中实现这个策略网络。假设我们得到一个向量xx ,它保存(预处理)像素信息。我们将计算:

h = np.dot(W1, x) # compute hidden layer neuron activations
h[h<0] = 0 # ReLU nonlinearity: threshold at zero
logp = np.dot(W2, h) # compute log probability of going up
p = 1.0 / (1.0 + np.exp(-logp)) # sigmoid function (gives probability of going up)

在这个代码片断中,w2w_2w1w_1 是我们随机初始化的两个矩阵。注意,我们在末尾使用Sigmoid函数作为非线性函数,它将输出概率压制到[0,1]的范围内。直观地,隐藏层中的神经元(其权重沿w1w_1 行排列)可以检测各种游戏场景(例如,球在顶部,我们的球拍在中间),w2w_2 中的权重可以决定在每种情况下我们应该向上还是向下。所以现在唯一的问题是找到w1w_1w2w_2 ,这是决定玩家水平的决定因素!

注:预处理。理想情况下,你希望给策略网络馈送至少2帧,以便它能够检测运动。为了让事情简单一点(我在我的Macbook上做了这些实验),我会做一些小小的预处理,例如我们实际上将差分帧馈送给网络(即减去当前和最后一帧)。

听起来有点不可能。在这一点上,我希望你们能理解RL问题有多困难。我们得到100800个数字(210*160*3)并传送到我们的策略网络(在w1w_1w2w_2 中参数数目将是百万级别)。假设我们决定向上。游戏可能会作出回应,在这一步得到奖励0,并再给下一帧另外的100800个数字。在得到任何非零奖励之前,我们可以重复这个过程上百次。

假设我们最终得到+1。那太好了,但是我们怎么能知道是哪一帧造成了这个结果呢?是上一帧吗?还是76帧以前?或者它可能与10帧和90帧有关?我们又该如何更新参数,使其能有更好的表现呢?我们称之为信用分配问题(Credit Assignment Problem)。在Pong的特定情况下,我们知道当对手没有接到球时,我们就得到奖励+1。其直接原因是我们碰巧把球弹到一个巧妙的轨迹上,但事实上我们在很多帧之前都这样做了——例如,在Pong的情况下,可能大约有20帧,之后我们做的每个动作对于我们是否最终得到奖励都没有影响。换句话说,我们面临着一个非常困难的问题,事情看起来相当无望啊。

监督学习

在我们深入研究策略梯度解决方案之前,先来简要地回顾一下监督学习,因为正如我们将看到的,RL与监督学习非常相似。请参阅下面的图表。在一般的有监督学习中,我们将图像馈送到网络,并获得某种概率,例如,对于上移(UP)和下移(DOWN)。我给出的是两种行为的对数概率(-1.2,-0.36)而不是原始概率(本例中为30%和70%),因为我们总是优化正确标签的对数概率(这等价于优化原始概率,因为对数是单调的)。现在,在监督学习中,我们可以访问标签。例如,我们可能被告知现在正确的做法是上移(label 0)。在一个实现中,我们将对UP的对数概率输入1.0的梯度,并运行反向传播来计算梯度向量

这个梯度将告诉我们,我们应该如何调参,以使得网络稍微更有可能预测UP这一动作。例如,有一个梯度为-2.1的参数,这意味着如果我们要给该参数增加一个小的正量(例如,0.001),UP的对数概率将减少 -2.1*0.001 。如果我们随后进行参数更新,那么,我们的网络在将来看到非常相似的图像时更倾向于预测上移(UP)。

策略梯度

好吧,但是如果我们在强化学习设置中没有正确的标签,我们该怎么办?下面是策略梯度解决方案(参考下图)。我们的策略网络计算上升概率为30%(对数概率 - 1.2)和下移为70%(对数概率 - 0.36)。现在我们将从这个分布中采样一个动作;例如假设我们向下采样,我们将在游戏中执行。此时,请注意一个有趣的事实:我们可以像在监督学习中一样,立即为DOWN填充1.0的梯度,并且找到将鼓励网络在将来更倾向于执行DOWN操作的梯度向量。然后我们可以立即评估这个梯度,这很好,但问题是,至少目前我们还不知道DOWN是否好。没关系,我们可以稍等一下看看!例如,在Pong中,我们可以等到游戏结束,然后获取我们得到的奖励(赢了+1,输了-1),然后输入该标量作为我们采取的行动的梯度(本例中为“DOWN”)。在下面的例子中,下移让我们输掉了游戏(奖励-1)。因此,如果我们填-1表示下降的对数概率,并且做反向传播,我们就会发现一个梯度,它阻止网络在未来对这个输入采取下降动作(因为采取下移动作会导致我们输掉游戏)。

很简单,我们有一个随机的策略对动作进行抽样,激励那些最终带来胜利的动作,并抑制带来失败的动作(Menta Carol Search,蒙特卡罗搜索)。此外,如果我们最终赢得比赛,奖励甚至不需要是1或1,它可以是某种最终质量的任意度量。例如,如果结果非常好,可能是10.0,然后我们将其输入为梯度而不是-1来执行反向传播。这就是神经网络的美妙之处;使用它们可能会感觉像是作弊:允许将100万个参数嵌入1万亿次计算中,并且可以使用SGD执行任意操作。它本不该起作用,但有趣的是,我们生活在一个宇宙中,它可以做到。

训练准则

也就是训练过程。我们将用一些w1w_1w2w_2 初始化策略网络,并玩100局Pong游戏(我们称这些策略为“Rollouts”)。假设每个游戏由200个帧组成,因此我们总共做了20000次上移/下移的决策,我们知道每一次决策的参数梯度(这可以让我们知道之后该如何调参)。现在剩下的工作就是为每一个决策标注出“好”或“坏”。例如,我们赢了12场比赛,输了88场比赛。我们将在获胜的游戏中做出所有200*12=2400的决策,并进行正向更新(为相应的动作赋予+1.0的梯度,进行反向传播,更新参数)。并对输掉的88局比赛的200*88=17600个决策做负向更新。之后网络将更倾向于重复有效操作,抑制无效操作。现在我们用改进之后的策略网络再打10局游戏,循环往复。

策略梯度:对于一个策略,执行多次,观察哪些动作会带来高回报,提高执行他们的概率。

4局游戏的漫画图解。每个黑圈都是一些游戏状态(底部显示三个示例状态),每个箭头是一个过渡,用采样的动作进行注释。在这种情况下,我们赢了2场比赛,输了2场比赛。有了策略梯度,我们将赢得两场比赛,并稍微鼓励我们在这一幕中所做的每一个动作。相反,我们也会抑制两局失败游戏的动作。

如果你想通过这个过程,你会发现一些有趣的特性。举例来说,假如我们在第50帧中做出了一个好动作(正确地弹回球),但是在第150帧时丢了球呢?如果每一个动作现在都被标记为“坏”(因为我们输了),那么这不是否定了第50帧上的正确反弹吗?是的,然而,当你在数以千万计的游戏中考虑这个过程时,正确地进行第一次反弹会使你更倾向于赢得比赛,所以平均来说,你会看到更多正确的反弹的正向更新而不是负向更新,并且你的策略最终会做正确的事情。

更新

2016年12月9日-另类观点。在我上面的解释中,我使用了诸如“梯度填充(fill in the gradient)和反向传播(backprop)”之类的术语,我意识到如果习惯于编写自己的反向传播代码,或者使用Torch(梯度是显式的,并且可以进行修正),那么这是一种特殊的思想。然而,如果你习惯了Theano或TensorFlow,你可能会感到有点困惑,因为代码是围绕着指定一个损失函数而组织起来的,并且反向传播是完全自动的并且很难修改。在这种情况下,下面介绍的另一种观点可能更为直观。

在一般的监督学习中,目标是最大化4baec8b0-d9f7-401d-9047-47ca0c25b49d,其中xix_iyiy_i 都是训练实例(比如图像或其标签)。策略梯度与监督学习几乎完全相同,但有两个小的差异:

  1. 我们没有正确的标签yiy_i ,所以我们用“假标签”代替了我们在看到xix_i 时从策略中取样的动作,
  2. 我们基于最终结果成倍地调整每个示例的损失,因为我们希望增加有效操作的对数概率,并且减少无效操作的对数概率。

所以总之,我们的损失现在看起来像0df6cf05-7196-418b-813b-25ed29953784,其中yiy_i 是我们取样的动作,AiA_i 是一个我们称之为优势的数字。例如,在Pong游戏中,如果我们最终赢了,那么AiA_i =1,否则AiA_i =-1。这将确保我们最大化每一个正确动作的对数概率,并尽量减少失败动作的对数概率。所以虽然强化学习与监督学习类似,但在不断变化的有规模优势的数据集(片断地),我们只希望根据每个样本数据集进行一次(或极少数)更新。

更一般的优势函数

我还承诺再讨论一下回报问题。到目前为止,我们已经根据是否赢得比赛来判断单一动作的好坏。在更一般的RL设置中,我们将在每个步骤得到一些奖励rtr_t 。一种常见的选择是使用折扣奖励,因此上面的图表中的“最终奖励”将变成a3563593-766d-435e-a04a-86de6bdfda4e,其中9cb0da17-2f75-481c-89c9-68df4e4b5e4a(0-1)称为折扣因子(例如0.99)。该表达式表示,我们鼓励样本动作的强度是事后所有奖励的加权总和,但以后的奖励指数就不那么重要了。

在实践中,对回报值进行规范化也很重要。例如,假设我们计算上述100局Pong游戏中的20000个动作的回报值rtr_t可以考虑将回报值“标准化(Standardize,如减去平均值、去除标准差),然后再进行反向传播。这样,被激励和被抑制的动作大概各占一半。从数学角度上,你也可以将这些技巧解释为控制策略梯度估计器的方差的一种方法。这里可以找到更深入的探索。

策略梯度推导

接下来,我将从数学角度给出策略梯度的推导过程。策略梯度是一个更一般的记分函数梯度估计的特例。一般情况是,当我们有一个表达式0e078f63-340a-46ea-8d1c-67cc5aead0e6时-即某标量值评分函数f(x)f(x) 在由某个θ\theta 参数化的概率分布d7b4f52f-1cb0-4ef6-8ed3-2cb360531d2a下的期望。

提示,f(x)f(x) 将成为我们的回报函数(或更一般的优势函数,Advantage Function),p(x)p(x) 将成为我们的策略网络,它实际上是p(aI)p(a|I) 即在给定图像II 的前提下,动作的概率分布。

我们感兴趣的是我们应该如何根据ff (即,我们如何改变网络的参数使动作样本获得更高的回报)(通过其参数θ\theta )调整该分布以增加其样本的分数。我们有:

我们有一些分布p(x;θ)p(x;\theta) (简单记作p(x)p(x) ),我们可以从(如高斯分布)中采样。对于每个样本,我们还可以通过样本标量值分值评估其得分函数ff 。这个方程告诉我们,通过函数ff 我们可以知道如果我们希望它的样本达到更高的分数,我们应该如何通过其参数θ\theta 调整分布。更具体一点,我们采样出一些样本(动作)xx ,获得它们的得分f(x)f(x) ,同时对于xx 中的每一个样本计算式中的第二项。这个第二项是什么呢?它是一个向量,指向能够使得样本x 概率增加的参数更新方向。换句话说,如果我们在的方向上轻推θ,我们会看到分配给某个xx 的新的概率有略微增加。

回到上面的公式,最终的梯度是该向量与样本得分f(x)的乘积,从而使得得分更高的样本比得分较低的样本对分布p(x;θ)的影响更大。因此,如果我们基于来自pp 的几个样本进行更新,概率密度将向高分方向移动,使得高分样本更有可能。


分数函数梯度估计器的可视化

左:高斯分布和少量样本(蓝点)。在每个蓝色点上,我们还绘制了对数概率相对于高斯平均参数的梯度。箭头指示应该轻推分布的平均值以增加该样本的概率的方向。

中间:在一些小区域中,除了+1之外,所有地方都给出-1的一些得分函数的叠加(注意,这可以是任意的,不一定是可微的标量值函数)。现在箭头是彩色编码的,由于更新中的乘法,我们将平均所有绿色箭头,以及红色箭头的负数。

右:参数更新后,绿色箭头和反向红色箭头将我们推到左侧和底部。从这个分布的样本现在将有更高的期望分数,根据需要。

我希望策略网络与增强学习之间的关系已经讲得很清楚了。策略网络给我们提供了动作的样本,其中一些动作的得分(由优势函数给出)比其他动作高。部分所谈及的数学部分则指导我们如何更新策略网络的参数:计算相应动作的梯度,乘上它的得分,再更新网络参数。一个更全面的推导过程以及讨论,推荐大家看看John Sculman的讲座

学习

好的,我们已经了解了策略梯度及其推导过程。我在130行Python脚本中实现了整个方法,该脚本使用OpenAI Gym的AtARI 2600 Pong。我用RMSProp训练了一个2层策略网络,其中有200个隐藏层单元,分批使用10段(每段是几十个游戏,因为每个玩家的游戏最多达到21分)。我没有调参太多,而是在我的(慢)Macbook上运行了实验,但是在训练了3个晚上之后,我最终得到了一个比AI玩家稍微好一点的策略。片段的总数大约是8000,所以算法玩了大约200000局Pong游戏总共做了800次更新。我朋友告诉我,如果用ConvNets在GPU上训练几天,就可以更轻松地打败AI玩家,如果你还仔细地优化超参数了,你也可以持续地控制AI玩家(即赢得每场比赛)。然而,我没有花太多的时间计算或调整,所以我们最终得到了一个还不错的能说明问题的Pong AI

学习到的权重

我们也可以看看学习到的权重。由于预处理,我们的每一个输入是一个80x80差分图像(当前帧减去最后一帧)。现在我们可以w1w1按行展开 ,伸展到80x80并可视化。下面是网格中200个神经元其中的40个神经元的集合。白色像素是正权重,黑色像素是负权重。注意,几个神经元被调谐到特定的弹球轨迹上,沿线用黑白交替编码。球每个时刻只能在一个点,所以这些神经元是多任务的(multitasking),并在球出现在相应位置时被充分激活。当球沿着轨迹行进时,神经元的活动会以正弦波形起伏,并且由于ReLU的影响,神经元会沿着轨迹在离散的、分离的位置被激活。在图像中有一点噪音,也许可以通过L2正则化解决。

What isn’t happening

我们从原始像素与策略梯度学会玩Pong游戏。策略梯度算法是猜测和检查(Guess-and-Check)的一种巧妙形式,其中“猜测”指的是我们根据当前策略来对动作进行采样,“检查”指的是不断激励能够产生高分的动作。这代表了我们目前解决强化学习问题的最好方法。但是一旦你理解了它的工作方式,你多少会感到有点失望,并心生疑问——它在什么情况下会失效呢?

与人类学会玩Pong游戏相比,要注意以下区别:

  • 在实际场景中,人类通常以某种方式(比如:英语)对这个任务进行交流,但是在一个标准的强化学习问题中,我们只有与环境交互而产生的回报。假如人类在对回报函数一无所知的情况下学习玩这个游戏(尤其是当回报函数是某种静态但是随机的函数),那么他也许会遇到非常多的困难,而此时策略梯度的方法则会有效得多。类似的,假如我们把每一帧画面随机打乱,那么人类很可能会输掉游戏,而对于策略梯度法却不会有什么影响。
  • 人类有丰富的先验知识,比如物理相关(球的反弹,它不会瞬移,也不会忽然停止,它是匀速运动,等)与心理直觉。而且你也知道球拍是由你控制的,会对你的“上移/下移”指令作出回应。而我们的算法则是完全从一无所知的状态开始学习。
  • 策略梯度是一种brute force(暴力搜索)算法。正确的动作最终会被发现并被内化至策略当中。人类则会构建一个强大的抽象模型,并根据它来作出规划。在乒乓游戏里,我能够推断出对手速度很慢,因此将球快速击出可能是一个好的策略。然而,似乎我们最终同样会把这些好的策略内化至我们的肌肉记忆,从而作出反射式操作。比如,当我们在学习开手动档车的时候,你会发现自己在一开始需要很多思考,但是最终会成为一种自动而下意识的操作。
  • 采用策略梯度时需要不断地从正回报样本中进行学习,从而调整参数。而在人类进行学习的过程中,即使没有经历过相应的选择(样本),也能够判断出哪个动作会有较高的回报。比如,我并不需要上百次的撞墙经历才能够学会在开车时如何避免(撞墙)——这个例子举得感觉很好。

蒙特苏马的报复:一个困难的游戏,我们的RL算法。玩家必须跳下,爬上去,拿到钥匙,然后打开门。人类明白获得钥匙是有用的。计算机采样数十亿随机的移动,99%的概率会落下死亡或被怪物杀死。换句话说,很难“绊倒”奖励的情况。



另一个叫做“冻伤”的困难游戏,其中人类知道东西在移动,有些东西好摸,有些东西不好摸,目标是一块块地建造冰屋。对这个游戏的一个好的分析以及对人和计算机方法之间区别的讨论可以在《像人一样学习和思考的建筑机械》中找到。

在许多游戏中,策略梯度可以很容易地击败人类,尤其是任何具有频繁的奖励信号、需要精确播放、快速反应和不需要太多长期计划的东西的游戏。因为策略梯度可以容易地“注意到”奖励和动作之间的这些短期相关性,并且可以通过策略完美执行。你可以在我们的Pong AI中看到这种情况的暗示:它开发了一种策略,它等待球,然后快速冲刺,恰好在边缘抓住它,然后快速地以高垂直速度发射它。Pong AI连续几次重复这一策略以得分。有很多ATARI游戏,其中深度Q-Learning以弹球游戏(Pinball)、最后逃亡(BreakOut)等方式破坏人类基线性能。

总之,一旦你理解了这些算法工作的“诀窍”,你就可以推断出它们的优缺点。特别地,我们离像人类一样通过构建抽象而丰富的游戏表示以进行快速地规划和学习还差得很远。未来的某天,计算机将会从一组像素中观察到一把钥匙和一扇门,并且会想要拿起钥匙去开门。目前为止,我们离这个目标还有很长的距离,而且这也是相关研究的热点领域。

神经网络中的不可微计算

我想再提一个与游戏无关的策略梯度的有趣应用:它允许我们设计和训练具有执行(或交互)不可微计算的组件的神经网络。这个想法最初是威廉姆斯在1992年提出的,“Hard Attention”这个名称最早在“视觉注意力递归模型”这一文中提出。该文章主要是关于处理具有低分辨率中央凹眼序列的图像(灵感来自我们自己的人眼)。在每次迭代中,RNN将接收到一小块图像并采样下一个位置。例如,RNN可能查看位置(5,30),接收一小块图像,然后决定查看(24,50)等。这种想法的问题在于,存在一个网络,它产生接下来要查看的位置的分布,然后从中进行采样。不幸的是,这个操作是不可微分的,直观地说,我们不知道如果我们对不同的位置进行采样会发生什么。更一般地,要考虑从一些输入到输出的神经网络:

请注意,大多数箭头(蓝色)和常规一样是可微的,但是一些表示转换也可以选择性地包括不可微的采样操作(红色)。我们可以通过蓝色箭头支撑,但是红色箭头表示我们不能支撑的依赖性。

使用策略梯度可以解决这个问题!我们将网络中的采样过程视为嵌入在网络中的一个随机策略。那么,在训练时,我们将产生不同的样本(下图中的分支),然后我们在参数更新过程中对那些最终能够得到好结果(最终的loss小)的采样进行激励。换言之,对于蓝色箭头上的参数,我们依然按照一般的反向传播来更新;而对于红色箭头上的参数,我们采用策略梯度法更新。Gradient Estimation Using Stochastic Computation Graphs 对这一方法做了很好的形式化描述。

可训练记忆读写

你会在很多其他论文中看到这种想法,例如:Neural Turing Machine有一个可读写的存储带。在执行写操作时,我们可能执行的是类似 m[i]=x 的操作,其中 ix 是由RNN控制器预测的。但是这个操作并不可微,因为我们并不知道如果我们写的是一个不同的位置 j!=i 时 loss 会有什么样的变化。因此,NTM只好执行一种“软”的读/写操作:它首先预测一个注意力的分布 (attention distribution) a (按可写的位置进行归一化),然后执行:for all i: m[i] = a[i]*x。是的,这样做的确可微了,但是计算代价也高了很多。想象一下,我们每次赋值都需要访问整个内存空间!

然而,我们可以使用策略梯度来避免这个问题(理论上),正如RL-NTM所做的。我们仍然预测一个注意力的分布 a,再根据a 对将要写的地址 i 进行采样:i = sample(a); m[i] = x。在训练过程中,我们会对 i 采样多次,并通过策略梯度法来对那些最好的采样进行激励。这样一来,在预测时就只需要对一个位置进行读/写操作了。但是,正如这篇文章(RL-NTM)所指出的,策略梯度算法更适用于采样空间较小的情况,而在这种搜索空间巨大的任务中,策略梯度并不是很有效。

结论

我们看到策略梯度是一个强大的通用算法,作为示例,我们从原始像素、从零开始、在130行Python代码中训练了ATARI Pong Agent。更一般地,同样的算法可以用于训练任意游戏的代理,并且有望有一天在许多有价值的现实世界控制问题上。我想在结尾处再加上几句话:

关于推进人工智能。我们看到策略梯度算法是通过一个brute-force搜索的过程来完成的。我们同样看到人类用以解决同样问题的方法截然不同。正是由于人类所使用的那些抽象模型非常难以(甚至不可能)进行显式地标注,所以最近越来越多的学者对于(无指导)生成模型(generative models)以及程序归纳(program induction)产生了兴趣。

在复杂机器人场景中的应用。将策略梯度算法应用到搜索空间巨大的场景中并非易事,比如机器人控制(一个或多个机器人实时与现实世界进行交互)。解决这个问题的一个相关研究思路是:确定性的策略梯度(deterministic policy gradients),这种方法采用一个确定性的策略,并从一个额外的估值网络(称为critic)中获取梯度信息。另一种思路是增加额外的指导。在很多实际的情形中,我们能够从人类玩家那儿获取一些专业的指导信息。比如AlphaGo先是根据人类玩家的棋谱,使用有监督学习得到能够较好地预测人类落子方式的策略,然后再使用策略梯度算法对此策略进行调整。

策略梯度在实际中的使用。在我之前关于RNN的博文中,我可能已经让大家看到了RNN的魔力。而事实上让这些模型有效地工作是需要很多小技巧(trick)支撑的。策略梯度法也是如此。它是自动的,你需要大量的样本,它可以一直学下去,当它效果不好的时候却很难调试。无论什么时候,当我们使用火箭炮之前必须先试试空气枪。以强化学习为例,我们在任何时候都需要首先尝试的一个(强)基线系统是:交叉熵。假如你坚持要在你的问题中使用策略梯度,请一定要注意那些论文中所提到的小技巧,从简单的开始,并使用策略梯度的的一种变型:TRPO。TRPO在实际应用中几乎总是优于基本的策略梯度方法。其核心思想是通过引入旧策略和更新之后策略所预测的概率分布之间的KL距离,来控制参数更新的过程。


原文链接:Deep Reinforcement Learning: Pong from Pixels

翻译:徐大白


| 4
登录后可评论,马上登录吧~
评论 ( 3 )
厉害了我的大白~
回复
6天前
可以出本书了
回复
6天前
您好,有兴趣写本书么?我这边是策划编辑
回复
2周前