news 2026/10/21 3:20:50

策略梯度到PPO:降低方差、步长约束与连续控制全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
策略梯度到PPO:降低方差、步长约束与连续控制全解析

学策略梯度的时候,很多人都会经历同一个阶段:看公式觉得理所当然,REINFORCE 就两行,策略梯度定理也清清楚楚,但一旦自己动手训练一个智能体,奖励曲线抖得像心律失常。我当初跟这门强化学习公开课的时候,第五课上完这种感觉格外强烈——知道梯度怎么算,却完全不知道怎么控制步长、怎么压低方差、怎么把算法从玩具环境搬到稍复杂一点的任务上。第五课下半部分其实就在填这些坑:从基线技巧到 Actor-Critic,再到 TRPO 的原理动机、PPO 的工程设计,最后落到 DDPG 这类适合连续控制的确定性策略梯度方法。对于正在学强化学习、尤其是想尽快看懂现代强化学习算法论文的人,这节课几乎是绕不开的一块基石。这篇笔记就按课堂主线整理出来,并把我自己动手重跑这些算法时踩过的坑一并写进去。

1. 复习承接:为什么策略梯度课要拆成上下两讲

1.1 上半场留下的那个关键问题

第五课上半部分的核心是策略梯度定理。简单来说,在参数化策略 π_θ(a|s) 之下,目标函数的梯度可以写成:

∇_θ J(θ) = E_{τ ~ π_θ} [ Σ_t ∇_θ log π_θ(a_t|s_t) · R(τ) ]

这个式子的直觉其实非常朴素:如果某条轨迹最终回报高,就抬高这条轨迹里所有动作的概率;回报低,就压低它们。REINFORCE 算法就是对这个梯度做蒙特卡洛估计,跑完一整条轨迹再用累计回报去加权。

但这里有一个非常致命的问题:REINFORCE 是无偏的,方差却大得惊人。原因在于,累计回报 R(τ) 受到整条轨迹里大量随机因素的影响——策略的随机性、环境的随机性、初始状态的分布——所有随机性都会叠加进梯度估计里。训练的时候你会看到 loss 曲线在震荡中缓慢爬行,甚至根本不收敛。老师在课堂上反复强调的一点我记到现在:策略梯度方向本身是对的,但那个方向带了很多噪声,你必须想办法在尽量不破坏无偏性的前提下把方差降下来。

1.2 本讲真正要回答的三个问题

第五课下其实有一条很清晰的逻辑主线,我在完整听完之后才意识到它是在回答三个递进的问题。

第一个问题是:怎么把方差降下来?答案是引入基线(baseline),进一步引入价值函数作为 Critic,这就把纯策略梯度方法发展成 Actor-Critic 结构。第二个问题是:当策略更新不能大步走的时候,怎么才能在数学上给出一个有保障的更新步长?这引出了 TRPO 的置信域约束,也是自然梯度思想在强化学习里的典型应用。第三个问题是:如果动作空间是连续的,继续沿用随机策略采样是否还划算?于是有了确定性策略梯度,DDPG 是它在深度强化学习里的经典落地。

这三条线并不是彼此独立的。AC 结构给后续几乎所有算法提供了骨架,TRPO 和 PPO 解决的是“有了梯度之后怎么迈步”的问题,DDPG 则把整套思路扩展到连续控制。课堂上的讲法是从 REINFORCE 一步步往前走,这个顺序非常符合直觉,笔记这部分也按同样顺序来。

2. 基线技巧到 Actor-Critic:降低方差的两个层次

2.1 减基线:一个不需要学、但必须懂的改动

降低方差最直接的一个手段是给回报 R(τ) 减掉一个基线 b(s)。如果这个基线不依赖于动作,那么策略梯度依然无偏,因为:

Σ_a ∇_θ π_θ(a|s) · b(s) = b(s) · ∇_θ Σ_a π_θ(a|s) = b(s) · ∇_θ 1 = 0

这个式子非常漂亮,它说明基线项在期望意义下不会改变梯度的方向,却能显著降低估计方差。那基线取什么好?一个常用选择是状态价值函数 V_π(s)。减掉 V(s) 之后,用来乘以 log 概率的那一项就变成 Q_π(s, a) − V(s),也就是优势函数 A_π(s, a) 的定义。

这个改动的直觉很直接:如果一个动作比当前状态的平均水平更好,A > 0,就抬高它;比平均水平差,A < 0,就压低它。相比直接用整条轨迹的总回报,用优势函数能够剥离“这个状态本身就已经很好”或“这个状态本身就很差”的影响,让梯度更聚焦在动作质量的相对优劣上。老师在课上也提到,实际实现中如果不方便估计 Q 或 A,直接用回报减去一个状态相关的基线也能起到很大作用,关键是去掉状态层面的公共噪声。

2.2 Critic 上场:AC 结构到底是怎样的

减基线还只是第一步,它并不改变“整条轨迹采样完才能更新”的模式。蒙特卡洛估计要等轨迹结束,这对长周期任务来说效率很低,而且每一段回报都包含大量随机噪声。另一个思路是用一个函数去近似 Q 值或优势值,在轨迹进行到一半的时候就能估计当前动作的价值,这就是 Critic 的来历。

Actor-Critic 的结构相当于两个网络协作:Actor 负责维护策略 π_θ(a|s),决定“怎么做”;Critic 负责估计价值,决定“做得怎么样”。Critic 是演员身边的表演教练,演员在台上演,教练在台下判断某句台词相对于平均水平到底好多少。训练的时候,Actor 用 Advantage 更新,Critic 用 TD 误差更新,两边各学各的,互相促进。

这里有一个典型弯路:很多人第一次搭 AC 的时候会忍不住把 Actor 和 Critic 设计成完全共享骨干、只分两个输出头的结构。在某些场景下这确实能提效,但实战中很容易出现两个任务“抢容量”的情况——Critic 学得越来越准,Actor 的梯度方向却被冲淡。稳妥的做法是,除非有明确理由,否则让两个网络在主干上适度分离,尤其在任务状态比较复杂的时候,独立网络通常比共享网络更容易调通。

2.3 方差、偏差与偏置,别搞混了

减基线不引入偏差,所以是有百利而无一害;但引入 Critic 之后,情况发生了变化。MC 回报是真实回报的无偏估计,方差高;TD 目标是有偏估计,但方差低。把 Critic 引入策略梯度,本质上是拿一点偏差换大量方差缩减。

这类权衡在强化学习里到处都是。课堂上给出了很清晰的对比:REINFORCE 无偏但方差巨大,训练极不稳定;Q Actor-Critic 用 Q 函数的自举值替代真实回报,方差低但偏差依赖价值函数是否准确;A2C 用优势函数作为 Critic 输出,配合并行环境可以进一步稳定训练。我自己的经验是,初学阶段不必追求“最高级”的算法,先把减基线、用优势、用多环境并行这三件事想明白,很多稳定性的问题已经能解决一大半。表格放这里方便对照:

方法梯度中的价值项偏差方差主要痛点
REINFORCE完整轨迹回报无偏极高收敛慢,样本效率低
减基线 REINFORCE回报−基线无偏中高仍依赖完整轨迹
Q Actor-CriticQ 函数自举值有偏中等偏差受 Critic 质量影响
A2C优势函数有偏较低需要维持并行环境

有一点必须单独提醒:偏差和方差并不是“非黑即白”的选择。偏差太高,策略会被某个学得不准的 Critic 带偏,最终收敛到错误的行为上;方差太高,更新过程就像喝醉了走路,根本到不了目的地。AC 类算法的工程重点,其实就是在这两头之间找平衡。

3. TRPO:为什么要约束策略更新的步长

3.1 大步更新带来的崩坏

策略梯度方法的更新公式其实很普通:θ ← θ + α∇J。问题在于,参数空间里相等的一步,在策略分布空间里的影响可能是天差地别的。某个参数方向动一点,输出分布的均值可能已经偏移很远;另一个方向动同样距离,分布几乎没变化。这个现象在神经网络策略里尤其明显,网络参数的空间几何和策略分布的空间几何完全不对应。

如果某个更新恰好踩在了敏感方向上,策略可能一夜间从“随机探索”变成“只输出某个固定动作”,然后整个 batches 的采样分布彻底改变,价值估计也连环崩塌。这就是强化学习里常说的“一更新就崩”现象。早期策略梯度算法不稳定的根源,很大程度就在这种步长失控上。老师举过一个挺形象的类比:在梯度方向上走路,你并不知道自己这一步迈出去之后,脚下的地势会不会突然变成悬崖。

3.2 替代目标函数是怎么推导的

TRPO 的思路是:与其在参数空间里限制步长,不如直接在策略分布空间里做约束。推导从一个优化问题出发:我们想让新策略期望回报最大化,但又不知道新策略的真实表现,所以只能用旧策略采样得到的回报来近似。用一个带约束的优化问题近似原问题:

maximize_θ E_{s,a ~ π_old} [ (π_θ(a|s) / π_old(a|s)) · A_old(s, a) ]

subject to E_s[ KL(π_old(·|s), π_θ(·|s)) ] ≤ δ

第一个式子里的比值就是重要性采样权重,目的很明确:我们只能从旧策略采样,但想优化新策略,所以用概率比值去纠正分布差异。第二个式子则要求新旧策略在平均 KL 散度上不要差太远。KL 散度衡量的是两个概率分布的差异,平均 KL 小于 δ,相当于给策略更新加了一个“看着像旧策略”的约束。

这里最精妙的地方在于:重要性采样保证目标函数在策略附近是原目标的一个合理近似,KL 约束保证我们不会离近似有效的区域太远。两者合在一起,提供的是一个带“安全带”的更新:至少从理论上,每次更新过的策略不会比旧策略差太多。这也是 TRPO 名字的由来——信任域策略优化,我们只在足够信任的区域内更新。

3.3 置信域与自然梯度:数学优雅但工程麻烦

实现 TRPO 的时候,实际优化问题需要先对约束做二阶近似,目标函数做一阶近似,然后用共轭梯度法解一个线性系统,再通过线搜索找到满足 KL 约束的最大步长。这一套在数学上非常优雅,它是自然梯度思想在策略梯度里的经典应用:把参数更新方向从普通梯度方向,变成经过 Fisher 信息矩阵逆修正的方向,从而在分布空间中实现“单位步长”。

但工程实现就没那么优雅了。两点之间的距离度量怎么取,KL 散度用哪些状态来估算,共轭梯度迭代多少步,线搜索的衰减系数设多少,每一步都有可调的自由度。而且 Fisher 信息矩阵的估计在 batch 样本不足时很不稳定。我自己尝试重现 TRPO 的时候就体会过:循环里套循环,单次更新耗时是普通 PG 的好几倍,而且对超参数非常敏感。因此,尽管 TRPO 理论价值极高,深度学习框架里用得最多的反而是它更“粗糙”的后代——PPO。

4. PPO:把置信域做成一个 clip 这么简单

4.1 两个版本的 PPO,课堂讲了什么

PPO 在公开课里给了两个版本。第一个版本是在 TRPO 的目标函数后面直接加一个关于 KL 散度的惩罚项,更新的时候动态调整惩罚系数:如果 KL 太大就加大惩罚,KL 太小就减小惩罚。这个版本写起来容易,但实际调参的时候要对 KL 阈值和系数变化速度做跟踪,稍微有点繁琐。

第二个版本就是现在遍地都是的 PPO-clip。这个版本干脆不做显式约束,而是把重要性采样权重限制在一个区间里。课上给出的目标函数是:

L^CLIP(θ) = E[ min( r_t(θ) · A_t, clip(r_t(θ), 1−ε, 1+ε) · A_t ) ]

其中 r_t(θ) = π_θ(a_t|s_t) / π_old(a_t|s_t),ε 按照经典配置取 0.2。这个式子没有约束、没有二阶近似、没有共轭梯度,只是对目标函数做了一次逐点截断,却实现了与置信域约束类似的保护效果。工程复杂度瞬间降了一个量级,这也是 PPO 能被整个领域广泛使用的原因。

4.2 clip 公式的直觉拆解

很多人在刚接触这个公式的时候,会被里面的 min 和 clip 绕晕。其实拆开看非常直白。先看 r_t 这个比率:它大于 1 说明新策略给这个动作的概率比旧策略高,小于 1 说明概率变低了。乘上优势 A_t 之后会出现四种情况。

当 A > 0,说明这个动作比平均水平好,我们希望 r 尽量大,但 clip 把 r 拦在 1+ε 附近。r 一旦超过 1+ε,目标函数的增长就停下来,这等于告诉优化器:“好动作你可以多选,但别一次冲太猛。”当 A < 0,说明这个动作不好,我们希望 r 尽量小,但 clip 会把下限限制在 1−ε。更关键的是 min 的存在:当 r 已经小于 1−ε 而 A < 0 时,取 min 后会得到一个不随 r 继续降低而变化的平台。也就是说,不管策略怎么把这个坏动作的概率进一步压低,目标都保持不变,梯度截断。这实质上等于划出了一条“更新带宽”:单次更新,任何动作的概率变化都不允许超过 ε 的范围太多。

这个设计非常工程化。它不需要计算 KL 散度,只需要按元素比较几个数,在 GPU 上几乎是零成本。而且它在直觉上抓住了“更新不过头”这个核心诉求——不像自然梯度那样在几何上精确,但足够稳。

4.3 TRPO 和 PPO 的取舍对照

对比项TRPOPPO-clip
约束方式平均 KL 散度约束逐点概率比率截断
优化复杂度二阶近似 + 共轭梯度 + 线搜索一阶梯度,直接反传
稳定性理论保证强,实现敏感经验上非常稳,调参宽容
单次更新开销高低
适用场景理论分析、小规模验证绝大多数深度强化学习任务

从我实际训练的经验来看,PPO 的 ε 在 0.1 到 0.3 之间对最终结果的影响没有想象中大,更值得关注的是广义优势估计里的 λ 和环境并行数量。PPO 的 clip 机制擅长的是“挡住灾难性更新”,但如果你连奖励都没归一化,再稳的算法也会被离谱的奖励尺度搅得一团糟。这一点放后面细说。

5. DDPG:连续动作空间里的确定性策略梯度

5.1 为什么连续空间里随机策略很尴尬

前面讨论的算法,策略输出当的都是某个动作的分布,比如高斯分布的均值和方差。采样的时候从分布里抽一个动作。这在离散动作空间里完全没问题,但一旦到了机器人控制、自动驾驶这类连续动作场景,麻烦就来了。连续动作空间的维度通常不低,你需要在每一步都对动作分布做采样,再拿最大回报或最大 Q 值去反向传播梯度的话,必须对动作空间积分。这个积分在连续高维空间里基本没法精确做,蒙特卡洛近似又非常低效。

更隐蔽的问题在于方差。连续控制里动作是向量,向量的每一个分量都有自己的随机性,随机策略带来的梯度估计噪声会成倍放大。做控制的都知道,对一个机械臂关节角度输出一个高斯分布,训练初期几乎等于在巨大噪声里漫无目的地搜索。你需要的恰恰是“给定状态,直接给出一个确定动作”的设定。

5.2 确定性策略梯度定理讲了什么

确定性策略梯度定理处理的就是这个问题。把策略写成 μ_θ(s),直接输出动作而不是动作分布,那么目标函数对参数的梯度可以写成:

∇_θ J(θ) = E_{s ~ ρ} [ ∇_θ μ_θ(s) · ∇_a Q_μ(s, a)|_{a=μ_θ(s)} ]

这个式子有一个非常优美的结构:它不再需要对动作空间积分,只需要沿着 Critic 对动作的梯度方向去调整 Actor 的输出。Actor 的目的是让“Critic 觉得当前动作的评分”尽可能高,Critic 的目的则是真实估计这个动作的价值。两者形成一个不依赖动作采样的闭环。

要注意的是,确定性策略梯度不再是某种“在采样过程中修正”的估计,它本质上是 actor-critic 在连续控制场景下的一次变形。课堂上也提醒过,这种“通过 Q 函数梯度来指导动作”的思路,直观上和一个爬山过程很像:Critic 构造出一片价值地形,Actor 沿着地形往上爬。地形不准,爬得再积极也没用。

5.3 DDPG 的四个网络和软更新

DDPG 把上面这套确定性策略梯度和 DQN 的思路拼在一起。它维护四个网络:在线 Actor、在线 Critic、目标 Actor、目标 Critic。目标网络用于计算 TD 目标,解决自举更新时“标准答案也在移动”的问题;而目标网络不能每步直接复制,要使用软更新:

θ_target ← τθ_online + (1−τ)θ_target,τ 通常取 0.005

这个 τ 很有讲究。太大会导致目标参数剧烈抖动,训练目标不稳定;太小又让目标网络更新过慢,价值估计跟不上策略的变化。0.005 是一个在经验上大量验证过的取值,但遇到新问题仍然值得检查。此外,DDPG 里还保留了一个经验回放缓冲池,用来破坏样本之间的时间相关性。这一点和 DQN 一致。

我训练 DDPG 的体会是,它比 PPO 更依赖奖励尺度,也对 Critic 的初始质量更敏感。如果你刚开始跑 DDPG 发现智能体完全不动,先别急着改网络结构,大概率是奖励尺度过大或者 Critic 学习率太激进。把环境奖励做一次缩放,比如限制在 ±1 范围内,往往立刻就能看到改进。当然,近年的改进版本会加入一些额外技巧,但课堂这一讲只需要你把 DDPG 的骨架理解透,后面看 TD3、SAC 的改进动机时会顺很多。

6. 自测回顾,以及跑 AC 类算法时最容易翻车的几个点

6.1 你学完这一讲,应该能回答这几个问题

听完课之后,建议拿下面几个问题自测一下,看是不是真的理解了第五课下这条主线。第一,为什么减掉一个与动作无关的基线不会改变策略梯度的期望?第二,AC 框架里的 Critic 到底在“指责”什么,它拟合的目标是从哪里来的?第三,TRPO 用 KL 散度约束,本质上约束的是参数空间还是分布空间?第四,PPO 的 clip 为什么能够在没有显式约束的情况下避免大幅更新,核心机制是什么?第五,确定性策略梯度相比随机策略梯度,在连续动作空间里省掉了怎样的计算困难?

每一个问题背后都对应着本讲一个核心知识点。如果你能不看笔记就讲清楚这五个问题,这节课的消化程度就已经相当好了。如果讲不清楚,建议转过头重新看对应章节的推导过程,再看我之前整理的线上笔记,搭配起来会轻松很多。

6.2 我在实践里反复踩的坑

最后写几个我不止一次踩过的坑,给正准备动手复现这些算法的同学提个醒。

第一个坑是奖励没有归一化就开训。AC 类算法对奖励尺度非常敏感。同一个环境,奖励乘 10,Critic 的学习率就可能明显跟不上,训练曲线看起来就像“死机”。我后来的习惯是:任何新环境先跑一两个 episode 看一下奖励的大致量级,再放进算法。Batch 内部做一个 reward scaling,能解决一大批“算法不收敛”的假象。

第二个坑是 PPO 的 clip 系数和熵正则相互打架。有些初学者会把 ε 调得特别大,以为这样探索更充分,结果策略概率被 clip 拦住之后熵又降得很快,智能体过早收敛到某个动作。反过来,熵系数设太高又会让策略一直不聚焦。我的做法是:ε 保持默认的 0.2,先观察熵值的下降曲线,再决定要不要开熵正则、系数给多少。

第三个坑是 Actor 和 Critic 学习率失衡。AC 框架里,如果 Critic 学得太慢,它给 Actor 的梯度方向就是过时的;如果 Actor 学得太快,它又会跑在价值估计前面,形成恶性循环。很多人一上来把两个网络的学习率都设成 3e-4,其实并不适合所有任务。我常用的经验是,Critic 学习率可以略高于 Actor,或者在训练过程中监控两者 loss 的变化趋势,哪一方明显震荡就先降哪一方的学习率。

第四个坑是目标网络软更新系数被忽略。DDPG 和后续一堆算法里,τ 的取值直接影响稳定性。某个实验里我把 τ 从 0.005 改到 0.01,训练直接开始剧烈震荡,改回去又恢复正常。说明这类超参数不是摆设,换环境、换网络规模的时候值得重新验证一遍。

再补充一个容易被忽视但真的很重要的细节:PPO 这类带重要性采样的算法,如果旧策略和新策略差距已经很大,重要性权重会出现极端值,clip 机制在这种情况下几乎是在“强行兜底”。与其依赖这层兜底,不如把一次 batch 的更新轮数控制住,这点在课堂的 PPO 部分虽然没有重点展开,但实际训练中非常关键。我的经验是最多跑 10–15 轮就停,宁多跑几轮梯度,也不要让策略离采样分布太远。

第五课下覆盖的内容很多,从 AC 到 TRPO、PPO、再到 DDPG,几乎每一段都值得单独做实验去验证。如果只想先跑通一个算法,我会建议从 PPO 开始,它最皮实;等理解了重要性采样和 clip 的保护逻辑之后,再去折腾 DDPG 和它的一系列改进版本,思路会顺很多。希望这篇笔记能把课堂的一些关键推论讲清楚,也帮后来者少踩几个我踩过的坑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 3:20:07

Linux命令行重定向与管道原理及实战应用

1. 这不是“命令行玄学”&#xff0c;而是每天都在用的底层逻辑你有没有过这样的经历&#xff1a;在终端里敲完一条命令&#xff0c;屏幕瞬间刷出几百行日志&#xff0c;眼睛根本跟不上滚动速度&#xff1b;或者想把某个程序的错误信息单独保存下来分析&#xff0c;却只能眼睁睁…

作者头像 李华
网站建设 2026/10/21 3:19:32

7B模型金融智能体架构演进:从RAG到多Agent编排

1. 项目背景&#xff1a;为什么非要用7B模型做金融智能体做金融智能体这个项目&#xff0c;是从一次需求评审开始的。业务那边提了个很实际的需求&#xff1a;让投研人员用自然语言直接查公司财报、算财务指标、对比行业数据&#xff0c;不用再手动翻PDF和Excel。听起来不复杂&…

作者头像 李华
网站建设 2026/10/21 3:19:23

STM32 L298N电机驱动代码详解:PWM调速与方向控制避坑指南

简介&#xff1a;针对STM32与L298N电机控制应用场景&#xff0c;代码包提供可直接运行的Keil工程代码&#xff0c;适合正在学习嵌入式电机驱动、需要用按键调速调向的开发者。压缩包共143个文件&#xff0c;以h头文件、c源文件、o目标文件为主&#xff0c;另有hex烧录文件、uvp…

作者头像 李华
网站建设 2026/10/21 3:18:48

触摸键检测芯片TS223

一、概述TS223是 触 摸 键 检 测 IC&#xff0c; 提 供 1个 触 摸 键 。 触 摸 检 测 IC是 为 了用 可 变 面 积 的 键 取 代 传 统 的 按 钮 键 而 设 计 的 。低 功 耗 和 宽 工 作 电 压是 触 摸 键 的 DC和 AC特 点 。TS223采 用 SSOP16、 SOT23-6的 封 装 形 式 封 装 。二…

作者头像 李华
网站建设 2026/10/21 3:17:28

Linux性能测试与内存泄漏排查:从命令组合到负载模拟

做Linux性能测试&#xff0c;最忌讳的就是一拿到机器就到处敲命令&#xff0c;top看一眼、free扫一行、再随手压一把负载&#xff0c;半小时过去&#xff0c;除了几个飘忽的数字什么都没留下来。我这些年跟核心命令、负载模拟和内存泄漏排查打交道&#xff0c;最深的体会是&…

作者头像 李华
网站建设 2026/10/21 3:17:04

JPA映射MySQL JSON字段:从转换器到原生类型的最佳实践

最近在一个项目里处理“jpa 映射 mysql json 对象”这个需求&#xff0c;刚开始以为只是给实体加个字段的事&#xff0c;结果真做起来才发现&#xff0c;这里面的坑比想象中多不少。这个主题主要解决一个实际问题&#xff1a;MySQL 从 5.7 开始原生了 JSON 类型&#xff0c;但 …

作者头像 李华