PPO 裁剪:限制策略一步走多远
Clipped surrogate 近似 trust region,实现比 TRPO 简单;ε、entropy coef 和 value loss 权重是主要旋钮。

1. 策略一步跳太远,on-policy 数据全废
On-policy 算法 collect 一批 rollout 后做多 epoch 更新——同一 batch 被啃多遍,若策略一步跳太远,旧 data 上的 ratio 爆炸,梯度方向全错。TRPO 用 KL 约束 trust region,实现重;PPO-clip 用 clipped surrogate 近似同一意图,实现简单,是 locomotion 和 manipulation 的默认起点。
Contact-rich 任务上 常导致 approx_kl 过大、训练震荡——降到 0.1 学习慢一些但更稳。我在 contact-rich 任务上把 clip_range 从 0.2 降到 0.1,approx_kl 会明显变小——trade-off 是 sample 效率换稳定性,对 sim 够便宜的任务值得。Rich contact 意味着 action 分布尖、Q/V 曲面陡,policy 更新需更保守,ε 是 trust region 半径而非越大越好。
2. 机制:clipped surrogate
概率比 。PPO-clip 目标:
总 loss:。Advantage 来自 GAE,在 mini-batch 内 normalize。On-policy 流程:collect rollout → 算 GAE → K 个 epoch mini-batch 更新 → 丢弃数据。有效 batch size = n_steps × n_envs;机械臂 sim 常用 2048×8 量级。K=3~4 常够,K=10 易过拟合旧 batch——SB3 默认 n_epochs=10 对简单 env 偏多,contact-rich 常降到 3~4。同一 batch 被多 epoch 重复使用时,clip 限制 ratio 在 [1-ε, 1+ε],但若 KL 仍超说明 ε 或 epoch 仍过大,应减而非关 clip。
总 loss 里 value 项和 entropy 项与 clip 项量级要平衡——只盯 clip 不看 explained_variance 和 entropy 曲线,容易在 critic 差或 exploration 枯竭时误判「clip 不够严」。
ratio = torch.exp(log_prob - old_log_prob)
pg1 = ratio * advantage
pg2 = torch.clamp(ratio, 1 - eps, 1 + eps) * advantage
loss = -torch.min(pg1, pg2).mean()SB3 额外提供 clip_range_vf 限制 value 相对 old value 的变化,contact-rich 任务有时有帮助。
3. 关键日志与旋钮
| 指标 | 健康范围 | 异常含义 |
|---|---|---|
approx_kl | <0.02/update | 步太大,减 ε 或 epoch |
clip_fraction | 0.1~0.3 | >0.5 长期说明 step 太大 |
explained_variance | >0.5 | critic 差,先修 value |
| entropy | 前 30% 不贴地 | decay 太快 → premature convergence |
Entropy coefficient 线性 decay 到 0 促进后期 exploit,但 decay 太快会 premature convergence。Learning rate linear decay 和 clip 一起用,后期小步 refine。Multiple epochs 时若 KL 仍超,应减 epoch 或减 LR,而不是关掉 clip。Multi-GPU 很少是 PPO 瓶颈,env 并行才是——先 SubprocVecEnv 再谈多卡。SB3 默认 n_steps=2048、batch_size=64、n_epochs=10,contact-rich 常改 n_epochs=4、clip_range=0.1。
4. 失败模式
Reward/obs normalize 改了旧 checkpoint 无效。Advantage 用 entire rollout normalize 而非 per-minibatch。连续任务 action 未 clip 到合法范围,log prob 异常。KL 仍超时减 epoch 或 LR,而不是关掉 clip——clip 是安全网,不是瓶颈。PPO 调参顺序:先 env/wrapper 一致,再 GAE/bootstrap,最后 clip/ε。
5. CleanRL / SB3 对照
CleanRL 的 ppo.py 里 ratio = exp(log_prob - old_log_prob),然后 max(pg1, pg2) 就是 clip。SB3 额外提供 clip_range_vf 可选限制 value 跳变。On-policy 数据有限,把 n_steps * n_envs 当作有效 batch size——太小则 advantage 估计噪声大,太大则每次更新间隔长、样本新鲜度降。
6. 验收
- Mechanical sim 上 PPO 1e6~5e6 步应明显优于 random。
approx_kl和clip_fraction在健康范围;eval 用deterministic=True。- Contact-rich 任务 ablate ε=0.2 vs 0.1,看 KL 和 return 权衡。
- Export ONNX 前 deterministic policy 跑 100 step,Python 内 ratio ≈1。
explained_variance>0.5 再谈 clip 微调。
7. 案例:clip_range 0.2 在 contact-rich 任务震荡
某机械臂 sim 任务 PPO clip_range=0.2 时 approx_kl 频繁超 0.05、训练震荡——降到 0.1 后 KL 稳定在 0.01 附近,收敛慢约 20% 但最终 success rate 更高。Contact-rich 任务 action 分布尖,policy 更新需更保守——ε 是 trust region 半径,不是越大越好。
8. Value loss 与 clip 的协同
里 默认 0.5——critic 差时 advantage 差,clip 再严也救不了。explained_variance 低应先加 value epoch 或调 ,而非只调 ε。clip_range_vf 限制 value 相对 old value 跳变,contact-rich 任务 value 目标噪声大时有时有帮助,但不能替代 critic 预训练。
Entropy bonus 鼓励探索——decay 到零促进后期 exploit,但 decay 曲线要和 task 难度匹配。简单 locomotion 可 early decay;sparse reward manipulation 需长期保持 entropy,否则 premature convergence 在局部最优。
9. On-policy 数据效率
PPO 丢弃每批 rollout 后重新 collect——data efficiency 低于 off-policy,但实现简单、稳定性好。n_steps × n_envs 是有效 batch size:2048×8=16384 是常见起点,太小 advantage 噪声大,太大更新间隔长、policy 过时。VecEnv 并行是 PPO wall-clock 的关键,不是更大 network。
Multiple epoch 啃同一 batch 时 clip 防止 ratio 爆炸——若 approx_kl 仍超,减 epoch 或 LR 而非关 clip。K=10 对 HalfCheetah 可能过拟合旧 batch,contact-rich 常 K=3~4。CleanRL 和 SB3 默认不同,复现论文时核对 n_epochs。On-policy 数据用完即弃,sample efficiency 低于 SAC,但工程上「能跑起来」的价值 often 高于「理论上更 sample efficient」却调参调崩的算法。Mechanical sim 上 PPO 1e6~5e6 步应明显优于 random——若达不到,先查 reward/obs normalize 和 GAE bootstrap,再查 clip 参数。approx_kl 和 clip_fraction 应进 tensorboard 默认面板,而非可选 log。Contact-rich 任务 ε=0.1 是常见起点,0.2 导致 KL 过大时要先减 ε 而非关 clip。PPO 健康度看 approx_kl 和 clip_fraction,不是只看 return。
PPO-clip 是 on-policy 的 trust region 近似。ε 和 epoch 控制步长,GAE 和 critic 质量决定方向——clip 防止走太远,不能替错误的 advantage。日志里的 approx_kl 和 clip_fraction 是健康度脉搏,长期 ignore 等于 blind flying。
相关
也可以看看
johan's blog