资讯动态

理解策略单调提升:TRPO与PPO背后的信任域与KL散度

发布时间:2026/10/17 19:05:16 来源:尧图企业网站定制
2021年2月12日我把强化学习笔记翻到第四十三篇正好卡在Monotonic Improvement Theory也就是策略的单调提升理论。说实话策略优化这一块最容易让人懵的不是某个算法有多复杂而是“为什么TRPO要限定KL散度”“为什么PPO要裁剪概率比”这些问题追根溯源都会落到单调提升理论上。这篇笔记我打算把这条线完整串起来它想解决什么困境、数学上怎么给出保证、TRPO和PPO各自怎么落地以及我实际调参过程中踩过的坑。适合刚学完策略梯度、准备进入TRPO和PPO的同学也适合那些跑了不少实验但始终没把理论脉络理顺的人。1. 为什么策略提升需要“单调”1.1 策略梯度方法的两难策略梯度方法的直觉非常简单把期望回报对策略参数求梯度然后沿着梯度方向更新参数。REINFORCE和Actor-Critic的更新公式本质上都是[ \nabla_\theta J(\theta) \mathbb{E}{\tau \sim \pi\theta} \left[ \sum_t \nabla_\theta \log \pi_\theta(a_t|s_t) A_t \right] ]用一批采样轨迹估计出这个梯度再执行参数更新。问题很快就会出现步长到底设多少步长太小策略几乎原地踏步训练几十万步都没有明显进展步长太大一个更新直接让策略跳到很差的位置后面采样到的状态分布彻底漂移前面的数据全部作废。这种“漂移—报废”的过程在训练曲线上往往表现为一段上升之后突然断崖式下跌。很多新手把锅甩给学习率把学习率调小一点确实能缓解但代价是训练慢到让人失去耐心。这里真正的矛盾在于当前梯度是在旧策略的采样分布下估计出来的它只在旧策略附近一小片区域里有较高可信度。新策略离旧策略越远梯度信息的保质期就越短。用一次固定步长的梯度更新根本没考虑策略空间的曲率。不同位置的“合理步长”完全不一样一个全局常数当然照顾不到所有情况。1.2 单调提升的直观图景如果每一次策略更新都能保证新策略的期望回报不低于旧策略那整个训练过程就是一条单调上升的曲线。这像是你每次修改完一份代码程序性能至少不会变差最多原地踏步。放在强化学习的场景里这就意味着可以在更新策略后放心继续采样不用担心昨天的好策略被今天的一次更新毁掉。但现实没有这么温柔。新策略的期望回报无法直接从旧数据里算出来必须重新采样、重新评估成本高得不可接受。于是研究者换了一个思路不直接优化真实目标而是在旧策略数据上构造一个“替代目标”。这个替代目标在旧策略处与真实目标函数值相等、梯度也相等所以局部可以用。关键问题是替代目标提升了真实目标究竟提升了多少单调提升理论回答的正是这个问题。它不追求无条件的单调而是给出一个误差界只要新旧策略足够接近替代目标的提升量就能下界地传递到真实目标上。换句话说“接近”换取“保证”。这个思路后来成为TRPO的理论基石也间接影响了PPO的设计哲学。1.3 从目标函数到替代目标先定义两个目标真实期望回报 (\eta(\pi)) 和替代目标 (L_\pi(\tilde{\pi}))。[ L_\pi(\tilde{\pi}) \eta(\pi) \sum_s \rho_\pi(s) \sum_a \tilde{\pi}(a|s) A_\pi(s,a) ]其中 (\rho_\pi(s)) 是旧策略下的折扣访问频率(A_\pi) 是旧策略的优势函数。当 (\tilde{\pi} \pi) 时这个替代目标等于真实回报对 (\tilde{\pi}) 求梯度时(\eta(\pi)) 是常数所以梯度的核心就是[ \sum_s \rho_\pi(s) \sum_a \nabla_\theta \tilde{\pi}\theta(a|s) A\pi(s,a) ]这样就有两个轮子替代目标负责“效率”误差界负责“安全”。只有替代目标而没有误差界策略更新会失控只有误差界而没有替代目标每一步更新小得可怜训练永远走不远。单调提升理论的贡献就是把这两个轮子用数学方法焊在了一起。2. 单调提升的核心推导与边界2.1 新旧策略回报差的拆解要给出单调性保证第一步是找到新旧策略期望回报差的精确表达式。从任意初始状态出发把新策略 (\tilde{\pi}) 和旧策略 (\pi) 产生的轨迹逐时间步做差用优势函数的累计求和做telescoping展开可以得到一个非常漂亮的等式[ \eta(\tilde{\pi}) - \eta(\pi) \sum_s \rho_{\tilde{\pi}}(s) \sum_a \tilde{\pi}(a|s) A_\pi(s,a) ]这个公式值得反复琢磨。左边是新旧策略的真实回报差右边每一项都是同一个优势函数 (A_\pi)但状态访问频率却来自新策略 (\tilde{\pi})。也就是说所有优势值都是从旧策略视角计算的“这个动作比平均水平好多少”而哪些状态会被频繁访问则取决于新策略。这个拆解的意义在于如果新策略更大概率选择优势为正的动作那么回报差就会为正。但问题也藏在这里。新策略会改变状态访问频率而访问频率的变化反过来又影响右侧权重。两边相互耦合不是简单“优势最大化的动作多采样一点”就能直接算清的。2.2 访问概率偏置与优势函数如果直接用旧策略的访问频率 (\rho_\pi(s)) 替换 (\rho_{\tilde{\pi}}(s))由于访问频率分布不一致会产生偏置。一种粗略的想法是既然新旧策略可能很像状态分布应该也差不多偏置不会太大。这句话在直觉上没错问题是如何量化。任意状态的访问频率受折扣因子 (\gamma) 影响。(\gamma) 越接近1轨迹越长早期一个微小动作分布偏移会通过环境动态不断传播最终放大到许多后续状态上。因此理论推导中会出现 ((1-\gamma)^{-1}) 甚至 ((1-\gamma)^{-2}) 这样的项就是用来吸收这种长期传播效应。常数里面有 (\gamma) 和 (1-\gamma)说明任务越长、折扣越重策略更新就必须越谨慎。这也能解释为什么在许多稀疏奖励、长周期任务里直接用PPO默认参数很容易不稳定。不是PPO本身有问题而是这些任务天然对策略漂移更敏感需要更紧的信任域或更保守的更新幅度。2.3 误差界TV距离、KL散度与常数C把访问频率偏置和优势函数误差统一收进一个误差界就得到类似这样的不等式[ \eta(\tilde{\pi}) \ge L_\pi(\tilde{\pi}) - C \cdot \alpha ]其中 (\alpha) 用于描述新旧策略在每个状态上的最坏分布偏差比如最大TV距离 (D_{TV}^{\max}(\pi,\tilde{\pi}))而常数 (C) 的量级通常包含 (\frac{2\epsilon\gamma}{(1-\gamma)^2}) 之类的因子。不同论文的推导会有细微差异有的把 (\alpha) 写成平方有的不写关键不在于死记这个常数而在于理解三个结论。第一误差界和“每个状态下”的最大偏差有关不是一个全局平均值。某个状态的策略分布完全变了哪怕其他状态都保持原样误差也会被拉大。第二误差界会随着折扣因子接近1急剧放大所以长生命周期任务里策略更新需要更保守。第三TV距离不好优化但Pinsker不等式把它和KL散度联系起来[ D_{TV}(p,q) \le \sqrt{\frac{1}{2} D_{KL}(p|q)} ]于是可以用KL散度替代TV距离。KL散度在策略参数上是平滑的可以求梯度可以二阶近似这才有了后续的信任域方法。选择KL不是拍脑袋而是因为它既能刻画分布差异又具备工程上可操作的性质。3. 从理论到算法TRPO与PPO3.1 信任域策略优化TRPO的落地理论给出的结论是“只要新旧策略足够接近替代目标提升就能传递到真实回报上”。TRPO把这句话直接转成了一个带约束的优化问题[ \max_{\theta} ; L_{\theta_{\text{old}}}(\theta) ][ \text{s.t.} \quad \bar{D}{KL}(\theta{\text{old}}, \theta) \le \delta ]其中 (\bar{D}_{KL}) 是旧策略采样状态下新旧策略KL散度的平均值(\delta) 就是信任域半径。用平均KL而不是理论里的最大KL是工程上的妥协因为平均KL更容易从样本中估计。直接解这个约束优化代价很高。TRPO的做法是目标函数在 (\theta_{\text{old}}) 处做一阶近似KL约束做二阶近似得到一个带二次约束的线性规划问题。它的最优解形如自然梯度更新[ \theta \theta_{\text{old}} \sqrt{\frac{2\delta}{g^T F^{-1} g}} F^{-1} g ]这里 (g) 是替代目标梯度(F) 是Fisher信息矩阵。真正实现时(F) 的维度等于策略参数个数显式求逆是不现实的所以要用共轭梯度法迭代求解 (F^{-1}g)并且每次只需要计算一个“Fisher向量积”。更新之后再做线搜索逐步缩小步长直到KL约束满足。这一套流程比普通策略梯度重很多但换来了更强的更新稳定性。3.2 PPO如何把约束变成惩罚TRPO虽好计算量和实现复杂度都不小。PPO的目标是保留“不漂移”的精神同时去掉二阶优化。它最常用的做法是裁剪概率比[ L^{\text{CLIP}}(\theta) \mathbb{E} \left[ \min \left( r_t A_t, ; \operatorname{clip}(r_t, 1-\epsilon, 1\epsilon) A_t \right) \right] ]其中 (r_t \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)}) 是重要性采样比率。直观解释是当一个动作的优势为正我们希望加大它的选择概率但只允许加到概率比 (1\epsilon) 为止当一个动作的优势为负我们希望降低它的选择概率但只允许降到 (1-\epsilon) 为止。这样每一步更新不会把单个动作的概率推得太夸张分布漂移就受到了限制。这个裁剪并不是单调提升理论严格推导出来的约束而是一种工程近似。它没有显式限制KL散度只是限制了概率比的上下界。概率比接近1的时候新旧策略自然接近概率比远离1时梯度被裁剪不会继续推。很多资料把PPO描述成TRPO的一阶近似这个说法不完全准确但思路确实是同一个构造一个不会跑飞的目标函数。PPO还有一个自适应KL惩罚版本目标函数里加上 (\beta \bar{D}_{KL})然后根据实测KL动态调整 (\beta)。如果当前KL明显超过目标值就加大惩罚系数如果KL低于目标就减小惩罚系数。这个版本更接近理论原味但实际中用纯裁剪版本的人更多因为它少一个需要调的超参数整体也够稳。3.3 为什么实际中很难真正“单调”理论上快照旧策略、严格限定KL散度替代目标提升是可以传导到真实回报的。但实际训练里几乎没人看到一条完全单调的回报曲线原因有很多。第一个原因是优势估计有噪声和偏差。GAE也好蒙特卡洛估计也好都只是 (A_\pi) 的近似代入不等式后误差界不再严格成立微小的优势估计偏差可能被常数 (C) 放大。第二个原因是价值函数本身也在变化。策略更新后价值函数继续拟合新策略它提供的优势信号每轮都在移动相当于目标本身不是静止的。第三个原因是理论常数通常过于保守。如果真按理论给出的最小步长去更新训练会慢得让人怀疑人生所以算法实现普遍会在边界上冒险。第四个原因是实践中只用平均KL约束某个状态子集的策略分布可能已经大幅偏移只是被平均数掩盖了。明白这些之后就不必因为回报曲线偶尔下跌就恐慌。你要做的是关注KL散度、熵、优势估计这些信号判断当前更新是否真的在“信任域外”。如果KL并不大回报下跌大概率是优势估计噪声或价值函数拟合问题而不是策略漂移灾难。4. 实操配置、监控与排障4.1 一个我常用的稳定配置先给出一套我在两类任务上反复验证过的配置作为默认起点。连续控制任务里我通常用两层256个神经元的MLP激活函数选tanh策略输出层的均值用线性层直接输出log标准差初始化在-0.5到0之间。离散任务里网络规模可以小一些两层64到128个神经元通常就够。超参数我习惯这样设置PPO的学习率3e-4裁剪系数0.2GAE的 (\lambda0.95)折扣因子0.99每次更新用2048到4096条transitionmini-batch大小64一个PPO周期内更新10次。TRPO方面KL目标设为0.01线搜索回退系数0.5最大回溯次数10。为什么这些数字这么常用3e-4是Autodiff社区在大量实验里沉淀出来的经验值配合裁剪系数0.2既保证前几千步能快速提升又不至于一步跑飞。2048这个批量大小能让优势估计方差不太大同时单次更新耗时不至于太久。如果你跑的任务特别难第一个该调的不是学习率而是增大批量或者降低裁剪系数这两招往往比调学习率更有效。4.2 训练监控指标与异常波形跑PPO和TRPO的时候我至少会盯四个指标新旧策略的平均KL散度、策略熵、价值函数解释方差、以及回合回报曲线。平均KL散度是判断“信任域是否越界”最直接的指标。PPO裁剪系数0.2时平均KL一般在0.01到0.05这个量级。如果某次更新后KL突然冲到0.3以上说明裁剪限制没有生效很可能是重要性采样权重出现了极端值或者某条transition的优势异常大。策略熵是另一个重要信号。熵下降太快说明策略过早变得确定性容易卡在局部最优熵如果几乎为0基本就是策略冻结了后续训练很难通过探索跳出局部解。训练曲线最常见的异常是“上升后断崖下跌”。我遇到过一次任务收敛到不错的奖励之后某次更新直接跌回初始水平。排查时先看KL发现那一轮的平均KL高达0.5原来是GAE里一条轨迹的回报估计出现异常尖峰导致优势方差暴增PPO的裁剪没能兜住。改法是把GAE的 (\lambda) 从0.95调低到0.9同时给优势做一次标准化之后断崖再也没有出现。还有一种现象是回报长期不涨。这时候先别怀疑算法检查价值函数是否拟合正常。如果解释方差很低说明Critic根本没学会预测回报优势信号全是噪声策略自然原地打转。解决办法往往是调大批量降低价值函数学习率或者给网络结构加一点归一化层。4.3 常见问题速查表现象可能原因排查方向与解决训练早期回报断崖下跌单次策略更新漂移过大查看KL散度降低PPO裁剪系数到0.1或0.15给优势做标准化策略熵骤降为0探索能力耗尽降低熵正则系数减小学习率检查奖励是否过于稀疏回报长期不涨Critic拟合效果差关注解释方差调大批量增加价值网络容量Loss中出现NaN概率比溢出或优势异常给概率加数值下限对回报做裁剪检查是否出现极端奖励值KL散度几乎为0更新步长太小策略被冻结提高学习率或裁剪系数检查是否梯度被错误mask同一个任务多次运行结果差异巨大随机种子或初始策略敏感固定随机种子尝试调整网络初始化增大批量和更新次数取均值这些排障思路不区分PPO和TRPO核心都是“拆开看是哪一层出了问题”。策略层、价值层、数据层分开排查通常半小时就能定位大部分训练异常。5. 从2021回看理论的扩展与个人体会5.1 自适应KL与熵正则PPO的自适应KL版本是一个经常被低估的设计。它通过在优化过程中实时监测KL散度动态缩放KL惩罚系数本质上是把步长从开环控制改成了闭环控制。这个思想比单纯的裁剪更接近单调提升理论的原始框架对某些对更新幅度敏感的任务有明显帮助。我曾在一个高维连续控制任务上对比过纯裁剪和“裁剪自适应KL”两种配置。纯裁剪版本一开始提升很快但中期出现了两次明显回撤加了自适应KL之后虽然前期速度略慢但中后段曲线平稳很多最终收敛结果也更高。原因是裁剪只限制单步概率比不保证整体分布距离而KL惩罚显式抑制了分布漂移。如果你的任务每次训练曲线都抖得厉害值得试试这个组合。熵正则也可以从信任域视角重新理解。最大化策略熵相当于给策略加了一个“不要过早确定”的软约束它不限制新旧策略之间的距离但限制策略分布的退化程度。这和单调提升理论关心的分布变化是同一类问题策略太陡分布变化太剧烈采样估计就失真。5.2 其他约束设计思路沿着单调提升理论继续往后看会发现后来不少方法都在回答同样一个问题如何在利用旧数据的同时不让策略跑飞。SAC这类最大熵方法把熵约束写进目标函数实际上是在每次更新时卡住一个“策略不要过度自信”的边界。有些基于概率分布的策略表示方法直接在策略更新后做分布投影把新策略投影回旧策略的邻域这比KL惩罚更机械但更容易控制。还有一些方法把信任域施加在Q函数或优势估计上限制价值目标的变化速度缓解非平稳性问题。这些思路单独看五花八门本质上都是单调提升理论中“误差界替代目标”这个框架的变形。理解了这条主线之后再看新算法会轻松很多。一个新策略优化算法如果号称稳定你第一个该问的问题就是它用什么办法控制新旧策略的分布差异是硬约束、软惩罚还是某种裁剪投影所有表述不同内核都是同一个。5.3 我自己绕过的学习弯路我最初学TRPO和PPO时选择直接看PPO源码跳过了单调提升理论。结果就是跑实验能跑出曲线但一遇到训练崩溃就无从下手。我隐约知道clip是限制更新幅度却不知道为什么要限制限制多少合适出了问题该往哪个方向调。后来花了一周时间回头啃理论推导才真正看懂KL散度、信任域、优势函数之间是怎么咬合的。如果让我重新走一遍学习路径我会建议按“策略梯度 → 单调提升 → TRPO → PPO”的顺序来学。先理解策略梯度的步长困境再理解替代目标和误差界的使用方法然后看TRPO如何用约束优化实现信任域最后看PPO如何用裁剪近似它。这条链路也许比我当初的“源码优先”路径慢但后劲足得多。调试算法时脑中有理论地图和没有理论地图完全是两种体验。落到个人体会我想强调一点单调提升理论最有价值的并不是那个具体常数而是“替代目标 误差界”这一整套建模方式。它教会我们在不能直接优化真实目标的时候先在近似目标上迈一小步再严格盯住这一步是否越界。这个思路不仅适用于策略优化也适用于其他需要利用旧数据做增量更新的场景。理解到这一层第四十三篇笔记才算真的没白写。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑