📑 本页目录(点开跳转)
10 · Actor-Critic
⏱ 26 分钟 | ⭐ 把前两章的优点合起来
🎯 一句话
第 8 章学价值(方差小但学不了连续动作), 第 9 章学策略(通用但方差大)。 Actor-Critic 就是:让一个网络演(Actor),另一个网络打分(Critic)—— 用 Critic 的估计去替换策略梯度里那个高方差的回报。
🎭 一、两个角色
Actor(演员):策略网络 π(a|s; θ)
└─ 决定做什么动作
Critic(评论家):价值网络 V(s; w) 或 Q(s,a; w)
└─ 评价这个状态/动作有多好
⭐ Actor 按 Critic 的评价来调整自己
Critic 按实际的奖励来调整自己
📉 二、它到底改了什么
回顾策略梯度(第 9 章):
$$\nabla J(\theta) = \mathbb{E}\big[\nabla\log\pi(a|s;\theta)\cdot \underbrace{G_t}_{\text{整条轨迹的回报}}\big]$$
⚠️ 问题:G_t 是【一整条轨迹】的实际回报
→ 必须等回合结束才能算
→ 方差极大(一次运气好坏影响整条轨迹的所有动作)
Actor-Critic 的替换:
$$\nabla J(\theta) = \mathbb{E}\big[\nabla\log\pi(a|s;\theta)\cdot \underbrace{A(s,a)}_{\text{优势函数}}\big]$$
其中最常用的估计是 TD 误差:
$$A(s,a) \approx \delta = r + \gamma V(s') - V(s)$$
💡 人话翻译:
δ = 「实际拿到的」减去「原本预期的」。 δ > 0 → 这个动作比预期好 → 提高它的概率 δ < 0 → 比预期差 → 降低它的概率
⭐ 三个好处一起来:
① 【每一步就能更新】,不用等回合结束(TD 的好处,第 5 章)
② 【方差大幅降低】(不再依赖整条轨迹的运气)
③ 保留了策略梯度的通用性(连续动作、随机策略都行)
⚠️ 代价:引入了【偏差】——因为 V 只是估计,不是真值
→ 又是偏差-方差的权衡(第 5 章的老朋友)
⭐ 三、优势函数与基线
为什么用"优势"而不是直接用 Q:
Q(s,a) 的绝对大小没有意义 —— 重要的是【相对好坏】
例:所有动作的 Q 都在 1000 左右
用 Q 当权重 → 所有动作的概率都被推高 → 梯度信号被淹没
A(s,a) = Q(s,a) − V(s) ← 减掉"这个状态的平均水平"
→ 只保留【这个动作比平均好多少】⭐
📐 为什么减基线不改变梯度的期望(想看再点)
对任意只依赖状态的函数 $b(s)$:
$$\mathbb{E}_{a\sim\pi}\big[\nabla\log\pi(a|s)\cdot b(s)\big] = b(s)\sum_a \pi(a|s)\frac{\nabla\pi(a|s)}{\pi(a|s)} = b(s)\nabla\sum_a\pi(a|s) = b(s)\nabla 1 = 0$$
⭐ 所以减去任何基线都不引入偏差,却能降低方差。 最优基线接近 $V(s)$ —— 这就是用它的理由。
GAE:在偏差和方差之间调一个旋钮
$$A^{GAE(\lambda)}_t = \sum_{l=0}^{\infty}(\gamma\lambda)^l\delta_{t+l}$$
λ = 0 → A = δ(单步 TD):偏差大、方差小
λ = 1 → A = 蒙特卡洛回报:无偏、方差大
⭐ λ ≈ 0.95 是实践中最常用的折中
🔨 四、最小实现
# 一步 Actor-Critic 的核心
import torch.nn.functional as F
value = critic(state)
next_value = critic(next_state).detach() # ⭐ 目标不回传
td_target = reward + gamma * (1 - done) * next_value
delta = (td_target - value).detach() # ⭐ 优势也要 detach
# Actor:朝"让好动作更可能"的方向走
logp = dist.log_prob(action)
actor_loss = -(logp * delta).mean() # ⭐ 负号:梯度上升
# Critic:把 V 拟合到 TD 目标
critic_loss = F.mse_loss(value, td_target)
loss = actor_loss + 0.5 * critic_loss - 0.01 * entropy # ⭐ 熵奖励鼓励探索
⚠️ 三个必踩的坑: ① 优势忘了
detach()→ 梯度会穿过 Critic 传回来,训练行为变得莫名其妙 ② 两个 loss 的量级差太多 → Critic 的 loss 通常大得多,要乘系数(常用 0.5) ③ 没有熵奖励 → 策略过早收敛到某个动作,探索直接死掉 ⭐
🧬 五、主要变体
| 算法 | 关键点 |
|---|---|
| A2C | 同步版本,多个环境并行采样 → 减小相关性 |
| A3C | 异步多线程(现在基本被 A2C 取代,因为同步版更简单也更稳) |
| PPO ⭐ | 加了"更新幅度限制",第 11 章的主角 |
| DDPG / TD3 | 确定性策略 + off-policy,用于连续控制 |
| SAC ⭐ | 最大熵 RL:目标里显式加入熵项,探索更好、超参更鲁棒 |
💡 SAC 值得记住:它把"熵奖励"从一个 trick 提升成了优化目标的一部分, 在连续控制任务上通常是最稳的选择。
🧭 六、三条路线的对比(这一章的总结)
| 价值方法(DQN) | 策略梯度(REINFORCE) | Actor-Critic | |
|---|---|---|---|
| 学什么 | Q 值 | 策略 | 两个都学 |
| 连续动作 | ❌ 难 | ✅ | ✅ |
| 方差 | 低 | 很高 | 中等 ⭐ |
| 偏差 | 有(自举) | 无 | 有 |
| 更新时机 | 每步 | 回合结束 | 每步 ⭐ |
| 样本效率 | 高(可回放) | 低(on-policy) | 中 |
🔑 一句话记住三者的关系: Actor-Critic 用"有偏但低方差"的 Critic 估计,换掉了策略梯度里"无偏但高方差"的回报。 这是一次典型的偏差-方差交易。
🔗 和站内其他章的关系
| 相关的地方 | 这里的位置 |
|---|---|
| 第 5 章 TD vs MC | 优势估计的 λ 就在调这个 ⭐ |
| 第 9 章 REINFORCE | Actor 部分 |
| 第 8 章 价值网络 | Critic 部分 |
| 第 7 章 探索 | 熵奖励是这里的探索手段 |
| ML 基础第 5 章 偏差方差 | 本章的核心权衡 |
✅ 检查点
- Actor 和 Critic 各负责什么?
- Actor-Critic 把策略梯度里的什么替换掉了?换成了什么?
- TD 误差 δ 的人话含义是什么?
- 这次替换带来三个好处和一个代价,分别是什么?
- 为什么用优势 A 而不是直接用 Q?
- 为什么减去基线不会引入偏差?
- GAE 的 λ 在调什么?常用取值?
- 实现的三个坑是什么?
- 用一句话概括三条路线的关系。
👀 答案
- Actor(策略网络)决定做什么动作;Critic(价值网络)评价状态/动作有多好。Actor 按 Critic 的评价调整,Critic 按实际奖励调整。
- 替换掉了整条轨迹的实际回报 G_t(高方差),换成优势函数 A(s,a),最常用的估计是 TD 误差 δ = r + γV(s') − V(s)。
- 实际拿到的减去原本预期的。δ>0 说明这个动作比预期好 → 提高其概率;δ<0 则降低。
- 好处:①每步就能更新不用等回合结束 ②方差大幅降低 ③保留策略梯度的通用性。代价:引入偏差(V 只是估计)——又是偏差-方差权衡。
- 因为 Q 的绝对大小没有意义,重要的是相对好坏。若所有动作 Q 都在 1000 左右,用 Q 当权重会把所有动作概率都推高、信号被淹没。A = Q − V 只保留"比平均好多少"。
- 因为对任意只依赖状态的 b(s),E[∇logπ·b(s)] = b(s)·∇(Σπ) = b(s)·∇1 = 0。所以减任何基线都不引入偏差,却能降方差。
- 调偏差和方差的折中:λ=0 是单步 TD(偏差大方差小),λ=1 是蒙特卡洛(无偏方差大)。常用 λ≈0.95。
- ①优势忘了 detach()(梯度穿过 Critic 传回)②两个 loss 量级差太多(Critic loss 要乘系数如 0.5)③没有熵奖励(策略过早收敛,探索死掉)。
- Actor-Critic 用"有偏但低方差"的 Critic 估计,换掉了策略梯度里"无偏但高方差"的回报——一次典型的偏差-方差交易。
🛑 可以停在这里
⚡ 走神救援
Actor 演(策略网络 π)、Critic 打分(价值网络 V)。⭐核心改动:把策略梯度里那个高方差的整条轨迹回报 G_t,换成优势函数 A,最常用的估计是 TD 误差 δ = r + γV(s') − V(s);💡人话:实际拿到的减去原本预期的,δ>0 就提高这个动作的概率。三个好处:每步就能更新(不用等回合结束)、方差大幅降低、保留策略梯度的通用性;⚠️代价是引入偏差(V 只是估计)——又是偏差-方差权衡。⭐为什么用优势不用 Q:Q 的绝对大小没意义(所有动作 Q 都是 1000 时信号被淹没),A = Q − V 只保留"比平均好多少";📐减基线不引入偏差因为 E[∇logπ·b(s)] = b(s)·∇1 = 0。GAE 用 λ 在偏差方差间调旋钮(λ=0 单步TD、λ=1 蒙特卡洛,实践常用 0.95),是 PPO 的标配。实现三坑:⚠️优势忘了 detach()、两个 loss 量级差太多(Critic 乘 0.5)、⭐没有熵奖励导致策略过早收敛、探索死掉。变体:A2C/A3C、⭐PPO(加了更新幅度限制)、DDPG/TD3(连续控制)、⭐SAC(把熵奖励从 trick 提升成优化目标的一部分,连续控制上最稳)。⭐一句话总结三条路线:Actor-Critic 用"有偏但低方差"的 Critic 估计,换掉了策略梯度里"无偏但高方差"的回报。
下一节 👉 11-PPO.md ⭐⭐