Actor-Critic: A2C 与 A3C 本节摘要:REINFORCE 太吵了。加一个学 的 critic,从回报里减掉它,你得到一个期望不变、方差大降的优势(Advantage)——这就是 Actor-Critic。本节讲透它的双网结构:actor 用策略梯度训,critic 用 MSE 回归训;两种优势形式(MC 优势无偏高方差、TD 残差有偏低方差);以及如何用 n 步优势与广义优势估计 GAE( )在两者间插值——λ=0.95 是 2026 年默认。然后是 A2C(同步、跨环境批处理)与 A3C(异步、多线程)的取舍:2026 年 GPU 批处理 A2C 因显卡偏好大 batch 而占主导。你会看到合体损失 ——这是 PPO、IMPALA、GRPO 的共同骨架。
本节摘要:REINFORCE 太吵了。加一个学
V̂(s)的 critic,从回报里减掉它,你得到一个期望不变、方差大降的优势(Advantage)——这就是 Actor-Critic。本节讲透它的双网结构:actorπ_θ(a|s)用策略梯度训,criticV_φ(s)用 MSE 回归训;两种优势形式(MC 优势无偏高方差、TD 残差有偏低方差);以及如何用 n 步优势与广义优势估计 GAE(A_t^{GAE} = Σ (γλ)^l δ_{t+l})在两者间插值——λ=0.95 是 2026 年默认。然后是 A2C(同步、跨环境批处理)与 A3C(异步、多线程)的取舍:2026 年 GPU 批处理 A2C 因显卡偏好大 batch 而占主导。你会看到合体损失L = -A·log π + c_v(V-G)² - c_e·H(π)——这是 PPO、IMPALA、GRPO 的共同骨架。
对应原课程:Phase 9 · Lesson 07 ·
actor-critic-a2c-a3c(原英文phases/09-reinforcement-learning/07-actor-critic-a2c-a3c/docs/en.md)。
阅读完本节,你应当能够:
G_t - V)、TD 残差(r + γV(s') - V(s))、n 步优势,说明偏差-方差权衡。vanilla REINFORCE 能用,但方差糟糕。蒙特卡洛回报 G_t 在不同回合间可以摆动 10 倍。把这个噪声乘上 ∇ log π 再求平均,产出的梯度估计器要数千回合才能把策略推动 DQN 几次更新就能推动的距离。
方差来自用原始回报。如果你减去一个基线 b(s_t)——任何状态的函数,包括学到的价值——期望不变,方差下降。最实际可用的基线是 V̂(s_t)。于是乘 ∇ log π 的量变成了优势:
A(s, a) = G - V̂(s)
一个动作如果产生了高于均值的回报,就是好的;低于均值,就是坏的。带学到的 critic 的 REINFORCE 就是 Actor-Critic。 critic 给 actor 一个低方差的老师。这是 2015 年后每一个深度策略方法(A2C、A3C、PPO、SAC、IMPALA)的母型。
π_θ(a | s):策略,采样出动作,用策略梯度训练。V_φ(s):估计从状态出发的期望回报,训练以最小化 (V_φ(s) - target)²。A_t = G_t - V_φ(s_t)。无偏,方差较高。A_t = r_{t+1} + γ V_φ(s_{t+1}) - V_φ(s_t)。有偏(用了 V_φ),方差低得多。也叫 TD 残差 δ_t。A_t^{(n)} = r_{t+1} + γ r_{t+2} + … + γ^{n-1} r_{t+n} + γ^n V_φ(s_{t+n}) - V_φ(s_t)
n = 1 是纯 TD,n = ∞ 是 MC。多数实现 Atari 用 n = 5,PPO 在 MuJoCo 上用 n = 2048。
Schulman et al. (2016) 提出对所有 n 步优势做指数加权平均:
A_t^{GAE} = Σ_{l=0}^{∞} (γλ)^l δ_{t+l},λ ∈ [0, 1]
λ = 0 是 TD(低方差高偏差);λ = 1 是 MC(高方差无偏);λ = 0.95 是 2026 年默认——调到你觉得合适的偏差/方差档位。
A2C(同步优势 Actor-Critic):跨 N 个并行环境收集 T 步,为每步算优势,在合并 batch 上更新 actor 与 critic。重复。A3C 的更简单、更可扩展的同胞。
A3C(异步优势 Actor-Critic):Mnih et al. (2016)。起 N 个 worker 线程,每个跑一个环境。每个 worker 在自己的滚动上本地算梯度,然后异步应用到共享参数服务器。无需回放池——worker 靠跑不同轨迹去相关。A3C 证明了 CPU 上能大规模训练。2026 年,基于 GPU 的 A2C(批量并行环境)占主导,因为 GPU 偏好大 batch。
L(θ, φ) = -E[ A_t · log π_θ(a_t | s_t) ] + c_v · E[(V_φ(s_t) - G_t)²] - c_e · E[H(π_θ(·|s_t))]
三项:策略梯度损失、价值回归、熵正则。c_v ~ 0.5、c_e ~ 0.01 是经典起点。
💡 Actor-Critic 的精髓是「用一个网去教另一个网」:critic 把高方差的回报
G压缩成低方差的优势A = G - V(s),actor 据此更新。这与第 09 节 RLHF 里「奖励模型教策略网」是同构的——一个网学评估、一个网学决策,迭代互促。
线性 critic V_φ(s) = w · features(s),用 MSE 更新:
def critic_update(w, x, target, lr): v_hat = dot(w, x) err = target - v_hat for j in range(len(w)): w[j] += lr * err * x[j] return v_hat
表格环境上 critic 几百回合收敛。Atari 上把线性 critic 换成共享 CNN 主干 + 价值头。
给定长度 T 的滚动与自举的末尾 V(s_T):
def compute_advantages(rewards, values, gamma=0.99, lam=0.95, last_value=0.0): advantages = [0.0] * len(rewards) gae = 0.0 for t in reversed(range(len(rewards))): next_v = values[t + 1] if t + 1 < len(values) else last_value delta = rewards[t] + gamma * next_v - values[t] gae = delta + gamma * lam * gae advantages[t] = gae returns = [a + v for a, v in zip(advantages, values)] return advantages, returns
returns 是 critic 的目标,advantages 是乘 ∇ log π 的量。
for step_i, (x, a, _r, probs) in enumerate(traj): adv = advantages[step_i] target_v = returns[step_i] # critic critic_update(w, x, target_v, lr_v) # actor for i in range(N_ACTIONS): grad_logpi = (1.0 if i == a else 0.0) - probs[i] for j in range(N_FEAT): theta[i][j] += lr_a * adv * grad_logpi * x[j]
on-policy,每次更新一滚动,actor 与 critic 用各自学习率。
N 个线程,各跑自己的环境与前向。周期性地把梯度推到共享主网。主网不加锁——竞争没关系,只算噪声。N 个环境实例,把观测堆成 [N, obs_dim] batch,批量前向、批量反向。GPU 利用率更高、确定性、更易推理。2026 年默认。我们的玩具代码为清晰起见单线程;改成批量 A2C 只需三行 numpy。
💡 优势归一化(每 batch 零均值单位方差)是 Actor-Critic 实现里最便宜也最有效的稳定性技巧。它让梯度幅度跨任务一致,几乎零成本就能稳定训练。别跳过它——PPO 文献反复强调这点。
A2C/A3C 在 2026 年很少是最终选择,但它们是后续一切的架构母型:
| 方法 | 与 A2C 的关系 |
|---|---|
| PPO | A2C + 裁剪重要性比率,支持多次 epoch 更新 |
| IMPALA | A3C + V-trace off-policy 修正 |
| SAC(下节) | off-policy A2C + soft-value critic |
| GRPO(第 12 节) | 没有 critic 的 A2C——组相对优势 |
| DPO | 把 A2C 塌缩成偏好排序损失,无需采样 |
| AlphaStar / OpenAI Five | A2C + 联赛训练 + 模仿预训练 |
2026 年论文里看到「优势」,就该想到 Actor-Critic。
stable-baselines3 提供 A2C 算法,默认带 GAE、优势归一化、熵正则、共享主干选项——与本节手写版一一对应。值得做的事:用 SB3 的 A2C 在 CartPole-v1 上跑 100k 步,观察它如何快速收敛;再回头读本节代码,看清每个 trick 在框架里长什么样。SB3 的 PPO 则是本节骨架 + 第 08 节的裁剪目标。
本节产出一个可复用 skill(位于原课程 outputs/skill-actor-critic-trainer.md)。骨架:
--- name: actor-critic-trainer description: 为给定环境产出 A2C / A3C / GAE 配置,明确优势估计与损失权重。 version: 1.0.0 phase: 9 lesson: 7 tags: [rl, actor-critic, gae] --- 给定一个环境与算力预算,输出: 1. 并行度。A2C(GPU 批)vs A3C(CPU 异步),worker 数。 2. 滚动长度 T。每次更新每环境多少步。 3. 优势估计器。n 步或 GAE(λ);给出 λ。 4. 损失权重。c_v(价值)、c_e(熵)、梯度裁剪。 5. 学习率。actor 与 critic(若分开用)。 拒绝在视野 > 1000 的环境上跑单 worker A2C(太 on-policy、太慢)。 拒绝交付没有优势归一化的。 标记任何 c_e=0 且观测熵 < 0.1 的运行为熵塌缩。
G_t - V(s_t))训 Actor-Critic,对比第 06 节带 running-mean 基线 REINFORCE 的样本效率。r + γ V(s') - V(s))。测优势 batch 的方差,降了多少?λ ∈ {0, 0.5, 0.9, 0.95, 1.0}。画最终回报与样本效率。这个任务的偏差/方差甜点在哪?c_e > 0,策略几百次更新内就变近确定性,停止探索。| 术语 | 俗称 | 实际含义 |
|---|---|---|
| Actor | 「策略网」 | π_θ(a|s),用策略梯度更新 |
| Critic | 「价值网」 | V_φ(s),用对回报 / TD 目标的 MSE 回归更新 |
| 优势 | 「比平均好多少」 | A(s,a) = Q(s,a) - V(s) 或其估计器;乘 ∇ log π 的量 |
| TD 残差 | 「δ」 | δ_t = r + γ V(s') - V(s);单步优势估计 |
| GAE | 「插值旋钮」 | n 步优势的指数加权和,由 λ 参数化 |
| A2C | 「同步 Actor-Critic」 | 跨环境批处理;每滚动一次梯度步 |
| A3C | 「异步 Actor-Critic」 | worker 线程往共享参数服务器推梯度;原论文,2026 年少见 |
| 自举 | 「在视野末用 V」 | 截断滚动,加 γ^n V(s_{t+n}) 闭合求和 |
c_e·H(π)。下一节,我们让 A2C 的数据能被复用多次——PPO 用一个裁剪的重要性比率,把同一份滚动跑 10+ epoch 还不爆,九年后仍是默认算法。