SAC
DQN解决了离散问题,于是人们开始着手于解决更加现实的连续控制问题。时至今日,连续控制领域基本被PPO(on-policy)和SAC(off-policy)这两个算法统治,但在早期发展中依然经历了诸多变革。本章以最终形态SAC作为核心,简要整理off-policy路线中最核心的概念。
SAC(Soft Actor-Critic)由Haarnoja等人在2018年提出,是目前连续控制领域最强的off-policy算法之一。它的核心创新是将最大熵(Maximum Entropy)原则引入Actor-Critic框架,使得策略不仅追求高回报,还同时追求高随机性(高熵)。这带来了更好的探索能力、更强的鲁棒性和更平滑的训练过程。
发展历程
SAC所在的off-policy路线的进化链路为:
这里要注意,截至TD3为止,走的是确定性策略梯度(Deterministic Policy Gradient)的路线。SAC本质上和TD3处于不同的理论路线:
- TD3基于deterministic policy gradient
- SAC基于maximum entropy RL
但是现代工程实践中,SAC融合了很多TD3的工程技巧(如Twin Q-networks),构造了一个更加成熟的版本。
DPG - Deterministic Policy Gradient
在标准的策略梯度方法中,策略 \(\pi_\theta(a|s)\) 是一个随机策略(Stochastic Policy)——给定状态 \(s\),它输出一个动作的概率分布,然后从中采样一个动作执行。
2014年,Silver等人提出了确定性策略梯度(Deterministic Policy Gradient, DPG)定理。确定性策略 \(\mu_\theta(s)\) 直接输出一个确定的动作值,不需要采样:
DPG定理证明了,确定性策略的梯度为:
直觉理解: 这个梯度的含义是——先用Q网络告诉我们"在当前状态下,动作往哪个方向调整能提高Q值"(\(\nabla_a Q\)),然后用链式法则告诉策略网络"要改变动作的输出方向,网络参数应该怎么调"(\(\nabla_\theta \mu_\theta\))。
DPG相比随机策略梯度的优势是:不需要对动作空间积分。 随机策略梯度需要对所有可能的动作求期望,在连续高维动作空间中这非常困难。而确定性策略梯度只需要在当前动作点处求梯度,计算效率高得多。
DDPG - Deep Deterministic Policy Gradient
DDPG由Lillicrap等人在2015年提出("Continuous control with deep reinforcement learning"),是将DPG与深度学习结合的产物。可以理解为"连续动作空间版的DQN"。
DDPG的核心组件:
- Actor网络 \(\mu_\theta(s)\): 输入状态,直接输出一个确定性的动作向量
- Critic网络 \(Q_\phi(s, a)\): 输入状态和动作,输出Q值
- Target网络: Actor和Critic各有一个target网络副本,用于稳定训练(和DQN中的Target Network思想完全一致)
- 经验回放(Replay Buffer): 存储 \((s, a, r, s', \text{done})\),随机采样训练
- 探索噪声: 由于确定性策略不具备随机性,需要在动作上手动添加噪声来探索
DDPG的训练逻辑:
- Critic更新: 最小化TD误差,目标值由target网络计算
- Actor更新: 沿着Q值上升的方向调整策略
- Target网络软更新: 不像DQN那样周期性硬拷贝,而是用指数移动平均缓慢更新
其中 \(\tau\) 通常取很小的值,如 \(0.005\)。
DDPG的问题:
- Q值过高估计: 和DQN一样,\(\max\) 操作会导致Q值被系统性高估,但DDPG中这个问题更严重
- 对超参数极其敏感: 学习率、噪声大小、batch size等稍有不当就会训练失败
- 训练极其不稳定: 经常出现策略崩塌,Q值发散
- 脆弱的探索: 高斯噪声的探索方式很原始,在复杂环境中效果差
TD3 - Twin Delayed DDPG
TD3由Fujimoto等人在2018年提出,通过三个简单但有效的技巧来修复DDPG的问题:
技巧1:Twin Q-Networks(双Q网络)
同时训练两个独立的Critic网络 \(Q_{\phi_1}\) 和 \(Q_{\phi_2}\),在计算目标值时取两者中的较小值:
取最小值的思路直接来自Double DQN的启发:既然单个Q网络容易过高估计,那我训练两个独立的Q网络,取它们中较小的那个,就能有效地抑制过估计。这不是完全消除偏差,而是把偏差从"过高"变成了"略微偏低",而略微偏低比过高要安全得多。
技巧2:Delayed Policy Updates(延迟策略更新)
Actor网络的更新频率低于Critic网络。通常Critic每更新两次,Actor才更新一次。
原理是:Actor依赖Critic的Q值来指导更新方向。如果Critic还没训练稳定,Actor就跟着一个不靠谱的"导师"在乱学。所以让Critic先多训练几步,等Q值估计变得更准确后,再更新Actor。
技巧3:Target Policy Smoothing(目标策略平滑)
在计算目标Q值时,给目标策略的动作加上一个截断的噪声:
这相当于对目标Q值做了一个局部平均,防止Critic在某个尖锐的峰值处给出过高的Q值估计。
TD3通过这三个技巧,大幅改善了DDPG的稳定性和性能。SAC在实际实现中直接借用了TD3的Twin Q-Networks技巧。
理论SAC
SAC的理论根基不在确定性策略梯度,而在最大熵强化学习(Maximum Entropy RL)——这是一个完全不同的理论框架。
最大熵强化学习
标准RL的目标:
标准RL只关心一个事情:累积奖励最大化。
最大熵RL的目标: 在最大化累积奖励的同时,还要最大化策略的熵:
其中 \(\alpha > 0\) 是温度系数(Temperature Parameter),控制熵的重要性;\(\mathcal{H}(\pi(\cdot|s_t)) = -\mathbb{E}_{a \sim \pi}[\log \pi(a|s_t)]\) 是策略在状态 \(s_t\) 下的熵。
为什么要加熵? 这不是一个拍脑袋的决定,而是有深刻的理论和实践动机:
1. 探索(Exploration)
标准RL中的确定性策略(如DDPG)需要手动添加探索噪声,而且噪声的设计非常讲究。最大熵RL通过目标函数中的熵项,让策略天然地保持随机性,自动探索。更关键的是,这种探索是"有意义的"——策略会在Q值相近的动作之间保持均匀分布,而不是简单地加一个和任务无关的高斯噪声。
2. 鲁棒性(Robustness)
在很多实际任务中,环境存在不确定性(如摩擦系数的变化、传感器噪声等)。一个确定性策略可能恰好利用了训练环境中的某个特定特征,换一个稍微不同的环境就失效。而最大熵策略倾向于学习所有可行的解决方案,而不是只依赖一种,因此对环境扰动更加鲁棒。
3. 多模态性(Multi-modality)
很多任务存在多种等价的最优策略。比如绕过一个障碍物可以从左边走也可以从右边走。确定性策略只能学到其中一种,而最大熵策略可以同时保留多种方案,赋予它们相应的概率。这在策略被用作后续任务的初始化(transfer learning)时非常有价值。
4. 更平滑的优化景观(Smoother Optimization Landscape)
熵项的加入相当于对目标函数做了一个"软化"处理。原本可能有很多尖锐的局部最优被平滑掉了,使得优化过程更加稳定。
Soft Bellman Equation
在最大熵框架下,传统的Bellman方程需要做相应的修改。
标准Bellman方程:
Soft Bellman方程: 将 \(\max\) 替换为 \(\text{softmax}\)(即log-sum-exp),同时加入熵项:
其中soft value function定义为:
直觉理解: 在标准Bellman方程中,我们贪婪地选择Q值最大的动作(\(\max\))。在Soft Bellman方程中,我们不再选最大的一个,而是用一种"软"的方式:所有动作都有可能被选中,Q值越高的动作被选中的概率越大,但Q值低的动作也不会被完全排除。这种"软"的选择,正是由策略的熵来实现的。
Soft Q-Learning
有了Soft Bellman方程,我们可以推导出最大熵框架下的最优策略。
在Soft Bellman方程下,最优策略满足:
其中 \(Z(s) = \sum_a \exp(Q_{\text{soft}}^*(s, a) / \alpha)\) 是配分函数(partition function),确保概率归一化。
这个形式就是一个Boltzmann分布(也叫Gibbs分布)。温度系数 \(\alpha\) 控制分布的"尖锐程度":
- \(\alpha \to 0\) 时:策略退化为贪婪策略(只选Q值最大的动作),回到标准RL
- \(\alpha \to \infty\) 时:策略趋近于均匀分布(所有动作等概率),完全随机
Soft Q-Learning(2017, Haarnoja et al.)就是在这个理论基础上提出的算法。但Soft Q-Learning在高维连续动作空间中存在计算困难——配分函数 \(Z(s)\) 需要对连续动作空间积分,无法精确计算。
这就是SAC要解决的核心问题。
Soft Actor-Critic
SAC(2018, Haarnoja et al.)的关键洞察是:不需要显式计算配分函数,只需要训练一个参数化的策略网络来近似最优的Soft策略。
SAC同时训练三组网络:
- 两个Q网络(Twin Critics): \(Q_{\phi_1}(s, a)\) 和 \(Q_{\phi_2}(s, a)\),借鉴TD3的Twin技巧
- 策略网络(Actor): \(\pi_\theta(a|s)\),输出一个高斯分布(均值和标准差)
- (SAC v1中还有)价值网络: \(V_\psi(s)\),在SAC v2中被删除
Soft Policy Evaluation(Q网络更新):
Q网络的目标是逼近Soft Bellman方程的不动点。损失函数为:
其中目标值 \(y\) 为:
注意与标准TD目标的区别:这里多了一个 \(-\alpha \log \pi_\theta(a'|s')\) 项,这就是熵奖励。\(a'\) 是从当前策略中采样的,而不是用确定性策略计算的。
Soft Policy Improvement(策略网络更新):
策略网络的目标是最小化策略与Soft Q函数的Boltzmann分布之间的KL散度:
其中 \(Q(s, a) = \min_{i=1,2} Q_{\phi_i}(s, a)\) 取两个Q网络的较小值。
直觉理解: 这个损失函数在做两件事——(1) 让策略倾向于选择Q值高的动作(\(-Q(s,a)\) 项);(2) 同时保持策略的随机性(\(\alpha \log \pi_\theta\) 项,即负熵)。两者通过 \(\alpha\) 来平衡。
Reparameterization Trick(重参数化技巧):
由于动作 \(a\) 是从策略 \(\pi_\theta\) 中采样的,直接对采样操作求梯度是不可能的(采样操作不可微)。SAC使用了重参数化技巧来解决这个问题:
其中策略网络输出均值 \(\mu_\theta(s)\) 和标准差 \(\sigma_\theta(s)\),然后将一个标准正态噪声 \(\epsilon\) 通过仿射变换得到动作 \(a\)。
重参数化的精妙之处在于:把随机性从策略网络"转移"到了外部噪声 \(\epsilon\) 上。 这样,给定一个固定的 \(\epsilon\),\(a\) 关于 \(\theta\) 是一个确定性的可微函数,可以正常地反向传播。这和VAE中的重参数化技巧完全一致。
由于连续动作空间中的动作通常有范围限制(如 \([-1, 1]\)),SAC对高斯分布的输出施加一个 \(\tanh\) 压缩:
此时需要对log概率做对应的Jacobian修正:
其中 \(u = \mu_\theta(s) + \sigma_\theta(s) \odot \epsilon\) 是 \(\tanh\) 之前的值,\(D\) 是动作维度。
SAC v2 - 自动温度调整
SAC v1中,温度系数 \(\alpha\) 是一个需要手动调整的超参数。这很不方便,因为:
- 不同任务的最优 \(\alpha\) 差异很大
- 即使在同一个任务中,训练的不同阶段可能也需要不同的 \(\alpha\)(初期需要更多探索,后期需要更精确的策略)
SAC v2(2019, Haarnoja et al., "Soft Actor-Critic Algorithms and Applications")做了两个关键改动:
改动1:自动温度调整(Automatic Entropy Tuning)
将温度调整形式化为一个带约束的优化问题:
其中 \(\mathcal{H}_0\) 是目标熵的下界。对于连续动作空间,常见的设置是:
即目标熵等于动作空间维度的负数。比如动作空间是6维的,目标熵就是 \(-6\)。
通过对偶变换,\(\alpha\) 的损失函数为:
直觉理解:
- 如果当前策略的熵 \(-\log \pi > \mathcal{H}_0\)(策略足够随机),则 \(\alpha\) 会减小,减弱对随机性的要求,让策略更专注于回报
- 如果当前策略的熵 \(-\log \pi < \mathcal{H}_0\)(策略太确定了),则 \(\alpha\) 会增大,强制策略增加随机性
这就实现了温度的自动调节:训练初期策略随机性自然较高,\(\alpha\) 会比较小;训练后期策略趋于确定,\(\alpha\) 会自动增大来维持必要的探索。
改动2:删除Value Network
SAC v1中有一个独立的Value Network \(V_\psi(s)\)。SAC v2发现这是冗余的,因为Soft Value可以直接从Q网络和策略网络推导出来:
删除Value Network后,网络结构更简单,需要维护的参数更少,训练也更稳定。Target Network只需要对Q网络做软更新。
现代SAC
将所有组件整合,现代SAC(即SAC v2)的完整训练流程如下:
网络架构:
| 网络 | 输入 | 输出 | 数量 |
|---|---|---|---|
| Q网络 \(Q_{\phi_i}\) | \((s, a)\) 拼接 | 标量Q值 | 2个(Twin) |
| Target Q网络 \(Q_{\phi_i^-}\) | \((s, a)\) 拼接 | 标量Q值 | 2个(软更新) |
| 策略网络 \(\pi_\theta\) | \(s\) | \((\mu, \log\sigma)\) | 1个 |
| 温度参数 \(\log \alpha\) | - | - | 1个可学习标量 |
训练伪代码:
SAC算法(现代版本):
1. 初始化 Q_ϕ1, Q_ϕ2, π_θ, log α
2. 初始化 target: Q_ϕ1^- = Q_ϕ1, Q_ϕ2^- = Q_ϕ2
3. 初始化经验回放池 D = {}
4. for each environment step do
5. a ~ π_θ(·|s) # 从策略采样动作
6. s', r, done = env.step(a) # 与环境交互
7. D ← D ∪ {(s, a, r, s', done)} # 存入回放池
8. # 从回放池采样一个batch
9. (s, a, r, s', done) ~ D
10. # ---- 更新Q网络 ----
11. a' ~ π_θ(·|s') # 用当前策略采样下一步动作
12. y = r + γ(1-done) * (min Q_ϕi^-(s',a') - α log π_θ(a'|s'))
13. 更新 ϕ1, ϕ2 最小化 (Q_ϕi(s,a) - y)^2
14. # ---- 更新策略网络 ----
15. a_new ~ π_θ(·|s) # 重参数化采样
16. 更新 θ 最小化 α log π_θ(a_new|s) - min Q_ϕi(s, a_new)
17. # ---- 更新温度 ----
18. 更新 α 最小化 -α(log π_θ(a_new|s) + H_0)
19. # ---- 软更新Target网络 ----
20. ϕi^- ← τϕi + (1-τ)ϕi^-
21. end for
关键公式汇总
| 公式名称 | 数学表达式 |
|---|---|
| 最大熵目标 | \(J(\pi) = \mathbb{E}\left[\sum_t \gamma^t (r_t + \alpha \mathcal{H}(\pi(\cdot\|s_t)))\right]\) |
| Q网络目标 | \(y = r + \gamma(\min_{j} Q_{\phi_j^-}(s', a') - \alpha \log \pi(a'\|s'))\) |
| Q网络损失 | \(L(\phi_i) = \mathbb{E}[(Q_{\phi_i}(s,a) - y)^2]\) |
| 策略损失 | \(J_\pi(\theta) = \mathbb{E}_s[\mathbb{E}_{a \sim \pi}[\alpha \log \pi(a\|s) - \min_i Q_{\phi_i}(s,a)]]\) |
| 温度损失 | \(J(\alpha) = \mathbb{E}[-\alpha(\log \pi(a\|s) + \mathcal{H}_0)]\) |
| Soft Value | \(V(s) = \mathbb{E}_{a \sim \pi}[Q(s,a) - \alpha \log \pi(a\|s)]\) |
| 重参数化 | \(a = \tanh(\mu_\theta(s) + \sigma_\theta(s) \odot \epsilon)\) |
| Target软更新 | \(\phi^- \leftarrow \tau\phi + (1-\tau)\phi^-\) |
超参数建议
| 超参数 | 符号 | 常见取值 | 说明 |
|---|---|---|---|
| 学习率 | \(\alpha_{lr}\) | \(3 \times 10^{-4}\) | Actor/Critic/Alpha统一 |
| 折扣因子 | \(\gamma\) | \(0.99\) | 未来奖励的折扣 |
| 软更新系数 | \(\tau\) | \(0.005\) | Target网络更新速率 |
| 目标熵 | \(\mathcal{H}_0\) | \(-\dim(\mathcal{A})\) | 自动温度调整的目标 |
| Batch大小 | \(B\) | \(256\) | 每次从回放池采样的数量 |
| 回放池大小 | $ | \mathcal{D} | $ |
| 网络宽度 | - | \(256\) | 隐藏层神经元数 |
| 网络深度 | - | \(2\) | 隐藏层数量 |
| 学习开始步数 | - | \(10^4\) | 开始训练前先收集的随机数据量 |
| 更新频率 | - | 每步更新1次 | 每与环境交互一步就更新一次 |
SAC的一个巨大优势是:超参数基本不需要怎么调。 上面这组默认值在绝大多数连续控制任务(MuJoCo等)中直接就能达到很好的性能。这和DDPG/TD3需要精心调参形成了鲜明对比。
SAC vs PPO vs DQN
| 对比维度 | DQN | PPO | SAC |
|---|---|---|---|
| 年份 | 2013/2015 | 2017 | 2018 |
| 动作空间 | 离散 | 离散/连续 | 连续(原生) |
| 策略类型 | 隐式(通过Q值贪婪选取) | 随机策略 | 随机策略(最大熵) |
| On/Off-Policy | Off-policy | On-policy | Off-policy |
| 样本效率 | 中等 | 低 | 高 |
| 训练稳定性 | 中等(需要Target Net) | 高(Clipping保护) | 高(熵正则化 + Twin Q) |
| 核心网络 | Q网络 + Target Q | Actor + Critic | Twin Q + Actor + \(\alpha\) |
| 经验回放 | 需要 | 不需要 | 需要 |
| 探索机制 | \(\epsilon\)-greedy | 策略本身的随机性 | 最大熵 + 策略随机性 |
| 调参难度 | 中等 | 简单 | 很简单 |
| 并行化 | 不擅长 | 非常擅长(多环境并行) | 不擅长 |
| 典型应用 | Atari游戏等离散任务 | RLHF、游戏AI、机器人 | 机器人控制、连续控制 |
| 数学基础 | Bellman方程 + 函数逼近 | 策略梯度 + 信赖域 | 最大熵RL + 策略梯度 |
选择建议:
- 离散动作空间(如棋盘游戏、Atari): DQN系列或PPO
- 连续控制 + 样本充足(如仿真环境): PPO(稳定、易并行)
- 连续控制 + 样本宝贵(如真实机器人): SAC(样本效率高)
- 需要最大鲁棒性和最少调参: SAC(自动温度调整、默认超参数好用)
- 大语言模型RLHF: PPO(离散token空间、易并行、配套工具链成熟)