之前介绍的 Q-learning、DQN 及 DQN 改进算法都是基于价值(value-based)的方法,其中 Q-learning 是处理有限状态的算法,而 DQN 可以用来解决连续状态的问题。在强化学习中,除了基于值函数的方法,还有一支非常经典的方法,那就是基于策略(policy-based)的方法。对比两者,基于值函数的方法主要是学习值函数,然后根据值函数导出一个策略,学习过程中并不存在一个显式的策略;而基于策略的方法则是直接显式地学习一个目标策略。策略梯度是基于策略的方法的基础。
在一场游戏里面,我们把环境输出的s与演员输出的动作a全部组合起来,就是一个轨迹,即
τ={s1,a1,s2,a2,⋯,st,at}
给定演员的参数θ,我们可以计算某个轨迹τ发生的概率为
pθ(τ)=p(s1)pθ(a1∣s1)p(s2∣s1,a1)pθ(a2∣s2)p(s3∣s2,a2)⋯=p(s1)t=1∏Tpθ(at∣st)p(st+1∣st,at)
我们把轨迹所有的奖励r都加起来,就得到了R(τ),其代表某一个轨迹τ的奖励。
在某一场游戏的某一个回合里面,我们会得到R(τ)。我们要做的就是调整演员内部的参数θ,使得R(τ)的值越大越好。但实际上R(τ)并不只是一个标量,它是一个随机变量,因为演员在给定同样的状态下会采取什么样的动作,这是有随机性的。环境在给定同样的观测时要采取什么样的动作,要产生什么样的观测,本身也是有随机性的,所以R(τ)是一个随机变量。我们能够计算的是R(τ)的期望值。给定某一组参数θ,我们可计算rθ的期望值为
Rθˉ=r∑R(τ)pθ(τ)=Eτ∼pθ(τ)[R(τ)]
从分布pθ(τ)采样一个轨迹τ,计算R(τ)的期望值,就是期望奖励。我们要最大化期望奖励。
因为我们要让奖励越大越好,所以可以使用梯度上升来最大化期望奖励。要进行梯度上升,我们先要计算期望奖励Rθˉ的梯度。我们对Rθˉ做梯度运算
∇Rθˉ=τ∑R(τ)∇pθ(τ)
其中,只有pθ(τ)与θ有关。
奖励函数R(τ)不需要是可微分的,这不影响我们解决接下来的问题。例如,如果在生成对抗网络里面,R(τ)是一个判别器,它就算无法微分,我们还是可以做接下来的运算。
∵f(x)∇logf(x)=f(x)⋅f(x)∇f(x)=∇f(x)∴∇pθ(τ)→pθ(τ)∇pθ(τ)=pθ(τ)∇logpθ(τ)=∇logpθ(τ)
我们对τ进行求和,把R(τ)和logpθ(τ)这两项使用pθ(τ)进行加权,既然使用pθ(τ)进行加权 ,它们就可以被写成期望的形式。也就是我们从pθ(τ)这个分布里面采样τ, 去计算R(τ)乘∇logpθ(τ),对所有可能的τ进行求和,就是期望的值。
∇Rθˉ=r∑R(τ)∇pθ(τ)=r∑R(τ)pθ(τ)pθ(τ)∇pθ(τ)=r∑R(τ)pθ(τ)∇logpθ(τ)=Eτ∼pθ(τ)[R(τ)∇logpθ(τ)]
实际上期望值Eτ∼pθ(τ)[R(τ)∇logpθ(τ)]无法计算,所以我们用采样的方式采样N个τ并计算每一个的值,把每一个的值加起来,就可以得到梯度,即
Eτ∼pθ(τ)[R(τ)∇logpθ(τ)]≈N1n=1∑NR(τn)∇logpθ(τn)=N1n=1∑NR(τn)∇(logp(s1)+t=1∑Tnpθ(at∣st)+t=1∑Tnp(st+1∣st,at))=N1n=1∑NR(τn)(∇logp(s1)+∇t=1∑Tnpθ(at∣st)+∇t=1∑Tnp(st+1∣st,at))=N1n=1∑NR(τn)∇t=1∑Tnpθ(at∣st)=N1n=1∑NR(τn)t=1∑Tn∇logpθ(atn∣stn)=N1n=1∑Nt=1∑TnR(τn)∇logpθ(atn∣stn)
我们可以直观地理解该式,也就是在我们采样到的数据里面,采样到在某一个状态st要执行某一个动作at,(st,at)是在整个轨迹τ的里面的某一个状态和动作的对。假设我们在st执行at,最后发现τ的奖励是正的,我们就要增加在st执行at的概率。反之,如果在st执行at会导致τ的奖励变成负的,我们就要减少在st执行at的概率。这怎么实现呢?我们用梯度上升来更新参数,原来有一个参数θ,把θ加上梯度∇Rθˉ,当然我们要有一个学习率η,学习率也是要调整的,可用 Adam、RMSProp 等方法来调整学习率,即
θ←θ+η∇Rθˉ
把每一个s与a的对拿进来,计算在某一个状态下采取某一个动作的对数概率logpθ(atn∣stn)。对这个概率取梯度,在梯度前面乘一个权重,权重就是这场游戏的奖励。我们计算出梯度后,就可以更新模型。
∇Rθˉ=N1n=1∑Nt=1∑TnR(τn)∇logpθ(atn∣stn)

更新完模型以后,我们要重新采样数据再更新模型。注意,一般策略梯度(policy gradient,PG)采样的数据只会用一次。我们采样这些数据,然后用这些数据更新参数,再丢掉这些数据。接着重新采样数据,才能去更新参数。
REINFORCE算法
REINFORCE 用的是回合更新的方式,它在代码上的处理上是先获取每个步骤的奖励,然后计算每个步骤的未来总奖励Gt,将每个Gt代入
∇Rθˉ≈N1n=1∑Nt=1∑TnGt∇logpθ(atn∣stn)
优化每一个动作的输出。所以我们在编写代码时会设计一个函数,这个函数的输入是每个步骤获取的奖励,输出是每一个步骤的未来总奖励。因为未来总奖励可写为
Gt=k=t+1∑Tγk−t−1rk=rt+1+γGt+1
即上一个步骤和下一个步骤的未来总奖励的关系如式所示,所以在代码的计算上,我们是从后往前推,一步一步地往前推,先算GT,然后往前推,一直算到G1。
Q&A
Q:应该如何理解策略梯度的公式?
A:策略梯度的公式如下:
Eτ∼pθ(τ)[R(τ)∇logpθ(τ)]≈N1n=1∑NR(τn)∇logpθ(τn)=N1n=1∑Nt=1∑TnR(τn)∇logpθ(atn∣stn)
pθ(τ)里面有两项,p(st+1∣st,at)来自环境,pθ(at∣st)来自智能体。p(st+1∣st,at)与θ无关,故∇p(st+1∣st,at)=0。
Q:手动推导策略梯度公式的计算过程。
A:首先我们的目的是最大化奖励函数,即调整θ,使得期望回报最大,可以用公式表示如下:
J(θ)=Eτ∼pθ(τ)R(τ)=Eτ∼pθ(τ)[t∑r(st,at)]
可以用梯度上升法求其最大值,即:
θ∗=θ+α∇J(θ)
即计算J(θ)对θ的梯度,即策略梯度。
∇θJ(θ)=∇θ∫pθ(τ)R(τ)dτ=∫∇θpθ(τ)R(τ)dτ=∫pθ(τ)∇θlogpθ(τ)R(τ)dτ=Eτ∼pθ(τ)[∇θlogpθ(τ)R(τ)]
其中,
pθ(τ)=p(s1)pθ(a1∣s1)p(s2∣s1,a1)⋯=p(s1)t=1∏Tpθ(at∣st)p(st+1∣st,at)
取对数后有
logpθ(τ)=logp(s1)+t=1∑Tlogpθ(at∣st)+i=t∑Tp(st+1∣st,at)
其中第一项与第三项与θ无关,导数为0。故
∇θlogpθ(τ)=t=1∑T∇θlogpθ(at∣st)
带入前式可得
∇θJ(θ)=Eτ∼pθ(τ)[∇θlogpθ(τ)R(τ)]=Eτ∼pθ(τ)[t=1∑T∇θlogpθ(at∣st)R(τ)]=Eτ∼pθ(τ)[t=1∑T∇θlogpθ(at∣st)t=1∑Tr(st,at)]
我们通过采样的方式计算该期望,则有
∇θJ(θ)=N1i=1∑N[t=1∑T∇θlogpθ(ai,t∣si,t)(t=1∑Tr(si,t,ai,t))]
Q:基于策略梯度优化的技巧有哪些?
A:
- 增加基线:为了防止所有奖励都为正,从而导致每一个状态和动作的变换,都会使得每一个变换的概率上升,我们把奖励减去一项b,称b为基线。当减去b以后,就可以让奖励R(τn)−b有正有负。如果得到的总奖励R(τn)大于b,就让它的概率上升。如果总奖励小于b,就算它是正的,值很小也是不好的,就需要让它的概率下降。如果总奖励小于b,就要让采取这个动作的奖励下降,这样也符合常理。但是使用基线会让本来奖励很大的“动作”的奖励变小,降低更新速率。
- 指派合适的分数:首先,原始权重是整个回合的总奖励。现在改成从某个时间点t开始,假设这个动作是在时间点t被执行的,那么从时间点t,一直到游戏结束所有奖励的总和,才真的代表这个动作是好的还是不好的;接下来我们再进一步,把未来的奖励打一个折扣,这里我们称由此得到的奖励的和为折扣回报。
- 综合以上两种技巧,我们将其统称为优势函数,用A来代表优势函数。优势函数取决于状态和动作,即我们需计算的是在某一个状态s采取某一个动作a的时候,优势函数有多大。