第305篇 SAC——最大熵强化学习
上篇聊了PPO,on-policy算法中的王者。但PPO有个绕不开的短板:样本效率低。在真实机器人上训练时,每次采样都要在硬件上跑,耗时耗力。如果有一种算法能用更少的采样达到同样好的效果,那就太有价值了。
SAC(Soft Actor-Critic)就是这样的算法。它是off-policy的,样本效率非常高;它引入了最大熵的思想,探索能力很强;它在连续控制任务上的表现超过了很多on-policy方法。如果你的机器人项目需要在真实硬件上训练RL策略,SAC很可能是最好的选择。
最大熵强化学习
传统的RL目标是最大化期望累积回报:max E[Σ r_t]。SAC在此基础上加了一项——策略的熵:
max E[Σ (r_t + α·H(π(·|s_t)))]
H(π) = -E[log π(a|s)]是策略的熵,α是温度系数,控制熵的权重。
这个改动看起来很小,但意义很大。加上熵项后,策略不仅要获得高回报,还要保持随机性。这意味着策略会主动探索更多的状态和动作,不会过早收敛到次优解。
直觉上可以这么理解:传统RL像一个保守的人,一旦发现某个行为能获得奖励,就反复执行。最大熵RL像一个好奇心强的人,在追求奖励的同时也愿意尝试新事物。在很多复杂任务中,这种探索精神是找到最优策略的关键。
从数学角度看,最大熵RL的最优策略有一个非常优美的形式:π*(a|s) ∝ exp(Q*(s,a)/α)。也就是说,最优策略是Q值的softmax分布。Q值高的动作概率大,但所有动作都有一定的概率。这个形式跟统计力学中的玻尔兹曼分布一模一样——温度α越高,分布越均匀;温度越低,分布越集中在最优动作上。
温度系数α很重要。α太大,策略过于随机,像无头苍蝇一样乱撞;α太小,探索不够,容易陷入局部最优。当α趋近于零时,SAC就退化成了确定性策略梯度方法。SAC-Auto(自动调节α的版本)让α也变成可学习的参数,通过梯度下降自动调整。具体做法是把α的参数化写成log(α),然后用梯度下降来优化一个关于α的对偶目标函数,让策略的熵接近一个预设的目标值。
SAC的三个网络
SAC维护三个网络:一个Actor(策略网络)和两个Critic(Q网络)。
Actor输入状态s,输出高斯分布的参数(均值和对数标准差),采样得到动作。两个Critic都输入(s, a),输出Q值估计。用两个Critic是为了取较小值来抑制过估计——跟TD3的双Critic思路一样。
# SAC的核心更新逻辑
# Actor loss: 最小化 KL(π || exp(Q/α))
# 等价于: loss = (log π(a|s) - (Q1(s,a) - log π(a|s)) / α).mean()
# 简化: loss = (α * log π(a|s) - Q(s,a)).mean()
# Critic loss: 最小化Q值的Bellman误差
# target = r + γ * (min(Q1_target, Q2_target)(s', a') - α * log π(a'|s'))
# loss_critic = (Q(s,a) - target.detach()).pow(2).mean()
Actor的更新目标很有意思:让策略接近exp(Q/α)。Q值高的动作,概率大;Q值低的动作,概率小。但同时熵项要求概率分布尽量均匀。这两个目标的平衡就是最大熵RL的核心。
SAC的训练流程
SAC是off-policy的,训练流程跟DDPG类似:
采集阶段:用当前策略在环境中执行动作,把(s, a, r, s', done)存入回放缓冲区。采集时动作直接从策略中采样,不需要额外的噪声(不像DDPG需要加OU噪声)。
更新阶段:每采集一步,从缓冲区随机采样一个mini-batch,更新Actor和两个Critic的参数。Target网络用软更新来稳定训练。
SAC的一个重要特点是每步都更新(或者每几步更新一次),而不是像PPO那样攒一批数据后集中更新。这得益于off-policy的特性——旧数据可以一直用。但训练初期有个问题:缓冲区里的数据太少,采样质量差。所以一般设一个warm-up阶段——先用随机策略采集几千到几万步数据填满缓冲区的初始部分,然后才开始训练。warm-up的步数通常在1000到10000之间,取决于任务的复杂度。
更新频率也是个超参数。有些实现每采集一步就更新一次(gradient_steps=1),有些每采集一步更新多次(gradient_steps>1)。对于简单任务,gradient_steps=1就够了;对于复杂任务,增大更新频率可以加快学习速度,但训练可能不稳定。实践中一般从1开始,如果训练太慢就增大到2或4。
回放缓冲区的大小对SAC影响很大。通常设100万到1000万。缓冲区越大,采样的多样性越好,训练越稳定。但内存也吃得更多。在实践中,如果你的任务episode比较短,缓冲区不需要太大;如果episode很长(比如几千步),缓冲区要设得大一些。一个经验法则是缓冲区至少能容纳1000个episode的数据。
SAC vs PPO:怎么选
面试中经常被问到这个问题。
样本效率:SAC远高于PPO。在MuJoCo基准上,SAC通常只需要PPO十分之一的采样量就能达到同样好的效果。如果你的采样成本高(真实机器人、复杂的物理仿真),SAC是更好的选择。
训练稳定性:PPO更好。PPO的clip机制让训练非常稳定,几乎不会崩溃。SAC虽然比DDPG稳定很多,但在某些任务上仍然会出现Q值发散的问题。
最终性能:两者差不多。在大多数基准测试上,SAC和PPO的最终性能差距不大。SAC在某些需要精细探索的任务上(比如迷宫导航)可能更好。
实现复杂度:PPO更简单。SAC有三个网络加温度系数的自动调节,调参的工作量更大。
实际选择逻辑:仿真中采样方便用PPO,真实硬件上采样昂贵用SAC。很多团队两个都用,看哪个效果更好。
还有个实际考虑:你的任务是不是多目标的。SAC的最大熵特性让它在多目标优化中表现更好——策略不会过早锁定到某一个目标上,而是保持多种行为的平衡。比如一个既要走路又要避障还要节能的机器人,SAC更容易找到一个好的平衡点。
SAC的训练中有几个工程上的技巧。动作的预处理很重要——把动作空间归一化到[-1, 1]范围内,Actor输出tanh变换后的值。Critic网络的结构也有影响,用Layer Normalization比Batch Normalization更稳定,因为off-policy的数据分布变化大,Batch Norm的统计量不准。梯度裁剪也是必要的,防止偶尔出现的大梯度破坏训练。
面试要点
最大熵的好处。面试时不要只说"增加探索",要能解释更深层的原因。最大熵策略对模型误差有鲁棒性——当环境动态有小的变化时,最大熵策略的退化程度比确定性策略小。这在Sim2Real场景中特别重要,因为仿真和真实环境之间总是有差距的。
自动温度调节。SAC-Auto把α作为可学习参数,目标是让策略的熵接近一个预设的目标值。如果熵太低(探索不够),α增大;如果熵太高(太随机),α减小。这个自动调节机制让SAC在不同任务上不需要手动调α,大大减少了超参数的工作量。
SAC的局限性。SAC只适用于连续动作空间。对于离散动作空间,有个变体叫Discrete-SAC,原理类似但实现有所不同。另外SAC的Critic过估计问题虽然比DDPG好(因为有双Critic),但在某些任务上仍然存在。最近的一些工作(比如RedQ)通过集成更多的Q网络(比如10个或20个)来进一步缓解这个问题,每次随机选其中两个来做目标值计算,效果比双Critic更好。还有一个实际问题是SAC的超参数比PPO多,调参成本更高——学习率、缓冲区大小、warm-up步数、软更新系数τ、mini-batch大小等都需要仔细调整。
给你的建议
SAC的实现比PPO复杂一些,但也不是很难。建议先跑通Stable-Baselines3的SAC实现,在几个MuJoCo环境上测试。然后对比PPO和SAC的训练曲线,体会on-policy和off-policy在样本效率上的差异。
如果想深入理解SAC的最大熵思想,推荐读Tuomas Haarnosh的原论文"Soft Actor-Critic: Off-Policy Maximum Entropy Deep RL with a Stochastic Actor"。论文写得非常清晰,数学推导也很完整。
下一篇预告:第306篇 强化学习在机器人控制中的应用
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)