深度学习第11期:基于Policy的强化学习

在前面的科普文中,我们介绍了强化学习问题的定义,主要的分类。然后,我们又集中介绍基于Q的强化学习问题,如何建立模型、如何训练模型。在本文中,我们将介绍基于policy的问题,如何建立以及训练模型。

如果我们拥有一个policy网络,则对于输入的状态,我们就可以直接输出动作。但有时候,我们是单独训练一个policy网络,而有的时候我们则是同时训练policy网络与Q网络。训练结束后,我们可以直接使用policy网络决策,用不到Q网络。但是训练过程中,Q网络却可以帮助我们加快训练的效率。

我们曾介绍过,离散动作问题主要有三类方法解决,除了第一类单独训练DQN外。另外两类是训练一个policy 网络的PG与同时训练Q网络与policy网络,然后还是用policy网络决策的Actor-Critic。而在连续问题中,同样也有两类方法——第一类是随机策略网络(SPG),即训练一个policy网络,然后根据随机原则去选择a,即SPG;第二是确定性策略网络(DPG),即同时训练Q网络与policy网络,然后还是用policy网络决策,并且采用确定性决策。由此可见,单独的policy网络与配合的policy网络及Q网络,都可以用在离散与连续的问题上。

要注意的是,SPG中我们既可以同时训练Q网络与policy网络,也可以只训练policy网络(但这里我们不探讨前者只探讨后者)。而对于DPG而言,我们必须同时训练Q网络与policy网络。并且,Policy net与Q net都需要同时训练target net与eval net。前者是后者一个比较旧的版本,每过一定数量的batch更新一次使得二者统一。这就会使得整个网络的结构非常复杂。在Actor-Critic算法中,Q网络的作用只是辅佐policy网络训练,加快训练速度。但是在DDPG中,为了训练policy网络,Q网络是必不可少的。这也就是说,DDPG中,polic网络应该更加充分地表达对于Q网络的尊敬。

回顾一下之前讲的所有方法。其中离散问题只训练DQN的方法我们在上一章已经介绍过了。这里剩下的四种方法都将在本篇介绍。值得注意的是,虽然上一章只讲了DQN,但是它讲到的有关局部收敛与off-policy的思想,在本篇要讲到的四种方法里,两种含有Q网络的方法中,都是很重要的。

在基于Q的学习中,我们想象有一个“客观存在的”最佳策略,所以每个Q(s,a)也有一个“客观存在”的Q。我们训练就是让Q(s,a)接近这个“客观存在”的值。当然,由于上面我们描述过的原因,去学习这个“客观存在”的值的过程远远不像监督学习一般容易,存在着局部收敛的风险。但是,我们想象这确实是客观存在的一个标准,等待着Q网络去拟合。

而policy gradient是完全另一个概念。它的函数P本身就是一个agent。面对s,P(s)直接输出最佳的a是多少。具体而言,面对离散动作的情况,P(s)输出采用各个a的概率;面对连续动作的情景,P(s)直接输出最佳的a是什么,这就像是神经网络面对分类问题与回归问题的区别。与基于Q的学习不同,没有一个“客观”的东西给我们去学。我们希望通过训练让这个agent能够获得更多的Q(期望意义下)。我们本节介绍的是离散动作的情况。

Policy Gradient

我们需要建立一个Policy net,对于每一个s判断应该采取哪个a。具体对于离散a情形而言,它会输出应该采取各个a对应的概率P(s,a),这和分类问题是一致的。 在Q(s,a)的算法里,我们有价值函数Q,所以(s,a)的价值就包含在r+γQ(s_)之中。而由于我们现在没有这个Q net,可判断(s,a)好不好又是必须的。所以,我们要用Monte Carlo的方法,利用许多回合的s1,a1,r1,s2,a2,r2,s3,a3,r3,…估计出(s,a)的价值vt,然后利用(s,a,vt)形式的数据集训练。具体而言,有不同的方法计算vt。比如,估算在s采取a之后,后面的回合中拿到的总的Q有多少,然后再对其进行一个中心化,使其均值为0。这里得到的vt可以视作是Q(s,a)的估算。

对于(s,a,vt)形式的数据集,总体而言如果vt大的话我们就要增大P(s,a),vt小就要减小P(s,a)。具体而言,对于一个policy函数p,我们需要估计出一个这种policy能够取得Q的期望,然后最大化这个期望。这被称之为surrogate object。在PG最常用的surrogate object是ΣlogP(s,a)vt(有些情况下人们也会使用ΣP(s,a)vt)。我们可以求这个surrogate object对于各个参数的梯度,然后利用梯度上升来更新参数。关于Policy Gradient的算法,我们给出参考链接,感兴趣的读同学可以详细研究。

对于P(s,a),我们可以选择采取随机策略或是确定策略。随机策略即每次根据给出的P(s,a)概率随机地选择a,而确定策略则选出让P(s,a)最大的那个a。这两种方法可以结合在一起,一般而言,训练的过程最好偏向于随机性强一些,而使用的时候则最好让确定性强一些。

Actor-Critc

Actor-Critic算法是一个将基于Q与基于Policy相结合的算法。Actor是一个基于P的gradient policy网络,Critic是一个基于Q的DQN。在建模结束后,我们就利用建模出来的Actor给出的P(s,a)来决定agent的行动。而Critic只是用来辅佐Actor训练的。

上一节说过,Actor(policy网络)需要用形如(s,a,vt)的数据来训练,即需要一个vt来代表(s,a)的价值。但是这个vt要用Monte Carlo算出来,这就导致网络不是单步更新的,不太方便。由于(s,a)造成的所有后果包含在(r,s)之中,所以我们希望有一个Critic可以根据(r,s)算出一个类似于vt的价值TD-error。这里这个TD-error代表前一步和后一步的价值差,也就是采取a所带来的价值。再把这个(s,a,TD-error)给Actor,这样Actor就能够按照policy gradient的方式训练学习。与普通的PG相比,我们还可以把数据斩断为一条条(s,a,r,s_)的形式,这样就会更加方便。

由于我们这个agent最后是按照Actor的P(s,a)来选择,所以Critic不必学出Q(s,a),它只用学出Q(s)就够了。假设我们的Critc已经学出了Q(s),则它面对(s,a,r,s)数据集的时候,就可以根据(r + γQ(s)) – Q(s)来判断agent做这个(s,a)到底带来了多大的价值,这个值就是用来替代vt的TD-error。所以当我们有这样的Critc了之后,就能把(s,a,r,s_)变成(s,a,TD-error)给Actor学习。

而Critc本身也是要学习的。它学习的办法就是要极小化这个TD-error。对于如何极小化(r + γQ(s_)) – Q(s),将其square error当成loss来优化即可,这一点在前面已经说过了。对Actor-Critic的算法感兴趣的同学可以参考:https://medium.com/@changrongko/deep-reinforcement-learning-pg-13-5-e3065d5b1dc7。

局部收敛

之前说过了,只要有Q网络在的地方,就会有局部收敛。我们来看看Actor-Critic什么时候达到收敛。

Critc收敛的充要条件是所有TD-error=0了,也就是说每一个给过来的(s,a,r,s)对应的TD-error=(r + γQ(s)) – Q(s)=0。这时候Critc就不再更新。而当所有TD-error=0了,那Actor也不会再更新了。它的所有P(s,a)都是固定的。

我们可以想象这时候的Actor也陷入了一种“套路”,它在这个“套路”下按照一定的概率产生出(s,a,r,s_)的数据集。而Critc给出的Q(s)同样也是在这个套路下,在s状态之后能获得多少Q的期望。然而当收敛到的这个“套路”不是真正的最佳策略时,就算是一种局部收敛。网络无法再进行进一步的更新了。

要注意的是,但凡DQN都有可能产生这种“局部收敛”的情况,即收敛了,但是收敛到不是最佳的情况。而单纯的policy gradient则不会产生局部收敛,因为它一直在追求最大化Σ log P(s,a) vt。在Actor-Critic算法中由于是DQN引导着policy net训练,所以DQN收敛了policy net也没法再训练下去了,本质上是由于DQN的局部收敛导致的AC的局部收敛。

A3C

A3C意思就是Asynchronous Advantage Actor-Critic (A3C),它采用一种异步的方法。对于一个Actor-Critic的系统,它有一个global的数据,还有多个worker,在多个核上并行地运行。它们不断从global数据中获取参数的最新版本。然后在自己的环境中玩耍,再将自己学习到的参数的梯度上传到global中,去更新全局的参数。这就是所谓的Asynchronous异步。

为了防止“局部收敛”,DQN采取了off-policy的手段,即降低训练集(s,a,r,s_)的前后关联性,同时避免训练集与policy分布高度重合。这样就避免了训练集中过早出现过多同一个“套路”的信息,降低局部收敛的风险。

而上述的Asynchronous的做法,由于训练集是由不同worker在独立的游戏过程中产生的,也不具有强烈的前后关联性。所以,A3C用了这个做法后就可以在on-policy的情况下避免局部收敛,同时提高训练效率、节省存储空间。

再给个通俗的比喻:我们脑子只有七秒的记忆,记不住小时候发生的事情(不搞experience replay),当我们去从事一个追求金钱的工作时,由于也只记得追求金钱的action,和有钱就很爽的state,记不住小时候别的美好的事情,所以很容易局部收敛。但是,我们忽然获得了一个分身术,也就是可以同时分成多个人去体验不同的生活。于是我高喊一声分身术,一个我去当唯利是图的商人,一个我去当救死扶伤的医生,一个我去当挖煤矿的工人……我靠着三个我的经验不断地学习,后来我发现是商人的唯利是图导致对煤矿工人的安全保护偷工减料,结果爆发了矿难。商人赚的一些钱,reward=1,可是工人被炸得残疾了,reward=-10,然后医生救死扶伤,感受到救人一命的幸福,reward=5,后来我的思想就转变了,我不再那么喜欢赚钱了,我开始热爱帮助他人。我又重新进行分身,变成了慈善机构的义工、环保爱好者、乡村教师,但是我逐渐发现这些都解决不了问题。最后,我选择了要为人类的解放事业、为社会主义事业奋斗……虽然我只有七秒的记忆,但由于我会分身术,我还是避免了“局部收敛”,找到了最伟大的policy。

此外,A3C采用的是advantage而不是Q的,即其衡量的是每个action对于state的附加价值,这一点有利于其加速训练。

至此,我们就大致地介绍完了离散动作的主要模型及其训练方法。其中,DQN与A3C是最常用的两种方法。下面,我们开始介绍连续动作的的强化学习问题。我们主要介绍两种方法——随机策略梯度法(SPG)与经典的深度确定策略梯度法(DDPG)。目前。DDPG是连续动作问题中被使用最多的模型。

SPG

SPG即stochastic policy gradient。它与DPG,即deterministic policy gradient有所不同。对于一个s,DPG直接输出一个确定的a=P(s)。而SPG则输出一个μ与Σ,以这个μ与Σ为均值与方差得到一个高斯分布,从这个高斯分布中产生一个a。从这个角度看,DPG更加简单、直接,而SPG则更加复杂、繁琐。

如果我们只是单单训练一个policy网络,而没有Q网络,则与上一节提到的离散动作的随机梯度法一样,我们也必须要采用Monte Carlo算出每个(s,a)的价值vt,然后才能利用这种形如(s,a,vt)的数据集进行训练。

但是,如果我们只有一个DPG,这是无法训练的。假设我们用Monte Carlo的算法得到了(s,a)的优势vt,继而得到了许多条(s,a,vt)的数据(其中P(s)=a)。根据这些vt,我们可以判断在s处采取a到底好不好。但是,我们无法知道对于一个s,我们应该将a=P(s)向哪个方向进行更新,才能有效提升我们的surrogate object。

在SPG中,我们只是根据s输出μ,μ与a还是不一样的,a只是根据以μ为均值的正态产生的。设我们拥有许多条(s,a,vt)的数据(其中P(s)=μ),则我们可以根据vt是否大于0,来控制对于s输出的μ是要接近a还是远离a,以及根据vt的大小来判断对于s输出的Σ增加或减少的幅度。一般来说,假设对于s输出的均值与方差分别是μ与Σ,我们从中生成的动作为a。则当vt大于0时候,就意味着a比较好,我们应该将μ修改得离a更近,且这种修改幅度与vt成正比;而Σ的更新则较为复杂。我们可以想象,当a比μ偏离得比较远,却又取得了比较好的成绩时候,说明Σ不宜太小,否则就会丧失找出这么好的a的机会;而另一方面,如果a离μ比较近,r又比较好的时候,就说明Σ应该要小一些,以保证可以稳定地获得较好的结果。

具体的算法如下图给出(其中的r−r¯指代的就是vt,即具有零均值性质的,能够反映s处采用a的价值的东西)

事实上,我们对于SPG也可以采用Actor-Critic算法,即额外训练一个Q网络,来给出vt的判断,则我们就可以不必使用Monte Carlo方法。有关这方面的内容与离散动作的差不多,但也有一定的差别。这里就不赘述了,在论文中都有给出。

DDPG

DDPG就是deep deterministic policy gradient。如同监督学习中分类问题总是有各个类别置信度的概念在里面,所以总是具有随机性,而回归问题我们完全可以直接给出a的预测。所以,a离散的时候没办法建立DPG,而a连续的时候我们完全就可以建立DPG。DPG比起SPG显得要更加地简单、直接。

然而,DDPG的结构十分复杂。它需要构造四个网络——基于Q的网络的eval net、target net,还有基于Policy网络的eval net与target net,也就是说,一共要用到四个网络。其简单的示意图如下:

但事实上,也只能这么构造,四个网络都是必不可少的。否则,训练将无法进行。其具体原因如下:

第一,为什么要同时训练基于Q的网络与基于Policy的网络。前面已经说过了,光训练基于Q的网络,训练好了也无法选出a,光训练基于Policy的deterministic网络无法训练,所以必须要二者结合。

第二,为什么基于Q的方法要训练Q(s,a),而不能只训练一个Q(s)?在上面a离散情形使用AC算法时,我们只用训练一个Q(s)就可以了,因为你算出TD-error=r+γQ(s)-Q(s_)就可以知道(s,a)好不好,P(s,a)应该加大还是减小。但对于a连续的情形,你训练P(s)的时候要告诉P(s)求出的a应该往哪个方向变化。所以你必须有一个Q(s,a),你才知道对于P(s)=a,a应该往哪个方向变才能让Q(s,a)增大(即Q(s,a)对于a的梯度),然后才能利用这个梯度来训练P(s)。第三,为什么Q要搞两个eval net与target net。这个原因在DQN中已经说明了。

第四,为什么P要搞两个eval net与target net?要注意的是,Q的更新方式是让Q(s,a)更加接近r+γQ(s)。在a离散的时候,我们用max Q(s,argmaxQ(s,a))来代表Q(s)。而当a连续的时候却没有这个argmaxQ(s,a)。我们只能对s找出那个能使得Q(s,a)极大化的a,才能用Q(s,a)来代表Q(s)。所以我们实际上训练过程是让Q(s,a)更加接近r+γQ(s,a)。为此,我们希望能用一个网络来对s来选择a。这也可以通过policy net的eval net做到。但是,我们希望r+γQ(s)这个部分更加类似于label,不经常随着训练过程而激烈变化,所以我们专门设计一个policy net的滞后版本target net来帮助实现这一点。

至此,DDPG的结构也差不多都说明白了。它有四个网络,Peval、Ptarget、Qeval、Qtarget。其中Ptarget与Qtarget分别是Peval与Qeval的一个比较旧的版本。它们能用来前传计算一些值,但是不通过后传算法更新。

具体而言,Qeval网络的更新公式如下:

Qeval(s,a)→r+γQtarget(s,Ptarget(s))

而Peval则是这样更新的:

对于s,它算出来P(s)=a。而Qeval算出来Q(s,a)对于a的梯度△a,即说明在s时候P(s)应该往a+△a的方向走。而P(s)后传△a求出各个参数对于△a的梯度,即policy gradient。这意味着往这个policy gradient的方向修改参数,这可以使得P(s)的输出从a往a+△a方向走,而这也意味着能够获得更大的Q(s,a)。 DDPG的具体算法可以参考论文《Continuous Control with Deep Reinforcement Learning》。

关于DDPG是否会出现局部收敛,即“套路”的问题,由于这个是连续动作,所以“套路”是什么不太容易产生直观的感觉。但是既然存在着DQN,用DQN来引导更新,所以大概还是会局部收敛的吧。所以使用DDPG的时候我们仍需要使用off-policy,即打乱训练集的相关性来进行学习,以降低局部收敛的风险。

soft replace

在DQN中,每过一定的回合,就直接将eval net的所有参数给替换成target net。这种做法被称为hard replace。

而在DDPG的论文中一般采取的是soft replace。即每一个回合都将target net的参数用一个小步长向着eval net的方向更新。如此看来,target net就是eval net的一个比较滞后的版本。

至于为什么要把hard replace改成soft replace,我猜大概还是为了使得训练更加稳定吧。因为我们加入时滞的target net目的本来就是让问题变得更像一个监督学习问题,让label更加稳定。而在hard replace的前后,可能全局所有Q(s_)的label都发生了剧烈的变化,就仿佛整个监督学习的问题都变了。这样又会导致求解的结果不稳定。而soft replace仿佛是在让label缓慢地发生变化,更加的平缓一些。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180616G18Q5T00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券