Actor-CriticActor-Critic & Continuous Actions
第 8 章末尾的 AC 只是一个预告。本章补上真正的 Actor-Critic:Actor 学策略、Critic 学价值,用单步 TD 优势把两者拧成一台低方差的学习机器,并第一次踏入连续动作空间——2D 目标追逐。
REINFORCE+Baseline vs Actor-Critic
当前观看:REINFORCE+Baseline 的 CartPole
两个算法独立训练:RB 每集用完整回报更新(高方差),AC 每步用 TD 优势更新(低方差)。曲线图始终展示两条学习曲线。
🧩 Actor-Critic 架构示意
状态 s 同时喂给 Actor 与 Critic:Actor 输出动作分布(离散概率或连续高斯均值),Critic 输出状态价值。环境的奖励 r 与下一状态 s′ 组合成 TD 优势 δ,同时更新两边。
采样动作 a
估计状态价值
2D 目标追逐 · 连续动作
9.1 演员与评论家:一个行动一个打分
REINFORCE 的梯度像「抽奖」:一条轨迹一个巨大数字,方向对但抖得厉害。Actor-Critic 把决策和评估分成两个角色:演员(Actor)负责出动作,评论家(Critic)负责逐帧打分 —— 单步 TD 优势让每个动作都得到及时、低噪声的反馈。再加上高斯策略,连续动作空间第一次被解锁。
下一步预告:AC 虽然每步更新,但策略更新幅度不受控。下一章 PPO 引入裁剪目标,用「信任区域」让策略更新更稳,成为如今 RLHF 的标准底座。
📌 发生了什么
- Actor 用优势 ∇logπ(a|s)·δ 更新,Critic 用 TD 目标回归价值
- δ = r + γV(s′) − V(s):bootstrap 换来低方差、有偏的更新信号
- 连续动作用高斯策略:网络输出 μ(s),固定 σ 采样,∇logπ = (a−μ)/σ²
- CartPole 上 AC 的学习曲线比 REINFORCE+Baseline 更平稳
⚠️ 常见陷阱
- 把 AC 的价值更新方向写反——V(s) 应回归到 TD 目标,取反会得到「负学习」
- 误以为 σ 是超参数不重要——σ 太大探索过度、太小过早收敛,是连续空间的「ε-greedy」
- 共享网络时把 softmax 应用到含 V 的整条输出上——策略分布会被价值污染
✅ 本章小结
- Actor-Critic = 策略梯度 + 价值基线 + 单步 TD 优势
- TD bootstrap:方差↓ 但有偏,换来每步可更新的样本效率
- 高斯策略让策略梯度自然覆盖连续动作空间
9.2 为什么 TD 优势方差更小
策略梯度定理:∇J(θ) = E[∇logπ(a|s)·A(s,a)]。任何不依赖动作的基线 b(s) 都不改变期望。第 8 章用 V(s) 做基线得到 G − V(s);AC 更进一步——把 G 也换成单步 bootstrap。
MC 回报 G 是对整条轨迹上所有随机奖励求和,噪声随长度累积;TD 误差 δ 只含一步奖励 r 加「被期望过的」V(s′)——bootstrap 用期望代替了后续噪声,方差因此显著下降,代价是 V(s′) 不准时的偏差。
9.3 两条更新线:Actor 与 Critic 共享 δ
两条更新线:Actor 沿 δ·∇logπ 上升(好动作概率升高);Critic 沿 δ 回归价值(V(s) 向 r + γV(s′) 逼近,方向不取反)。δ 是两者的共享桥梁——这就是「Actor-Critic」名称的由来。
9.4 高斯策略:解锁连续动作
连续动作:π(a|s) = N(μ(s), σ²)。网络只输出 μ(s),采样 a ~ μ + σ·N(0,1),且 ∇logπ(a|s) = (a−μ)/σ²——梯度把均值拉向「被 δ 正向加权的采样动作」。σ 固定时实现极简,正是本章演示所用。
9.5 AC 超参对比
AC 的每个旋钮都在方差/偏差/探索之间做权衡。
| 超参 | 表现 | 结果 |
|---|---|---|
| Critic 学习率过高 | V 震荡,TD 目标自身不稳 | 优势失真 |
| σ 太大(如 1.0) | 动作几乎随机,探索过度 | 学习极慢 |
| σ 中等(0.1~0.4) | 探索与利用平衡 | 推荐 |
| Actor 与 Critic 共享网络 | 参数少、特征复用,但两任务可能互相干扰 | 折中(A3C 常用) |
💡 经验法则:Critic 用比 Actor 稍大的学习率,让它更快追上真实价值;σ 从 0.3 起步,训练中后期可逐步调小。
9.6 A2C 核心代码走读
与 REINFORCE 的唯一区别:不用等整集结束,每步都能更新两个网络(Python)。
# Actor π(a|s;θ) 与 Critic V(s;w)
def step(s, a, r, s2, done):
v = value_net(s) # V(s)
v_next = 0 if done else value_net(s2)
target = r + gamma * v_next # TD 目标
delta = target - v # TD 优势
# 1) Actor:沿 δ·∇logπ 上升(离散用 ce 梯度 × δ)
g_policy = ce_grad(policy_net, a) # d(−logπ)/dθ
policy_net.params -= lr_a * delta * g_policy
# 2) Critic:V(s) 回归到 target(方向不取反)
g_value = mse_grad(value_net, target)
value_net.params -= lr_c * g_value
# 连续版本:π(a|s)=N(μ(s),σ²),∇logπ=(a−μ)/σ²
# policy_net 输出 μ;g_policy = (a − mu) / σ²
📚 参考文献与延伸阅读
- Mnih, V. et al. (2016), Asynchronous Methods for Deep Reinforcement Learning, ICML — A3C,A2C 的异步版本与并行加速来源
- Sutton, R. & Barto, A. (2018), Reinforcement Learning: An Introduction, §13.5-13.6 — Actor-Critic 与连续动作的权威教材章节
- Schulman, J. et al. (2017), Proximal Policy Optimization Algorithms, arXiv — PPO,AC 家族的现代继任者
- OpenAI Spinning Up: Kinds of RL Algorithms — AC 家族在现代 RL 中的定位总览
📝 课后练习
检验你的理解——答对为止