笔记内容来源于李宏毅老师的深度强化学习的PPT。
关于PPO(Proximal Policy Optimization),李老师分为了三个部分进行了介绍。
与基于价值的强化学习方法不同,Policy Gradient通常会采集多组完整的状态序列用于actor的训练。所谓actor本质上也就是agent,它的功能在于给定一个环境状态,可以输出一个action。
actor在进行训练之前,会先与环境进行交互,然后得到一组训练数据(由多条状态序列构成)。
train data : { τ 1 , τ 2 , . . . , τ N } , τ i = { s 1 , a 1 , . . . , s T , a T } \text{train data}:\{\tau^1,\tau^2,...,\tau^N\}, \; \tau_i=\{s_1,a_1,...,s_T,a_T\} train data:{τ1,τ2,...,τN},τi={s1,a1,...,sT,aT}
对于每条状态序列的奖励表示为该序列得到的所有的奖励之和,如下所示:
R ( τ ) = ∑ t = 1 T r t (1) R(\tau)=\sum_{t=1}^T r_t \tag1 R(τ)=t=1∑Trt(1)
但是Policy Gradient并不是只用一条状态序列来更新策略的,而是会根据所有的采集到的状态序列来计算它的期望奖励。
R ˉ θ = ∑ τ R ( τ ) p θ ( τ ) = E τ ∼ p θ ( τ ) [ R ( τ ) ] (2) \bar{R}_{\theta}=\sum_{\tau}R(\tau)p_{\theta}(\tau)=E_{\tau\sim p_{\theta}(\tau)}[R(\tau)] \tag2 Rˉθ=τ∑R(τ)pθ(τ)=Eτ∼pθ(τ)[R(τ)](2)
上式可以理解为:在使用参数为 θ \theta θ的actor与环境进行互动,采集到多条状态序列,其分布可以表示为 τ ∼ p θ ( τ ) \tau\sim p_{\theta}(\tau) τ∼pθ(τ)。对于这些以参数为 θ \theta θ的actor所收集到的状态序列,Policy Gradient会计算它们的期望奖励值,然后以该期望奖励值来更新actor的参数,得到新的参数 θ ′ \theta' θ′。如此往复,就是Policy Gradient的大致流程。 从这里可以看出,Policy Gradient是基于无模型的算法。
那么应该如何更新actor的参数呢?
Policy Gradient的后一个单词就告诉了我们方法,也就是采用梯度进行参数更新。即计算式(2)的梯度,然后朝着奖励值增加的方向更新参数。
对式(2)计算其梯度,我们可以得到:
∇ R ˉ θ = ∑ τ R ( τ ) ∇ p θ ( τ ) = ∑ τ R ( τ ) p θ ( τ ) ∇ p θ ( τ ) p θ ( τ ) (3) \nabla \bar{R}_{\theta}=\sum_{\tau}R(\tau)\nabla p_{\theta}(\tau)=\sum_{\tau}R(\tau)p_{\theta}(\tau) \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} \tag3 ∇Rˉθ=τ∑R(τ)∇pθ(τ)=τ∑R(τ)pθ(τ)pθ(τ)∇pθ(τ)(3)
根据导数公式 ∇ f ( x ) = f ( x ) ∇ log f ( x ) \nabla f(x)=f(x) \nabla \log f(x) ∇f(x)=f(x)∇logf(x),上式可以转化为:
∇ R ˉ θ = ∑ τ R ( τ ) p θ ( τ ) ∇ log p θ ( τ ) = E τ ∼ p θ ( τ ) [ R τ ∇ log p θ ( τ ) ] ( 4 ) ≈ 1 N ∑ n = 1 N R ( τ n ) ∇ log p θ ( τ n ) ( 5 ) = 1 N ∑ n = 1 N ∑ t = 1 T n R ( τ n ) ∇ log p θ ( a t n ∣ s t n ) ( 6 ) \begin{aligned} \nabla \bar{R}_{\theta} &= \sum_{\tau}R(\tau)p_{\theta}(\tau) \nabla \log p_{\theta}(\tau) \\ &= E_{\tau \sim p_{\theta}(\tau)}[R_{\tau} \nabla \log p_{\theta}(\tau)] \ \quad \qquad \qquad \; (4)\\ & \approx \frac{1}{N}\sum_{n=1}^N R(\tau^n) \nabla \log p_{\theta}(\tau^n) \qquad \qquad \quad (5)\\ &= \frac{1}{N}\sum_{n=1}^N \sum_{t=1}^{T_n} R(\tau^n) \nabla \log p_{\theta}(a_t^n|s_t^n) \quad \quad (6)\\ \end{aligned} ∇Rˉθ=τ∑R(τ)pθ(τ)∇logpθ(τ)=Eτ∼pθ(τ)[Rτ∇logpθ(τ)] (4)≈N1n=1∑NR(τn)∇logpθ(τn)(5)=N1n=1∑Nt=1∑TnR(τn)∇logpθ(atn∣stn)(6)
因为我们并不知道 τ ∼ p θ ( τ ) \tau\sim p_{\theta}(\tau) τ∼pθ(τ)的真实分布,因此只能通过采样的方式计算式(4)的数学期望,也就是式(5)的形式。
上图就是Policy Gradient的大致流程,也就是数据收集和模型更新的循环。这里需要注意的是,Policy Gradient每次收集到的数据只会对模型进行一次更新,并不会反复使用这些数据。 从这就可以看出,Policy Gradient是一种"On-policy"的算法。
那么应该如何在实际应用中使用式(6)来更新模型呢?
待续…
下图说明了两种方式的区别。简单来说,"on-policy"就是指我们自己训练,然后自己学习。而"off-policy"就是指我们可以旁观别人的训练,从而得到学习。
为什么我们要把on-policy方法转变为off-policy方法呢?
上一节我们提到Policy Gradient的训练方法,但是它的训练方法非常浪费时间。因为它获得的每一组训练资料都只能更新一次模型的参数,更新完之后又要重新收集训练资料。如果训练资料可以更新多次模型的参数,那么训练效率就会得到很大的提高。
在使用on-policy方法时,由于我们是使用参数为 θ \theta θ的actor收集训练数据的,一旦参数 θ \theta θ得到更新后,我们就必须重新收集数据,因为此时参数 θ \theta θ已经变化的。
为了可以使得训练资料可以反复使用,我们就必须固定actor的参数值。一个方法就是使用两个actor,一个参数为 θ ′ \theta' θ′的actor用于收集训练资料,另一个参数为 θ \theta θ的actor用于训练。因为前者不参与训练,故它的参数也不会发生变化,如此就可以反复使用这组训练数据。
但这里需要解决一个问题,即两个不同参数的actor得到的训练数据的分布是不同的,如何将它们联系起来呢?从公式角度出发,假设前者actor采集的训练资料的分布为 q q q,后者的分布为 p p p,我们应该如何实现这两者之间的转化呢?
∇ R ˉ θ = E τ ∼ p → E τ ∼ q \nabla \bar{R}_{\theta}=E_{\tau \sim p} \rightarrow E_{\tau \sim q} ∇Rˉθ=Eτ∼p→Eτ∼q
这里就需要提到一种称为Importance Sampling的技术。
E x ∼ p [ f ( x ) ] = ∫ f ( x ) p ( x ) d x = ∫ f ( x ) p ( x ) q ( x ) q ( x ) d x = E x ∼ q [ f ( x ) p ( x ) q ( x ) ] (7) \begin{aligned} E_{x \sim p}[f(x)] &= \int f(x)p(x)dx \\ &= \int f(x) \frac{p(x)}{q(x)}q(x)dx \\ &= E_{x \sim q}[f(x)\frac{p(x)}{q(x)}] \tag7 \end{aligned} Ex∼p[f(x)]=∫f(x)p(x)dx=∫f(x)q(x)p(x)q(x)dx=Ex∼q[f(x)q(x)p(x)](7)
但是上述方法的应用需要满足一个条件:两类分布 ( p , q ) (p,q) (p,q)不能差异太大。
原因在于,虽然通过式(7)使得两者的数学期望相同,但是两者的方差并不是相同的,如下图所示。
当 p ( x ) , q ( x ) p(x),q(x) p(x),q(x)相差很大时,根据采样情况存在两种可能:
举一个极端的例子,如下图所示。当两者分布相差较大时,如果我们采样的次数不多,比如采样得到的样本全部都在 q ( x ) q(x) q(x)右侧区域上(下图右侧的绿点),那么最终计算得到的 E x ∼ q E_{x\sim q} Ex∼q就是一个正值。但是 E x ∼ p E_{x\sim p} Ex∼p却是一个负值,此时就会导致两者的期望不相同。但是如果再多采样几个点,也许就会得到位于左侧区域的样本,由于权重大的原因( p ( x ) / q ( x ) p(x)/q(x) p(x)/q(x)比较大),就会把 E x ∼ q E_{x\sim q} Ex∼q拉到负值。
简单来说,PPO就是Policy Gradient的"off-policy"版本。为了满足Importance Sampling的使用条件,PPO在目标函数中加入了一个约束项。
J θ k = ∑ ( s t , a t ) p θ ( a t ∣ s t ) p θ k ( a t ∣ s t ) A θ k ( s t , a t ) ( 8 ) J P P O θ k = J θ k − β K L ( θ , θ k ) ( 9 ) J T R P O θ k = J θ k , K L ( θ , θ k ) < δ ( 10 ) \begin{aligned} J^{\theta^k}&=\sum_{(s_t,a_t)} \frac{p_{\theta}(a_t|s_t)}{p_{\theta^k}(a_t|s_t)}A^{\theta^k}(s_t,a_t) \quad (8)\\ J_{PPO}^{\theta^k}&=J^{\theta^k}-\beta KL(\theta,\theta^k) \quad (9) \\ J_{TRPO}^{\theta^k}&=J^{\theta^k}, \; KL(\theta,\theta^k)<\delta \quad (10) \\ \end{aligned} JθkJPPOθkJTRPOθk=(st,at)∑pθk(at∣st)pθ(at∣st)Aθk(st,at)(8)=Jθk−βKL(θ,θk)(9)=Jθk,KL(θ,θk)<δ(10)
PPO算法与TRPO算法的区别在于前者把约束项放入了目标函数中,而不是作为外部约束。
关于PPO算法,还有一个更加容易实现的形式:
J P P O 2 θ k ≈ ∑ s t , a t min ( p θ ( a t ∣ s t ) p θ k ( a t ∣ s t ) A θ k ( s t , a t ) , c l i p ( p θ ( a t ∣ s t ) p θ k ( a t ∣ s t ) , 1 − ϵ , 1 + ϵ ) A θ k ( s t , a t ) ) (11) J_{PPO2}^{\theta^k} \approx \sum_{s_t,a_t} \min (\frac{p_{\theta}(a_t|s_t)}{p_{\theta^k}(a_t|s_t)}A^{\theta^k}(s_t,a_t), clip(\frac{p_{\theta}(a_t|s_t)}{p_{\theta^k}(a_t|s_t)},1-\epsilon,1+\epsilon)A^{\theta^k}(s_t,a_t)) \tag{11} JPPO2θk≈st,at∑min(pθk(at∣st)pθ(at∣st)Aθk(st,at),clip(pθk(at∣st)pθ(at∣st),1−ϵ,1+ϵ)Aθk(st,at))(11)
注意:以上所有形式的目标函数的参数只有 θ \theta θ, θ k \theta_k θk表示的是旧策略的参数,并不参与参数的更新。
关于式(11),有一个直观的解释: