对应:Stanford CS234 Lecture 6–7(Policy Search 2 & 3) 配套代码:
code/lecture07/(前 3 个文件只需 numpy;第 4 个需要 torch 和 gymnasium) 预计阅读时间:5 小时
0. 本讲导航
0.1 本讲要回答的问题
第 6 讲结束时,REINFORCE 留下了三个问题:
- 方差大:用完整回合的回报 给动作打分,噪声很大;
- 样本效率低:同策略,每批数据用一次就扔;
- 步长难选:一步走错,策略可能崩溃,再也恢复不过来。
本讲依次解决它们:
| 问题 | 解决方案 | 核心思想来自 |
|---|---|---|
| 方差大 | Actor-Critic:用 TD 误差代替 | 第 3 讲 TD |
| 偏差–方差需要权衡 | GAE:用 在 TD 与 MC 之间插值 | 第 3 讲 TD(λ) |
| 步长难选 | 性能差异引理 → 替代目标 → 信赖域(TRPO) | 本讲 |
| 样本效率低 + 实现复杂 | PPO:裁剪目标,同一批数据安全地多轮更新 | 本讲 |
PPO 是今天最常用的策略梯度算法,从机器人控制到大语言模型的 RLHF(第 9 讲)都在用它。
0.2 学完本讲,你应该能够
- 解释 Actor-Critic 的结构,证明”当 时,TD 误差是优势函数的无偏估计”。
- 写出 GAE 的定义与递推公式,说明 如何控制偏差与方差,以及最佳 取决于什么。
- 解释为什么”参数空间中的一小步”可能是”策略空间中的一大步”,以及大步长的危险。
- 陈述并理解性能差异引理;写出替代目标,解释它何时准确、何时不准。
- 理解 TRPO 的单调改进思想、KL 约束和自然梯度。
- 写出 PPO 的裁剪目标,解释 min 与 clip 各自的作用。
- 用 PyTorch 实现 PPO,理解它的主要实现细节,并会用 approx KL、裁剪比例等指标诊断训练。
0.3 先修知识
| 知识点 | 用在哪里 | 最低要求 |
|---|---|---|
| 第 3 讲:TD 误差、 步回报、TD(λ) | 第 1–3 节 | 必须 |
| 第 6 讲:策略梯度定理、REINFORCE、基线、优势函数 | 全讲 | 必须 |
| 第 2 讲:策略改进定理 | 第 4 节 | 理解即可 |
| KL 散度 | 第 5–7 节 | 知道它衡量”两个分布差多远”,≥ 0,且不对称 |
| 泰勒展开(一阶、二阶) | 第 6 节 | 知道 |
0.4 本讲地图
第1节 Actor-Critic:用 TD 误差给动作打分
│
第2节 实验:Actor-Critic vs REINFORCE(方差、步长、局部最优)
│
第3节 GAE:用 λ 调节偏差与方差
│
第4节 步长问题:参数空间 ≠ 策略空间;一次坏更新的代价
│
第5节 性能差异引理与替代目标
│
第6节 TRPO:单调改进、KL 约束、自然梯度
│
第7节 PPO:裁剪目标
│
第8节 PPO 实现与消融实验
│
第9节 全景:策略梯度家族
0.5 本讲的实验平台
除了 PPO 在 CartPole 上的实验,本讲的前三个代码文件都使用同一个小问题(chain_mdp.py):
[+1 终点] ← 0 — 1 — 2 — [3] — 4 — 5 — 6 → [+10 终点] 每步 -0.5,80% 按意图移动,γ = 0.95
7 个状态、表格型 softmax 策略(14 个参数)。它小到可以精确算出 、、、、状态访问量 和精确的策略梯度——于是每个估计量的偏差和方差都可以直接测量。均匀随机策略的 ,最优策略(一直向右),局部最优”一直向左”。
1. Actor-Critic:用 TD 误差给动作打分
1.1 回顾:策略梯度需要什么?
策略梯度定理(第 6 讲 5.2 节):
其中 是”动作 有多好”的某种估计。第 6 讲给出了几种选择:
| 名字 | 偏差 | 方差 | |
|---|---|---|---|
| 整条回报 | 无偏 | 最大 | |
| 未来回报(REINFORCE) | 无偏 | 大 | |
| 带基线的 REINFORCE | 无偏 | 较大 | |
| 动作价值 | 无偏(若 精确) | 较小 | |
| 优势 | 无偏(若 精确) | 最小 |
后两者需要知道 或 ——我们不知道,但可以学。
1.2 Actor 与 Critic
Actor-Critic 同时学习两个东西:
- Actor(演员):策略 ,负责”做”;
- Critic(评论家):价值函数 (或 ),负责”评”——告诉 Actor 刚才的动作比预期好还是差。
┌────────────── 状态 s ──────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Actor π_θ │── 动作 a ──► 环境 ──►│ Critic V_w │
└───────────────┘ │ └───────────────┘
▲ ▼ r, s' │
└───────── TD 误差 δ = r + γV(s') - V(s) ─┘
(Actor 用 δ 更新策略;Critic 用 δ 更新自己)
1.3 TD 误差是优势的无偏估计
用 TD 误差 作为 。如果 Critic 是精确的():
(第一步用了 的贝尔曼方程:。)
所以 TD 误差是优势函数的无偏估计——前提是 Critic 精确。实际中 Critic 不精确, 就有偏差。这和第 3 讲”TD 有偏但方差小”完全一样:用偏差换方差。
1.4 一步 Actor-Critic 算法
算法:一步 Actor-Critic(Sutton & Barto 13.5 节)
初始化 θ、w
对每个回合:
s ← 初始状态,I ← 1
直到回合结束:
a ~ π_θ(·|s);执行 a,观察 r, s'
δ ← r + γ V_w(s') - V_w(s) (s' 为终止状态时 V_w(s') = 0)
w ← w + α_w δ ∇_w V_w(s) (Critic:半梯度 TD(0),第 5 讲)
θ ← θ + α_θ I δ ∇_θ log π_θ(a|s) (Actor:策略梯度,用 δ 代替 G_t - V(s))
I ← γ I;s ← s'
与 REINFORCE 相比:每走一步就能更新,不用等回合结束,也能用于持续型任务。
2. 实验:Actor-Critic vs REINFORCE
2.1 步长与局部最优
在链条问题上,从均匀随机策略出发,训练 300 个回合,每个设置用 30 个种子。表中是最终 的平均值,括号里是陷入”一直向左”局部最优()的种子数(代码 01_actor_critic.py 演示 1):
REINFORCE + 基线:
| \ | 0.05 | 0.1 | 0.2 | 0.4 | 0.8 |
|---|---|---|---|---|---|
| 0.1 | 5.54 (1) | 5.60 (1) | 5.38 (2) | 4.67 (5) | 4.07 (4) |
| 0.3 | 5.78 (0) | 5.84 (0) | 5.63 (1) | 4.92 (4) | 4.92 (4) |
一步 Actor-Critic:
| \ | 0.05 | 0.1 | 0.2 | 0.4 | 0.8 |
|---|---|---|---|---|---|
| 0.1 | 5.80 (0) | 5.85 (0) | 5.88 (0) | 5.89 (0) | 5.17 (3) |
| 0.3 | 5.79 (0) | 5.84 (0) | 5.88 (0) | 5.65 (1) | 5.17 (3) |
解读:
- REINFORCE 的步长稍大,就有越来越多的种子陷入局部最优:梯度估计方差大,早期几次”向左碰巧不错”的回合就可能把策略推向左边;一旦几乎总是向左,就再也看不到右边的 +10,永远困在那里。
- Actor-Critic 能承受大得多的步长( 时 30 个种子无一失败)——方差小带来的直接好处。
- 一个方法论上的提醒:我最初只用 8 个种子调步长,REINFORCE 碰巧一个失败都没遇到,于是”最佳步长”选成了 0.4——实际上那是一个危险的步长。调参和比较算法都需要足够多的种子。
2.2 学习曲线
各自最佳步长下,30 个新种子的平均精确 :
| 方法 | 第 10 回合 | 第 25 回合 | 第 50 回合 | 第 100 回合 | 第 200 回合 | 第 300 回合 |
|---|---|---|---|---|---|---|
| REINFORCE + 基线 | 3.16 | 4.79 | 5.49 | 5.71 | 5.80 | 5.84 |
| 一步 Actor-Critic | 1.61 | 4.72 | 5.75 | 5.84 | 5.88 | 5.90 |
前 10 个回合 REINFORCE 反而更快:Critic 从 0 开始,一开始很不准,TD 误差带有很大的偏差——这就是 Actor-Critic 的代价。Critic 变准之后,Actor-Critic 在第 50 回合左右反超,最终也更接近最优。
2.3 Critic 学到了什么?
训练结束后(演示 3):
| 状态 0 | 1 | 2 | 3(起点) | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|---|
| 0.044 | 0.205 | 0.870 | 1.000 | 0.996 | 0.999 | 0.998 | |
| Critic 的 | −0.30 | −1.40 | −1.37 | 6.13 | 7.01 | 8.05 | 9.34 |
| 真实的 | 0.35 | 0.46 | 4.25 | 5.89 | 6.94 | 8.06 | 9.25 |
| 访问量 | 0 | 0 | 0 | 1.24 | 1.16 | 1.09 | 1.02 |
起点及其右边(常访问的状态)Critic 估计得很准,策略几乎确定地向右;起点左边的状态现在几乎不会被访问(),那里的 Critic 和策略都学得不充分——但这些状态对 几乎没有影响。策略梯度只在”会去的地方”优化(策略梯度定理中的 权重)。
3. 广义优势估计(GAE)
3.1 从一步到 步
只看一步,偏差大(依赖 Critic); 看到底,方差大。第 3 讲的 步回报给出了中间选择:
最后一个等号是因为中间的 项两两抵消(望远镜求和):, 被消掉了。
时,。
3.2 GAE:对所有 做几何加权平均
和第 3 讲的 TD(λ) 一样,与其挑一个 ,不如把所有 步估计按 加权平均(Schulman et al., 2016):
第二个等号:把 代入,交换求和顺序, 出现在所有 的项中,系数为 。
两个特例:
| 性质 | ||
|---|---|---|
| 0 | 一步 Actor-Critic:方差小,Critic 不准时偏差大 | |
| 1 | REINFORCE + 基线:无偏( 只是基线),方差大 |
高效计算:和”从后往前算回报”一样,有递推 ,从回合末尾往前扫一遍即可,。
代码验证:
02_gae.py演示 1 用两种完全不同的算法(递推公式、按 λ-回报定义逐项求和)计算同一条轨迹的 GAE,最大差异在 量级;并验证了 时 。
3.3 实验:偏差与方差
在链条问题上固定一个策略,用 20000 个回合测量梯度估计 的偏差(与精确梯度的距离)和方差(代码 02 演示 2):
| Critic 精确:偏差 | Critic 精确:方差 | Critic 有系统误差:偏差 | Critic 有系统误差:方差 | |
|---|---|---|---|---|
| 0.00 | 0.024 | 12.97 | 0.973 | 82.12 |
| 0.50 | 0.022 | 10.90 | 0.671 | 49.40 |
| 0.80 | 0.028 | 16.90 | 0.337 | 46.73 |
| 0.90 | 0.038 | 27.09 | 0.180 | 54.86 |
| 0.95 | 0.048 | 39.31 | 0.099 | 66.01 |
| 1.00 | 0.065 | 67.76 | 0.081 | 92.96 |
(“有系统误差”指 。偏差的测量本身有约 0.01~0.07 的随机误差。)
- 偏差:Critic 精确时,所有 都几乎无偏;Critic 有误差时, 越小偏差越大(越依赖 ), 仍然无偏。
- 方差: 从 0.5 到 1,方差明显增大。但并非严格单调: 的方差比 还大——每个 本身就带噪声,而且 Critic 不准时 的波动会被放大(第二列 82.12)。” 越小方差越小”只是一个粗略的经验法则,不是定理。
3.4 最佳的 取决于什么?
用 个回合平均得到梯度估计时,均方误差 (代码 02 演示 3):
| 批大小 | Critic 精确时的最佳 | Critic 有误差时的最佳 |
|---|---|---|
| 1 | 0.5 | 0.8 |
| 10 | 0.5 | 0.8 |
| 100 | 0.5 | 0.9 |
| 1000 | 0.5 | 0.95 |
- Critic 精确时没有偏差,最佳 只由方差决定,与数据量无关。
- Critic 越不准、数据越多,越应该选大 (少依赖 Critic):数据多时方差被平均掉了,剩下的偏差成了主要误差。
- 实践中常用 左右。
4. 步长问题
4.1 参数空间 ≠ 策略空间
梯度下降在参数空间里迈步:。但我们关心的是策略变了多少。同样大小的参数变化:
- 在 softmax 的”平坦区”(偏好差距小,概率接近均匀),可能只让策略变化一点点;
- 在”陡峭区”,可能让某个动作的概率从 0.5 变成 0.99。
一个固定的学习率 ,在某些地方太保守,在另一些地方太激进。
4.2 一次坏更新的代价
在监督学习中,一次不好的梯度步只会让损失暂时变高,下一批数据会把它拉回来。在 RL 中不是这样:策略变差 → 收集到的数据变差(比如再也看不到好的区域)→ 基于差数据的更新更差……可能再也恢复不过来。第 6 讲短走廊的设置 C、本讲 2.1 节 REINFORCE 陷入局部最优,都是这种情况。
实验(代码 03_trust_region.py 演示 3):在链条问题上,用少量回合估计梯度(带噪声),沿估计的方向走不同的步长(参数空间中的距离),每种设置重复 300 次,测量真实的 变化:
| 每批回合数 | 步长 | 平均改进 | 变差的概率 | 最坏情况 |
|---|---|---|---|---|
| 2 | 0.3 | +0.64 | 1.7% | −0.74 |
| 2 | 3 | +3.10 | 15.3% | −4.35 |
| 2 | 30 | +0.71 | 43.0% | −8.43 |
| 10 | 0.3 | +0.97 | 0.0% | +0.47 |
| 10 | 3 | +5.28 | 1.3% | −1.33 |
| 10 | 30 | +5.46 | 13.3% | −8.43 |
的下界是 :策略变成在中间确定性地来回走、永远到不了终点。步子越大,越可能变差,而且最坏情况是灾难性的;梯度越不准(数据越少),大步子越危险。
我们需要一种”保证每一步都不会让策略变差”的更新方式。
5. 性能差异引理与替代目标
5.1 性能差异引理
引理(Kakade & Langford, 2002):对任意两个策略 和 , 其中 是新策略的折扣访问量。
证明(望远镜求和):,所以
第一项是 ;第二项是望远镜求和,只剩下 。
直觉:新策略比旧策略好多少 = 沿着新策略实际走过的每一步,“按旧策略的标准”它平均多拿了多少优势。
代码验证:03 文件演示 1,三个随机的新策略,真实的 与引理右边完全相等(例如 −0.4652 与 −0.4652、−5.2459 与 −5.2459)。
与第 2 讲的联系:如果 对 贪心,那么每个状态上 ,所以 ——这正是策略改进定理。性能差异引理是它的”精确版”。
5.2 替代目标
问题在于:引理的右边需要新策略的访问量 ,要算它就得用新策略去交互——而我们正是想在交互之前就知道新策略好不好。
替代目标(surrogate objective):把 换成旧策略的 :
它可以用旧策略收集的数据估计。用重要性采样把”对 的动作求期望”改写成”对 的动作求期望”:
所以
这就是 TRPO 和 PPO 优化的目标。 的数据可以反复用来评估不同的 ,这解决了”样本效率低”的问题。
替代目标准不准? 在 处, 与 的值相等、梯度也相等(对 求导,得到的恰好是策略梯度定理)。所以 离 近时它很准,离得远就不准了。
实验(03 文件演示 2):沿精确梯度方向走不同步长:
| 参数步长 | 平均 KL | 真实改进 | 替代目标预测 | 预测误差 |
|---|---|---|---|---|
| 0.1 | 0.0004 | +0.388 | +0.386 | −0.002 |
| 0.3 | 0.0039 | +1.155 | +1.146 | −0.009 |
| 1 | 0.042 | +3.456 | +3.602 | +0.146 |
| 3 | 0.318 | +6.407 | +7.955 | +1.548 |
| 10 | 1.810 | +7.462 | +10.398 | +2.935 |
KL 小时替代目标几乎完全准确;步子大时它严重高估了改进。在替代目标上”大胆优化”,得到的承诺并不兑现。
6. TRPO:信赖域策略优化
6.1 单调改进保证
TRPO(Schulman et al., 2015)的理论基础是一个下界:
这个下界意味着什么? 设 。
- 在 处,(KL 为 0);
- 对任何 ,。
所以如果选 ,就有 ——每一步都保证不变差。这叫**“最小化–最大化”(MM)算法**:每一步最大化一个”处处在真实目标之下、且在当前点与真实目标相切”的下界。
6.2 实用的 TRPO
理论中的 太大,按它走的步子极小。TRPO 在实践中改用约束形式,并把”最大 KL”换成”平均 KL”:
“只在 KL 距离 以内(信赖域)优化替代目标”——因为只有在这个范围内,替代目标才可信(5.2 节的表)。
6.3 自然梯度
怎么解这个带约束的问题?在 附近做泰勒展开:
- 目标的一阶近似:( 就是策略梯度);
- KL 约束的二阶近似:,其中 是 Fisher 信息矩阵(KL 在 处的 Hessian)。
用拉格朗日乘子法解得:
方向 叫自然梯度(Kakade, 2001)。它衡量的是”策略空间中的距离”而不是”参数空间中的距离”:在同样的 KL 预算下,找改进最快的方向。
一个优美的特例:对表格型 softmax,自然梯度方向恰好就是优势函数 (乘以一个常数)!
代码验证:03 文件演示 4 计算了 Fisher 矩阵的伪逆乘以梯度,每个状态上它与 的比值都是 9.812,恰好等于 。
也就是说,自然梯度 = “在每个状态按优势的大小提高好动作的偏好”,与状态被访问的频率无关——这正是一种”软”的策略迭代。普通梯度则被 加权,很少访问的状态几乎不更新。
在同样的 KL 预算下比较真实改进(演示 4):
| KL 预算 | 普通梯度 | 自然梯度 |
|---|---|---|
| 0.001 | +0.586 | +0.638 |
| 0.01 | +1.818 | +1.902 |
| 0.05 | +3.698 | +3.689 |
KL 预算小时(信赖域的典型用法),自然梯度改进更多;预算大时两者差不多——自然梯度只在”KL 的二阶近似”成立的局部范围内最优。
6.4 TRPO 的实现
神经网络有几万个参数, 是几万 × 几万的矩阵,没法直接求逆。TRPO 的做法:
- 用共轭梯度法近似求解 (只需要计算 这样的矩阵–向量乘积,不需要存储 );
- 沿 方向按上面的公式确定步长;
- 线搜索:检查实际的 KL 和替代目标改进,不满足就把步长减半,直到满足为止。
TRPO 效果很好,但实现复杂(二阶优化、共轭梯度、线搜索),也不方便与共享参数的网络结构、dropout 等配合。这催生了 PPO。
7. PPO:近端策略优化
7.1 思路:用一阶方法近似信赖域
PPO(Schulman et al., 2017)的目标:保留 TRPO”不要走太远”的精神,但只用普通的一阶梯度下降(Adam)就能实现。
有两种变体:
- PPO-Penalty:把 KL 约束改成惩罚项 ,并根据实际 KL 自适应地调整 ;
- PPO-Clip(最常用):直接裁剪概率比。
7.2 裁剪目标
设概率比 。PPO-Clip 的目标:
通常 。
逐项理解(03 文件演示 5 的表格,):
| 概率比 | : | 裁剪后 | PPO 目标 | : | 裁剪后 | PPO 目标 |
|---|---|---|---|---|---|---|
| 0.5 | +0.50 | +0.80 | +0.50 | −0.50 | −0.80 | −0.80 |
| 0.8 | +0.80 | +0.80 | +0.80 | −0.80 | −0.80 | −0.80 |
| 1.0 | +1.00 | +1.00 | +1.00 | −1.00 | −1.00 | −1.00 |
| 1.2 | +1.20 | +1.20 | +1.20 | −1.20 | −1.20 | −1.20 |
| 1.5 | +1.50 | +1.20 | +1.20 | −1.50 | −1.20 | −1.50 |
| 2.0 | +2.00 | +1.20 | +1.20 | −2.00 | −1.20 | −2.00 |
- (好动作):我们想提高它的概率(增大 )。但 超过 以后,目标不再增加(平了),梯度为 0——“已经提高得够多了,这批数据上别再推了”。
- (坏动作):我们想降低它的概率(减小 )。 低于 以后,目标同样不再变化。
- 取 min 的作用:得到一个”悲观”的下界。如果某次更新朝错误的方向走了(比如 但 变小到 0.5,或 但 变大到 1.5),min 会选择未裁剪的那一项,梯度仍然存在,错误会被纠正——裁剪只阻止”好的方向走太远”,不阻止”纠正坏的方向”。
7.3 为什么能多轮更新?
有了裁剪,同一批数据就可以安全地做很多轮(epochs)小批量梯度更新:一旦某个样本的概率比超出 且方向正确,它就不再贡献梯度,策略不会被这批数据”推”得太远。这大大提高了样本效率。
注意:裁剪只是一种启发式,并不严格保证 KL 很小(多轮更新后,概率比仍可能偏离很多)。所以实践中常常监控近似 KL,超过阈值就提前停止本批数据的更新。
7.4 完整的 PPO 算法
算法:PPO-Clip(Actor-Critic 形式)
初始化策略网络 π_θ、价值网络 V_φ
重复:
1. 用当前策略 π_θ 与环境交互 N 步,记录 (s, a, r, log π_old(a|s), V(s), done)
2. 用 GAE(γ, λ) 计算优势 Â_t,回报目标 R_t = Â_t + V(s_t)
3. 重复 K 轮:
把 N 条数据随机打乱,分成大小为 M 的小批量;对每个小批量:
r_t = exp(log π_θ(a_t|s_t) - log π_old(a_t|s_t))
L = -mean(min(r_t Â_t, clip(r_t, 1-ε, 1+ε) Â_t))
+ c_v · mean((V_φ(s_t) - R_t)²)
- c_e · mean(熵 H[π_θ(·|s_t)])
对 L 做一步梯度下降(梯度裁剪)
8. PPO 实现与消融实验
8.1 实现细节
04_ppo_cartpole.py 使用了以下常见细节(参考 Huang et al. 的博客 The 37 Implementation Details of PPO):
| 细节 | 作用 |
|---|---|
| 每批 2048 步,10 轮,小批量 64 | 标准配置 |
| GAE,, | 第 3 节 |
| 终止 vs 截断 | 真正终止时下一状态价值为 0;时间截断时继续用 自举;两种情况下 GAE 递推都要在回合边界”断开” |
| 小批量内优势标准化 | 统一尺度(第 6 讲 8.3 节) |
| 正交初始化;策略最后一层用很小的尺度 | 初始策略接近均匀随机,充分探索 |
| 梯度范数裁剪 0.5 | 防止偶尔的大梯度 |
| Adam,学习率 3e-4 | |
| 监控 approx KL 与裁剪比例 | 诊断更新是否”走得太远” |
两个诊断指标:
- approx KL :每批更新后新旧策略的差异。健康的 PPO 训练通常在 0.01 左右。
- 裁剪比例:概率比超出 的样本比例。通常在 0.05~0.2 之间。
8.2 标准 PPO 的训练过程
CartPole-v1,种子 0:
| 步数 | 最近 10 回合训练回报 | 贪心评估回报 | approx KL | 裁剪比例 |
|---|---|---|---|---|
| 10,240 | 89.2 | 293.4 | 0.0068 | 0.073 |
| 20,480 | 335.6 | 500.0 | 0.0024 | 0.017 |
| 40,960 | 500.0 | 500.0 | 0.0043 | 0.031 |
| 98,304 | 500.0 | 500.0 | 0.0028 | 0.022 |
约 4 万步就稳定达到满分,整个训练过程中 approx KL 最大只有 0.011。
8.3 消融实验
每种设置 3 个种子,训练 10 万步(约 49 次更新)。“首次达到”指最近 10 个训练回合的平均回报 ≥ 475:
| 设置 | 首次达到 475 的步数 | 最终训练回报 | 达到之后的最低回报 | 最大 approx KL |
|---|---|---|---|---|
| PPO(默认) | 36.9k, 32.8k, 30.7k | 500, 500, 500 | 500, 483, 500 | 0.011~0.016 |
| 去掉裁剪(仍然 10 轮) | 32.8k, 51.2k, 20.5k | 394, 206, 500 | 29.8, 60.9, 9.6 | 2.7~5.95 |
| 每批只更新 1 轮 | 未达到 | 306, 401, 298 | — | 0.005~0.008 |
| 去掉裁剪 + 只更新 1 轮 | 未达到 | 392, 449, 342 | — | 0.003~0.013 |
| GAE | 38.9k, 36.9k, 38.9k | 500, 500, 500 | 477, 476, 412 | 0.012~0.014 |
| GAE | 98.3k, 未达到, 未达到 | 483, 139, 101 | — | 0.20~0.40 |
解读:
- 去掉裁剪:同一批数据做 10 轮更新,没有任何保护,approx KL 冲到 2.7~6(是 PPO 的几百倍)。它有时学得很快,但会反复崩溃——达到高分之后,训练回报掉到 10~60。这正是第 4 节”一次坏更新”的真实写照。
- 只更新 1 轮:很稳定(KL 很小),但样本效率低,10 万步内没能解决问题。此时去不去掉裁剪几乎没区别——只更新一轮时,概率比几乎不会偏离 1,裁剪本来就很少起作用。裁剪的价值,在于让”多轮复用数据”变得安全。
- (MC 优势)在 CartPole 上表现与默认相当——这个问题的回合较短、奖励简单,方差不是主要矛盾。
- (完全依赖 Critic 的一步 TD 优势)大多失败,而且 approx KL 高达 0.2~0.4:训练早期 Critic 很不准,优势估计的偏差很大,策略被带向错误的方向。这印证了第 3 节的结论:Critic 不准时应当选大 。
9. 全景:策略梯度家族
REINFORCE(1992) ← 第 6 讲:MC 回报,高方差
│ + 基线 / Critic
▼
Actor-Critic(1983 / 2000) ← 本讲第 1 节:TD 误差,低方差、有偏
│ + n 步 / GAE(2016) ← 本讲第 3 节
│ + 并行采样
▼
A2C / A3C(2016) ← 多个环境并行收集数据,同步 / 异步更新
│ + 信赖域
▼
TRPO(2015) ← 本讲第 6 节:KL 约束,自然梯度,单调改进
│ 一阶近似
▼
PPO(2017) ← 本讲第 7 节:裁剪,多轮小批量更新
│
▼
RLHF 中的 PPO(2022)、GRPO(2024) ← 第 9、16 讲
另一个分支:异策略 Actor-Critic。对连续动作的控制问题,还有一族基于”确定性策略梯度”和经验回放的异策略方法:DDPG(2016)、TD3(2018)、SAC(2018,最大熵 RL)。它们的样本效率通常比 PPO 高,但对超参数更敏感。本课程不展开,感兴趣可以阅读 OpenAI Spinning Up 的相关章节。
10. 本讲总结
10.1 核心概念清单
- Actor-Critic:Actor(策略)+ Critic(价值);用 TD 误差 代替 ; 时 。
- 偏差换方差:Actor-Critic 能承受更大的步长、更少陷入局部最优;代价是 Critic 不准时的偏差。
- GAE:; 为一步 TD, 为 MC;Critic 越不准、数据越多,应当选越大的 。
- 步长问题:参数空间的距离 ≠ 策略空间的距离;RL 中一次坏更新可能不可逆。
- 性能差异引理:。
- 替代目标:用 代替 ,可以用旧数据估计;在 处值和梯度都与 相等;KL 大时严重高估。
- TRPO:在 KL 信赖域内最大化替代目标;理论上单调改进;实现用自然梯度 + 共轭梯度 + 线搜索。
- 自然梯度 :策略空间中的最速上升方向;表格型 softmax 时正比于优势函数。
- PPO-Clip:;让同一批数据的多轮更新变得安全。
- 诊断:approx KL、裁剪比例;终止 vs 截断;多种子。
10.2 公式速查表
| 名称 | 公式 |
|---|---|
| TD 误差 | |
| TD 误差是优势的无偏估计 | (当 ) |
| Actor 更新 | |
| Critic 更新 | |
| 步优势 | |
| GAE | ,递推 |
| 性能差异引理 | |
| 替代目标 | |
| 重要性采样形式 | |
| TRPO 下界 | |
| TRPO | s.t. |
| Fisher 信息矩阵 | |
| 自然梯度步 | |
| PPO-Clip | |
| 近似 KL |
10.3 中英术语对照表
| 中文 | 英文 | 中文 | 英文 |
|---|---|---|---|
| 执行者–评论者 | Actor-Critic | 优势函数 | Advantage function |
| TD 误差 | TD error | 广义优势估计 | Generalized Advantage Estimation (GAE) |
| 望远镜求和 | Telescoping sum | 性能差异引理 | Performance difference lemma |
| 替代目标 | Surrogate objective | 重要性采样 | Importance sampling |
| 概率比 | Probability ratio | 信赖域 | Trust region |
| 信赖域策略优化 | Trust Region Policy Optimization (TRPO) | 近端策略优化 | Proximal Policy Optimization (PPO) |
| 单调改进 | Monotonic improvement | 最小化–最大化算法 | Minorize-Maximization (MM) |
| KL 散度 | Kullback–Leibler divergence | Fisher 信息矩阵 | Fisher information matrix |
| 自然梯度 | Natural gradient | 共轭梯度 | Conjugate gradient |
| 线搜索 | Line search | 裁剪 | Clipping |
| 熵奖励 | Entropy bonus | 正交初始化 | Orthogonal initialization |
| 近似 KL | Approximate KL | 裁剪比例 | Clip fraction |
| 优势演员–评论家 | Advantage Actor-Critic (A2C) | 异步优势演员–评论家 | A3C |
11. 练习题
练习 1(TD 误差):Critic 给出 ,,执行动作后得到 ,。(a) 计算 TD 误差 ;(b) Actor 会提高还是降低刚才那个动作的概率?(c) 如果 Critic 高估了 ,会对 Actor 产生什么影响?
参考答案
(a) 。 (b) ,提高该动作的概率。 (c) 被高估会让 偏大,Actor 会过度偏爱”走到 “的动作——这就是 Actor-Critic 的偏差来源。
练习 2(GAE 递推):一个 3 步的回合,TD 误差依次为 ,,,。分别计算 、、 时的 。
参考答案
。 :1;:;:。 (用递推:,,,结果相同。)
练习 3(望远镜求和):证明 。
参考答案
。第二个和式中相邻项相互抵消,只剩 。
练习 4(性能差异引理):用性能差异引理证明第 2 讲的策略改进定理:若 ,则 。
参考答案
在每个状态选 ,所以 。由引理,。
练习 5(替代目标的梯度):证明在 处, 等于策略梯度 。
参考答案
。在 处,这就是 。又因为 ,可以把 换成 ,得到策略梯度定理的形式。
练习 6(PPO 裁剪):,某样本 。分别求 、、 时 PPO 目标的值,以及目标对 的导数。
参考答案
:,裁剪后 ,取 min 得 (裁剪项,导数为 0——坏动作的概率已经降得够多了)。 :,导数为 。 :,裁剪后 ,取 min 得 (未裁剪项,导数为 ——坏动作的概率反而上升了,必须纠正)。
练习 7(动手)★:运行 04_ppo_cartpole.py --no-clip,观察 approx KL 一列,并与默认设置对比。然后运行 --no-clip --epochs 1。解释为什么后者的 KL 很小、训练也比较稳定。
参考答案
不裁剪、10 轮时,同一批数据被反复”推”,概率比可以偏离 1 很远,approx KL 会达到 1 以上(讲义 8.3 节表中为 2.7~6),伴随训练回报的剧烈崩溃。只更新 1 轮时,每批数据只贡献一步梯度,策略的变化本来就小,不需要裁剪也很稳定,但样本效率低、学得慢。这说明裁剪的主要作用是让多轮复用数据变得安全。
练习 8(思考题):PPO 的裁剪并不严格保证 KL 很小。设计一个”提前停止”机制:当一批数据的更新过程中 approx KL 超过某个阈值时,就停止这批数据剩下的更新轮次。这个机制和 TRPO 的线搜索有什么相似之处?
参考答案
在 ppo_update 的每个小批量(或每一轮)之后计算 approx KL,若超过阈值(如 0.015~0.03)就 break 跳出剩下的轮次。它与 TRPO 的线搜索都是”事后检查实际的策略变化量,超出信赖域就收手”——一个是逐步缩小步长直到满足约束,一个是停止继续前进。Stable-Baselines3 等库中的 target_kl 参数就是这个机制。
12. 延伸阅读
- Sutton & Barto,Reinforcement Learning: An Introduction(第 2 版):第 13.5 节(Actor-Critic)、第 12 章(资格迹与 λ-回报)。
- CS234 Spring 2024 Lecture 6–7 录像与课件。
- Schulman et al. (2016),High-Dimensional Continuous Control Using Generalized Advantage Estimation:GAE。
- Kakade & Langford (2002),Approximately Optimal Approximate Reinforcement Learning:性能差异引理与保守策略迭代。
- Kakade (2001),A Natural Policy Gradient:自然策略梯度。
- Schulman et al. (2015),Trust Region Policy Optimization:TRPO。
- Schulman et al. (2017),Proximal Policy Optimization Algorithms:PPO。
- Huang et al. (2022),The 37 Implementation Details of Proximal Policy Optimization(ICLR 博客):PPO 实现细节的权威整理。
- OpenAI Spinning Up:VPG、TRPO、PPO、DDPG、TD3、SAC 的讲解与实现。
13. 下一讲预告
到目前为止,所有算法都依赖一个奖励函数——智能体通过试错来最大化它。但很多时候:
- 奖励很难写:怎么用一个数字描述”开车开得好”?(第 1 讲、第 2 讲都看到了奖励设计的陷阱。)
- 试错很危险:自动驾驶、手术机器人不能靠撞车来学习。
- 但有专家可以示范:人类司机开了几百万公里。
下一讲是模仿学习:直接从专家的示范中学习。你会看到:
- 行为克隆:把模仿当作监督学习——简单,但会遭遇”复合误差”;
- DAgger:让专家标注学生自己会遇到的状态,打破分布偏移;
- 逆强化学习:从行为反推奖励,以及最大熵逆强化学习;
- 为什么”分布偏移”是贯穿后面几讲(模仿学习、RLHF、离线 RL)的共同主题。
下一讲之前,建议你:跑通 code/lecture07/ 下的所有脚本(先运行 python chain_mdp.py),完成练习 2、4、6,并尝试练习 7 的消融实验。