30u30 中文导读 / 30 天目录 / 第 29 天

第 29 天 · 一个 clip,让策略梯度既稳又好写

第 6 单元Proximal Policy Optimization AlgorithmsJohn Schulman, Filip Wolski, Prafulla Dhariwal et al.arXiv · 2017
这是导读,不是翻译。先用 10 分钟拿到这篇论文的思想地图,再去读 原论文 →,去原仓库的 29_PPO/ 目录 → 动手写代码。
给孩子讲:这一天有 10 岁孩子能听懂的讲义,带猜字游戏和动手活动,可打印。打开儿童讲义 → · PDF 简体 · PDF 繁體

一句话

PPO 用一个裁剪后的替代目标限制每次策略更新的幅度,稳定性接近 TRPO,却只需要一阶优化。同一批数据可以训练多轮,实现只比普通策略梯度多几行代码,因此成为强化学习和 RLHF 的默认算法。

论文讲了什么

策略梯度(policy gradient)方法有一个老问题:步子迈大了,策略会崩。一次更新过猛,智能体开始采到更差的数据,之后很难恢复。2015 年的 TRPO 用 KL 散度约束限制更新幅度,但需要共轭梯度和二阶近似,实现复杂。它也不兼容含噪声的结构(例如 dropout)和策略与价值共享参数的网络。

PPO 的做法是只改目标函数。先定义新旧策略的概率比:

r_t(θ) = π_θ(a_t | s_t) / π_old(a_t | s_t)

再定义裁剪替代目标(clipped surrogate objective):

L_CLIP = E[ min( r_t · A_t, clip(r_t, 1 − ε, 1 + ε) · A_t ) ]

A_t 是优势函数的估计值,表示这个动作比平均水平好多少。这个目标的直觉如下:

因为每次更新的收益有上限,同一批采样数据可以安全地跑多轮小批量 SGD。论文在 MuJoCo 实验中每次采 2048 步,训练 10 轮,小批量大小 64,Adam 学习率 3 × 10^(−4)。

完整目标还有两项:价值函数的平方误差(系数 c1)和策略熵奖励(系数 c2)。这对应演员-评论家(actor-critic)结构。优势函数用 GAE 估计,λ = 0.95,γ = 0.99。

关键实验结果有 3 组:

关键概念

策略梯度(Policy gradient)
直接对策略参数求期望回报的梯度,提高优势为正的动作的概率。它不需要环境模型,但梯度方差大,对步长很敏感。
概率比(Probability ratio)
记作 r_t:新策略与采样时的旧策略给同一个动作的概率之比。r_t = 1 表示策略没有变化。它也是重要性采样的权重。
裁剪替代目标(Clipped surrogate objective)
把 r_t 限制在 [1 − ε, 1 + ε],再与未裁剪项取较小值。效果是:策略在改进方向上偏离旧策略超过 ε 后,梯度变为 0。
优势函数(Advantage function)
<code>A(s, a) = Q(s, a) − V(s)</code>,表示动作 a 比该状态下的平均水平好多少。用它代替原始回报,能显著降低梯度方差。
广义优势估计(Generalized Advantage Estimation, GAE)
把多步时序差分误差按 (γλ)^k 加权求和,用来估计优势。λ 在 0 到 1 之间调节:λ = 0 时偏差大,λ = 1 时方差大。
演员-评论家(Actor-critic)
演员网络输出动作分布,评论家网络估计状态价值 V(s)。评论家提供基线来计算优势。两个网络可以共享主干,PPO 的目标函数允许这样做。

历史位置:为什么值得读

PPO 出自 OpenAI。第一作者 John Schulman 也是 TRPO(2015)和 GAE(2015)的第一作者。可以把 PPO 看作他把 TRPO 的“信任域”思想压缩成一行目标函数的结果。

PPO 发表后很快成为 OpenAI 的默认强化学习算法。OpenAI Five 用大规模 PPO 训练 Dota 2 智能体,2019 年击败了世界冠军战队 OG。2022 年的 InstructGPT 用 PPO 依据奖励模型微调 GPT-3,ChatGPT 沿用了同一套流程。

后续研究也揭示了 PPO 的另一面。2020 年,Engstrom 等人发现,PPO 相对 TRPO 的优势有很大一部分来自代码层面的技巧,例如价值函数裁剪、奖励缩放、学习率退火和观测归一化。这些细节在论文正文里没有写全。

在清单里,第 27 天 Legg 把智能定义为在环境中拿奖励的能力,PPO 是实际拿奖励的主力算法。第 30 天的 RLHF 原论文用 A2C 和 TRPO 优化策略。后来把 RLHF 用到语言模型时,它们被换成了 PPO。

学前准备

在原仓库怎么学

  1. README.md:看本日的内容安排和文件清单。
  2. setup.py:运行它,检查依赖是否可用。
  3. implementation.py:按顺序读 4 个部分。ActorCritic 是演员和评论家网络。RolloutBuffer 存储轨迹并计算 GAE。ppo_loss 组合裁剪目标、价值损失和熵奖励。PPOAgent 实现训练循环。
  4. train_minimal.py:先用 CartPole-v1 跑通,再换 LunarLander-v2。
  5. data/README.md:了解训练日志 CSV 的列和模型检查点的保存位置。
  6. visualization.py:画 3 张诊断图:学习曲线、裁剪比例随训练的变化、策略熵随训练的变化。
  7. notebook.ipynb:在笔记本里逐步运行上面的流程。
  8. exercises/:做 5 个练习,依次是裁剪损失、GAE、演员-评论家网络、ε 消融实验、PPO 与普通策略梯度对比。答案在 exercises/solutions/。

今天再看

2026 年,PPO 仍是强化学习的基准算法。在大语言模型里,它的位置在变化:

另一条延续是可验证奖励的强化学习:数学题看答案对错,代码看测试是否通过。这类训练的算法骨架仍然是 PPO 家族,裁剪概率比这个核心设计一直被大规模使用。

容易卡住的地方

延伸阅读