PPO: Proximal Policy Optimization Algorithms John Schulman, Filip Wolski, Prafulla Dhariwal, Alec Radford, Oleg Klimov — arXiv 2017
PPO(Proximal Policy Optimization)经常被一句话概括成:给 Policy Gradient 加了 clipping 的稳定版强化学习算法 。
这句话没有错,但太短了。真正理解 PPO,需要沿着一条更完整的线索走:
Policy Gradient
→ 回报折扣与 baseline
→ advantage 估计
→ on-policy 数据利用率低
→ importance ratio 尝试复用旧数据
→ policy 更新过大导致崩溃
→ TRPO 用 KL 约束更新幅度
→ PPO 用 clipping 做一阶近似
这篇文章就按这条路径展开。最后你应该能回答四个问题:
Policy Gradient 到底在优化什么?
为什么 baseline、折扣因子和 advantage 是必须理解的基础?
PPO 为什么不是严格的 off-policy,却又能比 Vanilla Policy Gradient 更有效地复用数据?
clipped objective 为什么能限制 policy 更新幅度?
可信度说明:本文关于 PPO / TRPO / GAE 目标函数与算法流程的表述主要来自原论文与 OpenAI Spinning Up 教程,结论可信度为 High 。实现细节如 advantage normalization、value clipping、entropy bonus 在不同代码库中会有差异,本文只讨论最常见版本。[Schulman et al., 2017, arXiv:1707.06347] [Schulman et al., 2015, arXiv:1502.05477] [Schulman et al., 2015, arXiv:1506.02438] [OpenAI, Spinning Up PPO]
1. PPO 解决的核心问题
强化学习里,agent 不是从静态数据集里学习“标准答案”,而是通过和环境交互得到奖励。
一个典型交互过程如下:
Policy πθ(a | s) Environment P(s', r | s, a) Trajectory τ = s, a, r... action next state + reward use sampled trajectories to update θ
PPO 的目标不是“让每一步都拿到最高即时奖励”,而是最大化长期期望回报:
J ( θ ) = E τ ∼ π θ [ ∑ t = 0 T γ t r t ] J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta}\left[\sum_{t=0}^{T} \gamma^t r_t\right] J ( θ ) = E τ ∼ π θ [ t = 0 ∑ T γ t r t ]
这里:
π θ ( a ∣ s ) \pi_\theta(a \mid s) π θ ( a ∣ s ) 是参数为 θ \theta θ 的策略;
τ \tau τ 是按照当前 policy 采样得到的轨迹;
r t r_t r t 是第 t t t 步奖励;
γ ∈ [ 0 , 1 ] \gamma \in [0, 1] γ ∈ [ 0 , 1 ] 是折扣因子。
PPO 要解决的问题是:怎样让 policy 朝着更高回报方向更新,同时不要一步走太远,把已经学到的行为破坏掉 。
2. Policy Gradient:直接优化策略
在监督学习里,我们通常有固定标签,可以直接最小化交叉熵。但强化学习没有“每个 state 下唯一正确 action”。一个 action 好不好,往往要看后面很多步的累计奖励。
Policy Gradient 的基本想法是:
如果某个 action 最终带来了高回报,就提高它在对应 state 下的概率;
如果某个 action 最终带来了低回报,就降低它的概率。
从轨迹概率推导 REINFORCE
先把一条轨迹写成:
τ = ( s 0 , a 0 , r 0 , s 1 , a 1 , r 1 , ⋯ , s T ) \tau = (s_0, a_0, r_0, s_1, a_1, r_1, \cdots, s_T) τ = ( s 0 , a 0 , r 0 , s 1 , a 1 , r 1 , ⋯ , s T )
在给定 policy π θ \pi_\theta π θ 时,这条轨迹出现的概率是:
p θ ( τ ) = p ( s 0 ) ∏ t = 0 T − 1 π θ ( a t ∣ s t ) P ( s t + 1 ∣ s t , a t ) p_\theta(\tau)
= p(s_0)\prod_{t=0}^{T-1}\pi_\theta(a_t \mid s_t)P(s_{t+1} \mid s_t, a_t) p θ ( τ ) = p ( s 0 ) t = 0 ∏ T − 1 π θ ( a t ∣ s t ) P ( s t + 1 ∣ s t , a t )
目标函数可以写成对轨迹回报的期望:
J ( θ ) = E τ ∼ p θ ( τ ) [ R ( τ ) ] = ∫ p θ ( τ ) R ( τ ) d τ J(\theta)
= \mathbb{E}_{\tau \sim p_\theta(\tau)}[R(\tau)]
= \int p_\theta(\tau)R(\tau)d\tau J ( θ ) = E τ ∼ p θ ( τ ) [ R ( τ )] = ∫ p θ ( τ ) R ( τ ) d τ
其中完整轨迹回报为:
R ( τ ) = ∑ t = 0 T γ t r t R(\tau) = \sum_{t=0}^{T}\gamma^t r_t R ( τ ) = t = 0 ∑ T γ t r t
现在对 θ \theta θ 求梯度:
∇ θ J ( θ ) = ∇ θ ∫ p θ ( τ ) R ( τ ) d τ = ∫ ∇ θ p θ ( τ ) R ( τ ) d τ \nabla_\theta J(\theta)
= \nabla_\theta \int p_\theta(\tau)R(\tau)d\tau
= \int \nabla_\theta p_\theta(\tau)R(\tau)d\tau ∇ θ J ( θ ) = ∇ θ ∫ p θ ( τ ) R ( τ ) d τ = ∫ ∇ θ p θ ( τ ) R ( τ ) d τ
使用 log-derivative trick:
∇ θ p θ ( τ ) = p θ ( τ ) ∇ θ log p θ ( τ ) \nabla_\theta p_\theta(\tau)
= p_\theta(\tau)\nabla_\theta \log p_\theta(\tau) ∇ θ p θ ( τ ) = p θ ( τ ) ∇ θ log p θ ( τ )
于是得到:
∇ θ J ( θ ) = ∫ p θ ( τ ) ∇ θ log p θ ( τ ) R ( τ ) d τ = E τ ∼ π θ [ ∇ θ log p θ ( τ ) R ( τ ) ] \nabla_\theta J(\theta)
= \int p_\theta(\tau)\nabla_\theta \log p_\theta(\tau)R(\tau)d\tau
= \mathbb{E}_{\tau \sim \pi_\theta}\left[
\nabla_\theta \log p_\theta(\tau)R(\tau)
\right] ∇ θ J ( θ ) = ∫ p θ ( τ ) ∇ θ log p θ ( τ ) R ( τ ) d τ = E τ ∼ π θ [ ∇ θ log p θ ( τ ) R ( τ ) ]
接着展开轨迹 log probability:
log p θ ( τ ) = log p ( s 0 ) + ∑ t = 0 T − 1 log π θ ( a t ∣ s t ) + ∑ t = 0 T − 1 log P ( s t + 1 ∣ s t , a t ) \log p_\theta(\tau)
= \log p(s_0)
+ \sum_{t=0}^{T-1}\log \pi_\theta(a_t \mid s_t)
+ \sum_{t=0}^{T-1}\log P(s_{t+1} \mid s_t, a_t) log p θ ( τ ) = log p ( s 0 ) + t = 0 ∑ T − 1 log π θ ( a t ∣ s t ) + t = 0 ∑ T − 1 log P ( s t + 1 ∣ s t , a t )
环境转移 P ( s t + 1 ∣ s t , a t ) P(s_{t+1} \mid s_t, a_t) P ( s t + 1 ∣ s t , a t ) 和初始状态分布 p ( s 0 ) p(s_0) p ( s 0 ) 不由 policy 参数 θ \theta θ 控制,所以它们的梯度为 0:
∇ θ log p θ ( τ ) = ∑ t = 0 T − 1 ∇ θ log π θ ( a t ∣ s t ) \nabla_\theta \log p_\theta(\tau)
= \sum_{t=0}^{T-1}\nabla_\theta \log \pi_\theta(a_t \mid s_t) ∇ θ log p θ ( τ ) = t = 0 ∑ T − 1 ∇ θ log π θ ( a t ∣ s t )
代回去得到最基础的 REINFORCE 形式:
∇ θ J ( θ ) = E τ ∼ π θ [ ∑ t = 0 T − 1 ∇ θ log π θ ( a t ∣ s t ) R ( τ ) ] \nabla_\theta J(\theta)
= \mathbb{E}_{\tau \sim \pi_\theta}\left[
\sum_{t=0}^{T-1}\nabla_\theta \log \pi_\theta(a_t \mid s_t)R(\tau)
\right] ∇ θ J ( θ ) = E τ ∼ π θ [ t = 0 ∑ T − 1 ∇ θ log π θ ( a t ∣ s t ) R ( τ ) ]
从完整回报到 reward-to-go
上面的式子用的是完整轨迹回报 R ( τ ) R(\tau) R ( τ ) 。但第 t t t 步动作 a t a_t a t 不可能影响它之前已经发生的奖励 r 0 , ⋯ , r t − 1 r_0, \cdots, r_{t-1} r 0 , ⋯ , r t − 1 。因此可以把完整回报替换为从第 t t t 步开始的 reward-to-go:
G t = ∑ k = t T γ k − t r k G_t = \sum_{k=t}^{T}\gamma^{k-t}r_k G t = k = t ∑ T γ k − t r k
直观上,这是一个“因果性修正”:
用 a_t 之后的结果评价 a_t,
不要用 a_t 之前已经发生的奖励评价 a_t。
于是最经典的 REINFORCE 梯度可以写成:
∇ θ J ( θ ) = E τ ∼ π θ [ ∑ t ∇ θ log π θ ( a t ∣ s t ) G t ] \nabla_\theta J(\theta)
= \mathbb{E}_{\tau \sim \pi_\theta}\left[
\sum_t \nabla_\theta \log \pi_\theta(a_t \mid s_t)G_t
\right] ∇ θ J ( θ ) = E τ ∼ π θ [ t ∑ ∇ θ log π θ ( a t ∣ s t ) G t ]
这就是你经常看到的 Policy Gradient 形式。
这条公式的直觉很直接:
项 含义 作用 log π θ ( a t ∣ s t ) \log \pi_\theta(a_t \mid s_t) log π θ ( a t ∣ s t ) 当前策略选择动作的 log probability 告诉模型要调哪个动作的概率 ∇ θ log π θ ( a t ∣ s t ) \nabla_\theta \log \pi_\theta(a_t \mid s_t) ∇ θ log π θ ( a t ∣ s t ) 让该动作概率升高或降低的方向 提供可优化梯度 G t G_t G t 这个动作之后带来的长期回报 决定更新强度和方向
如果 G t G_t G t 很大,就沿着提高 a t a_t a t 概率的方向更新;如果 G t G_t G t 很小甚至为负,就降低这个 action 的概率。
state s observe environment sample action a from πθ(a | s) collect return G = discounted sum update θ scale by G high return increase log probability of sampled action low return decrease log probability of sampled action
但 Vanilla Policy Gradient 有两个明显问题:
方差很大 :同一个策略采样出的轨迹可能差异很大,梯度噪声高。
数据利用率低 :数据由当前 policy 采样,policy 一更新,旧数据就变得“不那么当前”。
PPO 后面的设计,本质上就是围绕这两个问题展开。
3. 折扣因子:为什么未来奖励要打折
折扣因子 γ \gamma γ 控制 agent 在多大程度上关心未来。
G t = r t + γ r t + 1 + γ 2 r t + 2 + ⋯ G_t = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \cdots G t = r t + γ r t + 1 + γ 2 r t + 2 + ⋯
直观上:
γ \gamma γ 行为倾向 适用直觉 接近 0 更看重即时奖励 短期反馈足够可靠 接近 1 更看重长期收益 长期规划重要
如果 γ = 0 \gamma = 0 γ = 0 ,agent 只关心当前一步奖励;如果 γ \gamma γ 接近 1,远期奖励也会被认真考虑。
future timestep reward weight smaller γ: fast decay larger γ: slow decay
折扣因子有两个作用:
定义任务偏好 :到底是短期收益重要,还是长期收益重要。
降低估计难度 :远期奖励不确定性更高,折扣可以减少远期噪声对当前更新的影响。
但只加折扣还不够。因为即使使用折扣回报,Policy Gradient 的估计方差仍然很大。
4. Baseline:不改变期望,只降低方差
Policy Gradient 可以减去一个只依赖 state、不依赖 action 的 baseline:
∇ θ J ( θ ) = E [ ∇ θ log π θ ( a t ∣ s t ) ( G t − b ( s t ) ) ] \nabla_\theta J(\theta)
= \mathbb{E}\left[
\nabla_\theta \log \pi_\theta(a_t \mid s_t)(G_t - b(s_t))
\right] ∇ θ J ( θ ) = E [ ∇ θ log π θ ( a t ∣ s t ) ( G t − b ( s t )) ]
最常用的 baseline 是状态价值函数:
V π ( s t ) = E a t , s t + 1 , ⋯ ∼ π [ G t ∣ s t ] V^\pi(s_t) = \mathbb{E}_{a_t, s_{t+1}, \cdots \sim \pi}\left[G_t \mid s_t\right] V π ( s t ) = E a t , s t + 1 , ⋯ ∼ π [ G t ∣ s t ]
于是我们得到 advantage:
A t = G t − V π ( s t ) A_t = G_t - V^\pi(s_t) A t = G t − V π ( s t )
它回答的问题不是“这个 action 的回报有多高”,而是:
这个 action 比当前 state 下的平均水平好多少?
这是一个非常关键的转换。
使用信号 问的问题 问题 return G t G_t G t 这个轨迹回报高不高? 不同 state 的天然难度不同,噪声大 advantage A t A_t A t 这个 action 是否比预期更好? 更适合判断该不该提高动作概率
Raw return Gₜ = 18 looks good, but compared to what? Baseline V(sₜ) = 15 expected return at this state Advantage Aₜ = 3 better than expected − = Baseline does not change the expected policy gradient; it mainly reduces variance.
Baseline 为什么不改变梯度期望
baseline 的关键条件是:b ( s t ) b(s_t) b ( s t ) 只能依赖 state,不能依赖 action。
对固定的 state s s s ,baseline 对 policy gradient 的贡献是:
E a ∼ π θ ( ⋅ ∣ s ) [ ∇ θ log π θ ( a ∣ s ) b ( s ) ] \mathbb{E}_{a \sim \pi_\theta(\cdot \mid s)}\left[
\nabla_\theta \log \pi_\theta(a \mid s)b(s)
\right] E a ∼ π θ ( ⋅ ∣ s ) [ ∇ θ log π θ ( a ∣ s ) b ( s ) ]
因为 b ( s ) b(s) b ( s ) 与 action 无关,可以提出期望外:
= b ( s ) ∑ a π θ ( a ∣ s ) ∇ θ log π θ ( a ∣ s ) = b(s)\sum_a \pi_\theta(a \mid s)\nabla_\theta \log \pi_\theta(a \mid s) = b ( s ) a ∑ π θ ( a ∣ s ) ∇ θ log π θ ( a ∣ s )
利用 ∇ θ log π θ ( a ∣ s ) = ∇ θ π θ ( a ∣ s ) π θ ( a ∣ s ) \nabla_\theta \log \pi_\theta(a \mid s)=\frac{\nabla_\theta \pi_\theta(a \mid s)}{\pi_\theta(a \mid s)} ∇ θ log π θ ( a ∣ s ) = π θ ( a ∣ s ) ∇ θ π θ ( a ∣ s ) :
= b ( s ) ∑ a ∇ θ π θ ( a ∣ s ) = b ( s ) ∇ θ ∑ a π θ ( a ∣ s ) = b(s)\sum_a \nabla_\theta \pi_\theta(a \mid s)
= b(s)\nabla_\theta \sum_a \pi_\theta(a \mid s) = b ( s ) a ∑ ∇ θ π θ ( a ∣ s ) = b ( s ) ∇ θ a ∑ π θ ( a ∣ s )
而所有 action 的概率和恒等于 1:
∑ a π θ ( a ∣ s ) = 1 \sum_a \pi_\theta(a \mid s) = 1 a ∑ π θ ( a ∣ s ) = 1
所以:
b ( s ) ∇ θ ∑ a π θ ( a ∣ s ) = b ( s ) ∇ θ 1 = 0 b(s)\nabla_\theta \sum_a \pi_\theta(a \mid s)
= b(s)\nabla_\theta 1
= 0 b ( s ) ∇ θ a ∑ π θ ( a ∣ s ) = b ( s ) ∇ θ 1 = 0
连续动作空间中把求和换成积分,结论相同。因此:
E a ∼ π θ [ ∇ θ log π θ ( a ∣ s ) b ( s ) ] = 0 \mathbb{E}_{a \sim \pi_\theta}\left[
\nabla_\theta \log \pi_\theta(a \mid s)b(s)
\right] = 0 E a ∼ π θ [ ∇ θ log π θ ( a ∣ s ) b ( s ) ] = 0
这说明 baseline 不改变 policy gradient 的期望,只改变估计方差。它把“绝对回报”改成“相对平均表现”:
∇ θ J ( θ ) = E [ ∇ θ log π θ ( a t ∣ s t ) A t ] \nabla_\theta J(\theta)
= \mathbb{E}\left[
\nabla_\theta \log \pi_\theta(a_t \mid s_t)A_t
\right] ∇ θ J ( θ ) = E [ ∇ θ log π θ ( a t ∣ s t ) A t ]
其中:
A t = G t − V π ( s t ) A_t = G_t - V^\pi(s_t) A t = G t − V π ( s t )
这也是 PPO 通常使用 actor-critic 框架的原因:
actor :策略 π θ ( a ∣ s ) \pi_\theta(a \mid s) π θ ( a ∣ s ) ,决定怎么行动;
critic :价值函数 V ϕ ( s ) V_\phi(s) V ϕ ( s ) ,估计当前 state 的平均未来回报。
5. 从 return 到 GAE:更平滑地估计 advantage
实际训练 PPO 时,很少直接用完整 Monte Carlo return 计算 advantage。更常见的是使用 GAE(Generalized Advantage Estimation)。
从 Bellman 误差到 TD residual
价值函数满足 Bellman 形式:
V π ( s t ) = E a t ∼ π , s t + 1 ∼ P [ r t + γ V π ( s t + 1 ) ] V^\pi(s_t)
= \mathbb{E}_{a_t \sim \pi, s_{t+1} \sim P}\left[
r_t + \gamma V^\pi(s_{t+1})
\right] V π ( s t ) = E a t ∼ π , s t + 1 ∼ P [ r t + γ V π ( s t + 1 ) ]
如果我们用当前 critic V ( s ) V(s) V ( s ) 近似真实的 V π ( s ) V^\pi(s) V π ( s ) ,那么单步估计的“实际结果”是:
r t + γ V ( s t + 1 ) r_t + \gamma V(s_{t+1}) r t + γV ( s t + 1 )
当前 state 的“原本预期”是:
V ( s t ) V(s_t) V ( s t )
两者相减,就得到 TD residual:
δ t = r t + γ V ( s t + 1 ) − V ( s t ) \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) δ t = r t + γV ( s t + 1 ) − V ( s t )
它可以理解成:
这一步的实际奖励 + 下一个状态价值,是否超过了当前状态的价值预期?
如果 δ t > 0 \delta_t > 0 δ t > 0 ,说明这一步比 critic 预期更好;如果 δ t < 0 \delta_t < 0 δ t < 0 ,说明更差。
从多步 advantage 到 GAE
单步 TD residual 方差低,但只看一步,偏差可能较大。Monte Carlo advantage 可以写成:
A ^ t M C = G t − V ( s t ) \hat{A}_t^{MC} = G_t - V(s_t) A ^ t MC = G t − V ( s t )
把 G t G_t G t 展开:
A ^ t M C = r t + γ r t + 1 + γ 2 r t + 2 + ⋯ − V ( s t ) \hat{A}_t^{MC}
= r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \cdots - V(s_t) A ^ t MC = r t + γ r t + 1 + γ 2 r t + 2 + ⋯ − V ( s t )
再把相邻的 value 项加减进去:
A ^ t M C = δ t + γ δ t + 1 + γ 2 δ t + 2 + ⋯ \hat{A}_t^{MC}
= \delta_t + \gamma\delta_{t+1} + \gamma^2\delta_{t+2} + \cdots A ^ t MC = δ t + γ δ t + 1 + γ 2 δ t + 2 + ⋯
也就是说,Monte Carlo advantage 可以看成所有未来 TD residual 的折扣和。
GAE 在这个基础上再加入 λ \lambda λ ,让更远处的 TD residual 衰减得更快:
A ^ t G A E ( γ , λ ) = ∑ l = 0 ∞ ( γ λ ) l δ t + l \hat{A}_t^{GAE(\gamma, \lambda)}
= \sum_{l=0}^{\infty}(\gamma\lambda)^l \delta_{t+l} A ^ t G A E ( γ , λ ) = l = 0 ∑ ∞ ( γλ ) l δ t + l
当 λ = 1 \lambda=1 λ = 1 时,它接近 Monte Carlo advantage;当 λ = 0 \lambda=0 λ = 0 时,只保留单步 TD residual:
A ^ t G A E ( γ , 0 ) = δ t \hat{A}_t^{GAE(\gamma, 0)} = \delta_t A ^ t G A E ( γ , 0 ) = δ t
其中 λ \lambda λ 控制 bias-variance tradeoff:
λ \lambda λ 更接近 特点 0 one-step TD 方差低,偏差可能更高 1 Monte Carlo return 偏差低,方差更高 0 到 1 多步折中 PPO 常用选择
GAE 的意义不是改变 PPO 的核心目标,而是提供更稳定的 advantage 估计。[Schulman et al., 2015, arXiv:1506.02438]
6. On-policy:为什么旧数据会过期
Policy Gradient 的期望写作:
E τ ∼ π θ [ ⋯ ] \mathbb{E}_{\tau \sim \pi_\theta}[\cdots] E τ ∼ π θ [ ⋯ ]
这意味着数据应该来自当前 policy。如果我们用旧 policy π θ o l d \pi_{\theta_{old}} π θ o l d 采样的数据去更新新 policy π θ \pi_\theta π θ ,分布就变了。
例如:
old policy 很少尝试 action A;
new policy 却已经很喜欢 action A。
那旧数据里 action A 的样本就很少,用它来估计新 policy 的真实表现会有偏差。
这就是 on-policy 的核心限制:
类型 数据来源 优点 缺点 on-policy 当前 policy 新采样 估计更直接、更稳定 样本利用率低 off-policy 可使用旧 policy 或 replay buffer 数据 样本利用率高 需要校正分布偏移,训练更复杂
PPO 经常被放在 on-policy 算法里,因为它仍然依赖当前或刚刚过去的 policy 采样数据;但它又不是“一条轨迹只更新一次”的朴素 on-policy。
更准确的说法是:PPO 是 on-policy 算法,但会在一个受限制的范围内,用 importance ratio 对刚采样的数据做多轮 minibatch 更新 。
7. 从 on-policy 到“有限 off-policy”:importance ratio
如果数据来自旧策略 π θ o l d \pi_{\theta_{old}} π θ o l d ,我们不能直接把它当作新策略 π θ \pi_\theta π θ 的样本。先从普通 importance sampling 恒等式开始:
E x ∼ p [ f ( x ) ] = ∫ p ( x ) f ( x ) d x = ∫ q ( x ) p ( x ) q ( x ) f ( x ) d x = E x ∼ q [ p ( x ) q ( x ) f ( x ) ] \mathbb{E}_{x \sim p}[f(x)]
= \int p(x)f(x)dx
= \int q(x)\frac{p(x)}{q(x)}f(x)dx
= \mathbb{E}_{x \sim q}\left[\frac{p(x)}{q(x)}f(x)\right] E x ∼ p [ f ( x )] = ∫ p ( x ) f ( x ) d x = ∫ q ( x ) q ( x ) p ( x ) f ( x ) d x = E x ∼ q [ q ( x ) p ( x ) f ( x ) ]
对应到 policy update:
目标分布 p p p 是新策略 π θ \pi_\theta π θ ;
采样分布 q q q 是旧策略 π θ o l d \pi_{\theta_{old}} π θ o l d ;
被修正的量是动作概率。
因此定义 importance sampling ratio:
r t ( θ ) = π θ ( a t ∣ s t ) π θ o l d ( a t ∣ s t ) r_t(\theta) = \frac{\pi_\theta(a_t \mid s_t)}{\pi_{\theta_{old}}(a_t \mid s_t)} r t ( θ ) = π θ o l d ( a t ∣ s t ) π θ ( a t ∣ s t )
把原来的 advantage policy gradient 写成旧数据上的 surrogate objective:
L P G ( θ ) = E t [ r t ( θ ) A ^ t ] L^{PG}(\theta)
= \mathbb{E}_t\left[r_t(\theta)\hat{A}_t\right] L PG ( θ ) = E t [ r t ( θ ) A ^ t ]
这里的 E t \mathbb{E}_t E t 表示对旧 policy 收集到的 timestep 样本求平均。它不是完整无偏地解决所有 off-policy 问题,而是在新旧策略足够接近时给出一个可用近似。
这个 ratio 的含义是:
r t ( θ ) r_t(\theta) r t ( θ ) 含义 r t = 1 r_t = 1 r t = 1 新旧 policy 对这个 action 的概率一样 r t > 1 r_t > 1 r t > 1 新 policy 更倾向这个 action r t < 1 r_t < 1 r t < 1 新 policy 更不倾向这个 action
如果 A ^ t > 0 \hat{A}_t > 0 A ^ t > 0 ,说明这个 action 比预期好,我们希望提高它的概率;如果 A ^ t < 0 \hat{A}_t < 0 A ^ t < 0 ,说明它比预期差,我们希望降低它的概率。
old policy π old(a | s) new policy π θ(a | s) ratio r(θ) = new / old A > 0 larger ratio increases objective A < 0 smaller ratio increases objective problem ratio can move too far
这一步看起来像是从 on-policy 走向 off-policy:旧 policy 采样的数据,也能拿来更新新 policy。
但注意边界:
如果新旧 policy 差异很小,ratio 修正通常比较可靠;
如果新旧 policy 差异很大,ratio 可能极端,方差会变大,更新会不稳定。
所以 PPO 不是要变成完全 off-policy,而是要回答:怎样在复用旧数据的同时,避免新旧策略差得太远?
8. 加约束:TRPO 的 trust region 思想
TRPO 的核心动机是:policy 更新不能太大。因为在强化学习里,一个看似小的参数变化,可能让动作分布发生很大变化,导致性能突然崩溃。
从 surrogate objective 到 KL 约束
前面得到的 surrogate objective 是:
L P G ( θ ) = E t [ r t ( θ ) A ^ t ] L^{PG}(\theta)
= \mathbb{E}_t\left[r_t(\theta)\hat{A}_t\right] L PG ( θ ) = E t [ r t ( θ ) A ^ t ]
如果只最大化它,会出现一个问题:只要 A ^ t > 0 \hat{A}_t > 0 A ^ t > 0 ,优化器就会不断增大 r t ( θ ) r_t(\theta) r t ( θ ) ;只要 A ^ t < 0 \hat{A}_t < 0 A ^ t < 0 ,优化器就会不断压低 r t ( θ ) r_t(\theta) r t ( θ ) 。这可能让新策略离旧策略很远。
TRPO 的做法是:继续最大化 surrogate objective,但显式约束新旧 policy 的平均 KL 距离:
max θ E t [ π θ ( a t ∣ s t ) π θ o l d ( a t ∣ s t ) A ^ t ] \max_\theta \; \mathbb{E}_t\left[
\frac{\pi_\theta(a_t \mid s_t)}{\pi_{\theta_{old}}(a_t \mid s_t)}\hat{A}_t
\right] θ max E t [ π θ o l d ( a t ∣ s t ) π θ ( a t ∣ s t ) A ^ t ]
subject to E t [ D K L ( π θ o l d ( ⋅ ∣ s t ) ∣ ∣ π θ ( ⋅ ∣ s t ) ) ] ≤ δ \text{subject to}\quad
\mathbb{E}_t\left[D_{KL}\left(
\pi_{\theta_{old}}(\cdot \mid s_t)\;||\;\pi_\theta(\cdot \mid s_t)
\right)\right] \leq \delta subject to E t [ D K L ( π θ o l d ( ⋅ ∣ s t ) ∣∣ π θ ( ⋅ ∣ s t ) ) ] ≤ δ
KL 项展开为:
D K L ( p ∣ ∣ q ) = ∑ a p ( a ) log p ( a ) q ( a ) D_{KL}(p||q) = \sum_a p(a)\log\frac{p(a)}{q(a)} D K L ( p ∣∣ q ) = a ∑ p ( a ) log q ( a ) p ( a )
因此这里的约束衡量的是:在同一个 state 下,旧 policy 的动作分布和新 policy 的动作分布相差多大。
也就是说:
你可以提高目标函数,
但新 policy 不能离旧 policy 太远。
old policy trust region: average KL ≤ δ safe update too far TRPO maximize surrogate objective under a KL constraint stable but more complex
TRPO 很优雅,但实现上通常需要二阶近似、共轭梯度、line search 等步骤,工程复杂度高。[Schulman et al., 2015, arXiv:1502.05477]
PPO 的目标就是保留 trust region 的直觉,但用更简单的一阶优化方法实现。
9. PPO Clipped Objective:用裁剪限制更新动机
PPO 最常见的版本是 PPO-Clip。它不直接写 KL 约束,而是从未约束的 surrogate objective 出发:
L P G ( θ ) = E t [ r t ( θ ) A ^ t ] L^{PG}(\theta)=\mathbb{E}_t[r_t(\theta)\hat{A}_t] L PG ( θ ) = E t [ r t ( θ ) A ^ t ]
问题是这个目标没有阻止 ratio 走得太远。于是 PPO 先构造一个被裁剪的 ratio:
r ˉ t ( θ ) = clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) \bar{r}_t(\theta)
= \operatorname{clip}(r_t(\theta), 1 - \epsilon, 1 + \epsilon) r ˉ t ( θ ) = clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ )
也就是:
r ˉ t ( θ ) = { 1 − ϵ , r t ( θ ) < 1 − ϵ r t ( θ ) , 1 − ϵ ≤ r t ( θ ) ≤ 1 + ϵ 1 + ϵ , r t ( θ ) > 1 + ϵ \bar{r}_t(\theta)=
\begin{cases}
1-\epsilon, & r_t(\theta) < 1-\epsilon \\
r_t(\theta), & 1-\epsilon \leq r_t(\theta) \leq 1+\epsilon \\
1+\epsilon, & r_t(\theta) > 1+\epsilon
\end{cases} r ˉ t ( θ ) = ⎩ ⎨ ⎧ 1 − ϵ , r t ( θ ) , 1 + ϵ , r t ( θ ) < 1 − ϵ 1 − ϵ ≤ r t ( θ ) ≤ 1 + ϵ r t ( θ ) > 1 + ϵ
如果只把 r t r_t r t 替换成 r ˉ t \bar{r}_t r ˉ t ,还不够保守。PPO 使用原目标和裁剪目标的较小值:
L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , r ˉ t ( θ ) A ^ t ) ] L^{CLIP}(\theta) =
\mathbb{E}_t\left[
\min\left(
r_t(\theta)\hat{A}_t,
\bar{r}_t(\theta)\hat{A}_t
\right)
\right] L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , r ˉ t ( θ ) A ^ t ) ]
代入 r ˉ t \bar{r}_t r ˉ t ,就是常见写法:
L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t ) ] L^{CLIP}(\theta) =
\mathbb{E}_t\left[
\min\left(
r_t(\theta)\hat{A}_t,
\operatorname{clip}(r_t(\theta), 1 - \epsilon, 1 + \epsilon)\hat{A}_t
\right)
\right] L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t ) ]
这里 ϵ \epsilon ϵ 通常是一个小数,例如 0.1 或 0.2。
这条公式的关键是:当 ratio 已经变化太多时,不再给目标函数继续变好的奖励 。
分情况推导会更清楚。
当 advantage 为正
如果 A ^ t > 0 \hat{A}_t > 0 A ^ t > 0 ,说明这个 action 比预期好,我们希望增加它的概率,也就是让 r t ( θ ) r_t(\theta) r t ( θ ) 变大。
此时目标内的两项是:
r t ( θ ) A ^ t r_t(\theta)\hat{A}_t r t ( θ ) A ^ t
和:
clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t \operatorname{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)\hat{A}_t clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t
因为 A ^ t > 0 \hat{A}_t > 0 A ^ t > 0 ,乘以正数不会改变大小关系。当 r t ( θ ) > 1 + ϵ r_t(\theta) > 1 + \epsilon r t ( θ ) > 1 + ϵ 时:
clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) = 1 + ϵ \operatorname{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)=1+\epsilon clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) = 1 + ϵ
所以:
min ( r t ( θ ) A ^ t , ( 1 + ϵ ) A ^ t ) = ( 1 + ϵ ) A ^ t \min(r_t(\theta)\hat{A}_t, (1+\epsilon)\hat{A}_t)
= (1+\epsilon)\hat{A}_t min ( r t ( θ ) A ^ t , ( 1 + ϵ ) A ^ t ) = ( 1 + ϵ ) A ^ t
也就是说,超过上界以后,目标函数不再因为 ratio 继续变大而增加。PPO 允许提高好 action 的概率,但不奖励无限提高。
当 advantage 为负
如果 A ^ t < 0 \hat{A}_t < 0 A ^ t < 0 ,说明这个 action 比预期差,我们希望降低它的概率,也就是让 r t ( θ ) r_t(\theta) r t ( θ ) 变小。
此时因为 A ^ t \hat{A}_t A ^ t 是负数,乘法会反转大小关系。当 r t ( θ ) < 1 − ϵ r_t(\theta) < 1-\epsilon r t ( θ ) < 1 − ϵ 时:
clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) = 1 − ϵ \operatorname{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)=1-\epsilon clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) = 1 − ϵ
由于 A ^ t < 0 \hat{A}_t < 0 A ^ t < 0 ,有:
r t ( θ ) A ^ t > ( 1 − ϵ ) A ^ t r_t(\theta)\hat{A}_t > (1-\epsilon)\hat{A}_t r t ( θ ) A ^ t > ( 1 − ϵ ) A ^ t
PPO 取二者较小值:
min ( r t ( θ ) A ^ t , ( 1 − ϵ ) A ^ t ) = ( 1 − ϵ ) A ^ t \min(r_t(\theta)\hat{A}_t, (1-\epsilon)\hat{A}_t)
= (1-\epsilon)\hat{A}_t min ( r t ( θ ) A ^ t , ( 1 − ϵ ) A ^ t ) = ( 1 − ϵ ) A ^ t
也就是说,低于下界以后,目标函数不再鼓励继续压低该动作概率。PPO 允许降低坏 action 的概率,但不奖励把它压到过低。
r(θ) = 1 1 - ε 1 + ε A > 0: cap benefit above 1 + ε A < 0: cap benefit below 1 - ε Clipping removes the incentive to move the new policy too far from the old policy.
这就是 PPO 的“proximal”:更新可以发生,但要保持在旧 policy 附近。
PPO 不是硬性保证 KL 一定小于某个阈值,而是通过 clipped surrogate objective 降低过大更新的动机。很多实现还会监控 approximate KL,如果 KL 太大就提前停止当前 epoch。[Schulman et al., 2017, arXiv:1707.06347] [OpenAI, Spinning Up PPO]
10. PPO 的完整 loss
实际 PPO 通常不是只优化 policy loss,还会加上 value loss 和 entropy bonus:
L ( θ , ϕ ) = L C L I P ( θ ) − c 1 L V F ( ϕ ) + c 2 H ( π θ ) L(\theta, \phi) =
L^{CLIP}(\theta)
- c_1 L^{VF}(\phi)
+ c_2 H(\pi_\theta) L ( θ , ϕ ) = L C L I P ( θ ) − c 1 L V F ( ϕ ) + c 2 H ( π θ )
其中:
项 作用 L C L I P L^{CLIP} L C L I P 更新 actor,让更好的动作更可能出现 L V F L^{VF} L V F 训练 critic,让 V ϕ ( s ) V_\phi(s) V ϕ ( s ) 更准确 H ( π θ ) H(\pi_\theta) H ( π θ ) entropy bonus,鼓励探索,避免策略过早坍缩
value loss 常见写法是:
L V F ( ϕ ) = E t [ ( V ϕ ( s t ) − R ^ t ) 2 ] L^{VF}(\phi) = \mathbb{E}_t\left[(V_\phi(s_t) - \hat{R}_t)^2\right] L V F ( ϕ ) = E t [ ( V ϕ ( s t ) − R ^ t ) 2 ]
其中 R ^ t \hat{R}_t R ^ t 可以理解为用于训练 critic 的回报目标。
PPO 因此是一个 actor-critic 方法:
state s observation Actor πθ(a | s) Critic Vφ(s) PPO update clip + value + entropy
11. PPO 算法流程
PPO 的训练循环可以分成两层:
外层:用当前 policy 和环境交互,收集一批 trajectories;
内层:在这批数据上做多轮 minibatch SGD,但用 clipping 限制 policy 漂移。
完整流程如下:
1. collect rollout using π old 2. estimate values V(s), returns 3. compute GAE Â_t 4. freeze log π old 5. minibatch SGD several epochs 6. clipped loss policy + value + entropy 7. update policy θ old ← θ
伪代码可以写成:
initialize policy πθ and value function Vφ
repeat:
θ_old ← θ
collect trajectories using πθ_old
compute rewards-to-go or return targets
compute advantages  using Vφ, γ, λ
store old log probabilities log πθ_old(a_t | s_t)
for epoch in 1..K:
for minibatch in collected data:
r_t(θ) = exp(log πθ(a_t | s_t) - log πθ_old(a_t | s_t))
policy_loss = -mean(min(
r_t(θ) * Â_t,
clip(r_t(θ), 1 - ε, 1 + ε) * Â_t
))
value_loss = mean((Vφ(s_t) - return_target_t)^2)
entropy_bonus = mean(entropy(πθ(. | s_t)))
loss = policy_loss + c1 * value_loss - c2 * entropy_bonus
update θ, φ with gradient descent
optionally stop early if approximate KL is too large
这里有几个容易混淆的点:
设计 目的 保存 old log prob 计算新旧策略 ratio 多轮 minibatch 更新 提高同一批 rollout 的数据利用率 clipping 避免多轮更新把 policy 推太远 advantage normalization 让梯度尺度更稳定,常见但不是 PPO 目标的核心 approximate KL early stop 额外安全阀,不是所有实现都完全一样
12. PPO 为什么稳定
PPO 的稳定性来自几个机制叠加,而不是单一技巧:
机制 解决什么问题 折扣因子 γ \gamma γ 定义长期回报,并减少远期不确定性的影响 baseline / critic 降低 Policy Gradient 方差 GAE 在 bias 和 variance 之间折中估计 advantage importance ratio 允许用旧 policy 数据评估新 policy 更新 clipped objective 限制新旧 policy ratio 变化带来的过大收益 minibatch + 多 epoch 提高样本利用率 entropy bonus 保持探索,避免过早确定化
更直观地说:
Vanilla Policy Gradient: 方向对,但噪声大,数据利用率低。
TRPO: 更新稳,但优化过程复杂。
PPO: 用 clipping 模拟 trust region 的效果,保留一阶优化的简单性。
这也是 PPO 被大量使用的原因:它不是理论上最完美的 policy optimization 方法,但在“稳定性、实现难度、样本效率、工程可调性”之间做了很好的折中。
13. 常见误区
误区一:PPO 是 off-policy 算法
不准确。
PPO 通常仍被归类为 on-policy。它的数据来自当前或刚刚过去的 policy,不像 DQN / SAC 那样长期使用 replay buffer 里的旧数据。
更准确的说法是:PPO 使用 importance ratio 和 clipping,在有限范围内复用刚采样的数据 。
误区二:clipping 等价于 KL 约束
不完全等价。
TRPO 直接约束平均 KL;PPO-Clip 是通过裁剪 ratio,让目标函数不再奖励过大策略变化。它通常能起到类似 trust region 的经验效果,但不是严格的 KL 约束。
误区三:baseline 会改变最优策略
不会。
只要 baseline 不依赖 action,它不会改变 Policy Gradient 的期望,只会减少方差。它改变的是训练稳定性,不是优化目标的最优解。
误区四:advantage 越大越好
不一定。
advantage 是估计量。估计噪声太大时,更新方向会不稳定。实践中常见做法是对 advantage 做 normalization,让训练尺度更平稳。
14. 一句话总结
PPO 可以理解成:
在 Policy Gradient 的基础上,用 critic / GAE 降低方差,用 importance ratio 复用刚采样的数据,再用 clipping 限制新旧策略差异,从而实现一种简单、稳定、可工程化的 policy optimization 方法。
如果只记一个公式,就是:
L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t ) ] L^{CLIP}(\theta) =
\mathbb{E}_t\left[
\min\left(
r_t(\theta)\hat{A}_t,
\operatorname{clip}(r_t(\theta), 1 - \epsilon, 1 + \epsilon)\hat{A}_t
\right)
\right] L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t ) ]
如果只记一个直觉,就是:
好的 action 可以更可能出现,坏的 action 可以更少出现;
但无论变好还是变坏,都不要让 policy 一步跨得太远。
References
[Schulman et al., 2017] John Schulman, Filip Wolski, Prafulla Dhariwal, Alec Radford, Oleg Klimov. “Proximal Policy Optimization Algorithms.” arXiv:1707.06347.
[Schulman et al., 2015] John Schulman, Sergey Levine, Pieter Abbeel, Michael Jordan, Philipp Moritz. “Trust Region Policy Optimization.” arXiv:1502.05477.
[Schulman et al., 2015] John Schulman, Philipp Moritz, Sergey Levine, Michael Jordan, Pieter Abbeel. “High-Dimensional Continuous Control Using Generalized Advantage Estimation.” arXiv:1506.02438.
[Sutton et al., 2000] Richard S. Sutton, David McAllester, Satinder Singh, Yishay Mansour. “Policy Gradient Methods for Reinforcement Learning with Function Approximation.” NeurIPS.
[OpenAI] OpenAI Spinning Up. “Proximal Policy Optimization.”