资讯动态

Q-learning与Sarsa区别详解:强化学习入门必看的双胞胎算法对比

发布时间:2026/10/15 18:29:45 来源:尧图企业网站定制
强化学习入门最容易卡住的地方Q-learning和Sarsa到底哪里不一样先说实话当年我自己学强化学习的时候Q-learning和Sarsa这对“双胞胎”让我怀疑人生。公式看起来就差了一个符号老师讲的时候说一个是off-policy一个是on-policy我点头点头回头自己写代码跑出来结果完全不同再一个个翻公式才明白——那个“max”和“实际动作”的区别决定了两种完全不同的决策性格。如果你也在学这两兄弟或者已经在跑代码了但搞不清为什么结果有时候差很多这篇文章就是写给你的。我会从二者的共同祖先讲起拆到更新公式的每一位再用一个经典实验把差距摆在桌面上最后聊聊实际项目里到底该怎么选。1. 先搞清楚它们从哪里来时序差分、价值迭代和那张“不太聪明但好用”的Q表很多教程一上来就扔两个公式然后说“看区别就在这里”这是最蒙人的教法。你要不知道这两个算法为了解决什么而生背再多次公式也白搭。Q-learning和Sarsa都属于时序差分Temporal Difference, TD类算法。TD思想的精髓是一句话用当前奖励加上对下一步的估计去更新当前这一步的估计。它不需要像蒙特卡洛那样等整个回合结束才知道结果太慢也不会像动态规划那样必须知道完整的环境模型大多数实际场景根本给不了。它走一小步就立刻回过头来修正自己的认知——有点像你开车时一边看后视镜一边修正方向盘而不是等到了终点才回忆刚才哪个路口转错了。这两兄弟共同的家就是那张Q表。Q表记录的是“在某个状态下采取某个动作未来能获得的累计折扣回报的期望”。强化学习训练的过程说白了就是反复跟环境交互用反馈来回填这张表让表里的估计值越来越贴近真实。表格型方法在真实项目里确实受限于状态空间爆炸但它作为理解RL核心思想的最佳教具地位至今没人能替代。那么问题来了既然TD思想定了Q值的定义也定了“更新Q表”这件事到底应该用哪个值作为更新目标这正是Q-learning和Sarsa分道扬镳的分岔口。顺便提一句这两个算法都遵循贝尔曼方程——就是那个把“当前价值”拆成“即时奖励”和“下一状态价值”的递归等式。你可以把贝尔曼方程理解为一张“价值地图”的拼图规则每个位置的价值等于你现在拿到的收益加上下一个位置的价值。Q-learning和Sarsa是拼图的两只手拿着同一张规则却用不同的方式找下一块拼图。2. 一条公式的两种写法max让它们分道扬镳我们直接把两个更新公式摆在一起看。立刻就能找到那个起决定性作用的差异Q-learning的更新目标Q(s, a) ← Q(s, a) α * [r γ * max_{a} Q(s, a) - Q(s, a)]Sarsa的更新目标Q(s, a) ← Q(s, a) α * [r γ * Q(s, a) - Q(s, a)]如果你第一次看可能会说这不就差一个max吗对就这一个小东西让两个算法的逻辑性格天差地别。我用一个生活化的比喻把这些讲透。假设你在玩一个无限重复的迷宫探险游戏每次走到一个岔路口都面临“继续往前”“回头”“左转”等选择。Sarsa走的是“我现在定下的策略是什么下一秒就这么干”——更新Q值时用到的下一个动作必须是按当前策略选出来的动作比如按ε-greedy策略选出的那个具体动作。也就是说Sarsa是在评估自己正在走的这条路到底值多少。Q-learning则完全不管下一秒实际做什么——它只关心“下一步所有可能动作中哪个能让我拿到的Q值最大”。哪怕当前策略是个探索很猛、瞎走很多的策略Q-learning更新时依然死死盯着那个理论上最优的动作。所以它学习的是“假设接下来一直选择最优动作这条路的值是多少”而不等待你真正执行什么动作。这就是那对关键术语的来源Sarsa是on-policy同策略行为策略用来选择和生成数据的策略和目标策略用来更新价值的策略是同一个。更新公式跟实际行为绑定怎么走就怎么算。Q-learning是off-policy异策略行为策略和目标策略是两码事。行为策略可以是任意灵活的探索机制但它更新Q值时用的是“最优”跟实际选择的动作脱钩。这是整篇文章最重要的一个认知拐点。你一旦理解了这条后面所有实验现象Sarsa保守、Q-learning激进、悬崖行走那个经典对比都不难解释。2.1 为什么Q-learning的max是“激进的乐观派”Q-learning里面那个max实质上是把“后继状态的价值估计”推向最高的地方。这有两个直接后果第一只要某个动作在未来有一个时刻存在获得高回报的可能Q-learning就会倾向于认为这条路的价值很高。哪怕这条路中途会掉几次悬崖只要“走过悬崖之后能到终点拿到大奖励”它会觉得整条路都值得。这种乐观偏差在价值估计不准确的时候尤其明显——Q-learning对Q值的估计会系统性偏高。这个现象在学术论文里有个专门的名字过估计overestimation。它是max操作和函数近似误差一起导致的。啊对你要是用神经网络而不是表格过估计会被放得更大——这正是DQN后来需要Double DQN去修一个补丁的原因后面我会提。第二因为总是取maxQ-learning的更新方向和更新幅度在训练早期非常跳跃。它敢于“畅想”一个还没实际验证过的好结果。这种性格在环境比较简单、动作空间清晰的任务里很管用收敛快能找到接近全局最优的路径但在环境有随机性、有风险陷阱的任务里它经常会做出“为了那个诱惑先赌一把”的选择。2.2 为什么Sarsa是“跟随当前策略的保守派”Sarsa的更新目标是“当前策略实际会选择的下一个动作”的Q值。如果当前策略已经在某些状态探索得比较少或者ε-greedy策略里探索率ε比较高那么下一步很可能选到某个次优甚至比较差的动作——这个差动作的价值会被用来更新前一步的Q值。换句话说Sarsa在学习时把“当前策略可能会犯的错”也算进去了。这就让它的估计更贴近“如果我按照现在这个策略走下去真实能得到多少”。因为会把策略的不完美算进折扣Sarsa的Q值估计通常比Q-learning更保守、更贴近地面真实。代价是当环境允许走一条高风险高收益的捷径时Sarsa常常会“不敢”学出那条捷径的价值。它宁可绕远路也不走悬崖边因为只要探索策略让它跌过一两次它就会把“悬崖边”这条路的估计压得比较低。这么说吧如果你把两个算法都训练成“走迷宫到终点”的智能体Q-learning成绩表上经常是“最快路径但偶尔摔跤”Sarsa则是“慢一点但几乎不掉坑”。3. 用一个格子世界实验验证悬崖行走里的两种驾驶风格纯讲术语太虚我们来跑个实验。经典用例是Cliff Walking悬崖行走一个4×12的网格世界起点在左下角终点在右下角中间有一片悬崖区。智能体每走一步非终点非悬崖的格子奖励为-1掉进悬崖奖励为-100并回到起点到达终点回合结束。最优路径是贴着悬崖边走过去——路径短但一步失误就坠崖安全路径是绕到最上面一行再绕下来——路径长很多但稳定。这正是检验两种算法性格的完美场地。来看核心代码简化掉画图部分import numpy as np # 环境简化4行12列悬崖在最后一行1~10列 class CliffWalk: def __init__(self): self.row, self.col 4, 12 self.start (3, 0) self.goal (3, 11) self.cliff [(3, c) for c in range(1, 11)] self.reset() def reset(self): self.state self.start return self.state def step(self, a): # 动作: 0上 1下 2左 3右 r, c self.state if a 0 and r 0: r - 1 if a 1 and r self.row - 1: r 1 if a 2 and c 0: c - 1 if a 3 and c self.col - 1: c 1 state_ (r, c) if state_ in self.cliff: return self.start, -100, True # 掉崖重置回起点 if state_ self.goal: return state_, -1, True return state_, -1, False def choose_action(Q, state, epsilon): if np.random.random() epsilon: return np.random.randint(4) r, c state return int(np.argmax(Q[r, c, :])) # 平局时argmax取第一个 def run(method, episodes500, alpha0.1, gamma0.99, epsilon0.1): env CliffWalk() Q np.zeros((env.row, env.col, 4)) ep_rewards [] for _ in range(episodes): s env.reset() done False total 0 if method sarsa: a choose_action(Q, s, epsilon) while not done: if method q: a choose_action(Q, s, epsilon) s_, r, done env.step(a) total r # 核心差异 if method q: target r gamma * np.max(Q[s_[0], s_[1], :]) else: a_ choose_action(Q, s_, epsilon) # 先按当前策略选好下一步动作 target r gamma * Q[s_[0], s_[1], a_] Q[s[0], s[1], a] alpha * (target - Q[s[0], s[1], a]) if method sarsa: a a_ s s_ ep_rewards.append(total) return Q, ep_rewards注意Sarsa的更新里面a_的选取必须发生在更新之前而且更新完之后你要真的把a_当作下一步的动作去执行也就是那句sarsa分支里的a a_。这正是on-policy的关键你要用一个“按当前策略选好的下一步”来更新然后真的走下去。你跑完整个实验会得到两个在很多场景下完全不一样的Q表对比项Q-learningSarsa学出来的路径贴着悬崖边的最短路绕到上方的安全长路平均每回合掉崖次数较高很低接近零单回合累计回报最优时约-13稳定约-22到-30学习早期方差大忽好忽坏小渐进改善收敛后的最终策略路径最短最优安全保守有时未必最优这里打一个醒虽然表格里看起来Q-learning更“优”回带更少但它这种“优”是建立在环境允许掉崖重来这个前提下的。要是换成真实世界的机器人掉一次悬崖可能就是摔一次跟头、烧一次电机甚至出安全事故——那时候Sarsa的保守反而是工程上更理性的选择。3.1 如果你想让它们都走捷径衰减ε的策略会带来什么实验里有个细节值得展开如果你在训练后期把ε从一个比较大的值比如0.3逐渐衰减到接近0Q-learning学出的最优路径依然会偏向悬崖边因为它的max本身就是在主张“理论最优”而Sarsa在ε比较大的时期已经积累了“走悬崖容易掉”的教训后面ε降下来也很难洗掉这种保守倾向。我有一次实验把Q-learning的ε从0.1改成0.3早期它每回合掉崖三四次但三四百回合后收敛出来依旧是贴崖的最优路线。Sarsa在这个ε下几乎从始至终没有大规模贴近悬崖。这就是策略痕迹policy footprintSarsa的Q值里留了太多“旧策略犯过的错”想擦掉非常难。4. 两个隐藏的工程差异参数敏感性和过估计偏差在实际项目中大家用的往往不是表格而是神经网络逼近Q函数。这时Q-learning和Sarsa的一些小差异会被放大成工程上致命的坑。这里单独列一节说清楚。4.1 学习率α的敏感性不一样Q-learning的更新目标里带了maxmax操作本身对Q值的干扰比较大所以它对学习率α比较敏感。α太大Q值震荡得厉害α太小收敛慢得让人怀疑人生。不少项目里Q-learning都需要把α从0.1往下探到0.01甚至更小尤其是环境带有随机奖励的时候。Sarsa因为更新目标用的是“实际选到的动作的Q值”少了一层max对噪声的放大作用整体更新平稳许多。所以Sarsa通常能在稍大一点的α下稳定训练也更容易配出不会发散的参数。一个小建议如果你在调参时发现Q-learning发散去先别急着改网络结构先往下降α往往能救回来。4.2 过估计Q-learning的max是一把双刃剑前面提过过估计。表格型Q-learning由于Q表是离散独立存储的过估计相对可控但一旦换到神经网络比如DQNmax操作会让Q值系统性地高于真实价值训练到后期经常看到“明明收益在变差Q值却还在往上涨”的反常现象。Sarsa没有这个Max困扰但它也不因此就高枕无忧。当动作空间很大的时候on-policy需要海量数据才能把策略覆盖完整否则学到的东西会严重偏向“已经探索过的路径”很多更优分支根本没机会被发现。这也就是高维控制场景比如机器人连续控制普遍更偏爱off-policy方法的根本原因——数据效率和信息覆盖上off-policy天然占优。4.3 数据来源一个很少被提及但极其现实的差异工程落地时常遇到一个问题你不是真的能亲自控制环境或者手里只有一段别人跑出来的历史数据。这时候Q-learning突然变成了几乎唯一的选择因为它是off-policy可以在别的策略采出来的数据上反复离线学习不断更新自己的Q表。Sarsa是on-policy它的更新目标依赖“当前策略”指定的下一步动作拿历史数据来训练的时候逻辑上会拧巴历史数据里的动作可能根本不是你当前策略会选的动作那你还怎么用“当前策略选的a”做更新这个差异在现实项目里意味着什么意味着Q-learning可以拿存量数据、别家agent的轨迹做离线训练Sarsa则必须是线上边试边学。做交易策略、自动驾驶决策这类有大量历史日志的领域off-policy几乎是默认选择。你网上看到很多“从expert trajectory里学策略”的案例底层基本都是Q-learning、DQN这一挂。5. 到底选哪个我给决策场景列了一个真实可用的选择清单直接给结论容易误人这里我按实际场景盘一盘。优先选Sarsa的情况任务对单步失败容忍度极低。比如机器人行走、自动仓储车调度摔一次代价很大宁可绕远也不冒险。环境随机性比较大比如动作执行有噪声、奖励有噪声。Sarsa把噪声算进更新目标里学出来的策略更贴地。你打算长期在线训练、环境允许大量试错但试错的单次成本不能太高。你希望策略的行为方差小一点方便做后期的安全性验证。优先选Q-learning的情况你手里有离线数据、历史日志想离线训练一个决策模块。这是off-policy的主场Sarsa根本打不了。任务有清晰的奖励结构高回报路径明确环境允许“失败后重置”比如游戏、仿真器可以将训练期的一些“翻车”视为可接受成本。你后面计划往DQN、Double DQN等深度强化学习方向走。那本质上都是从这个max框架延伸出去的底子打了不亏。动作空间大、需要高数据利用率的任务。如果你实在拿不准我的土办法是先用Sarsa搭一个安全保守的基线再拿Q-learning往上冲最优解。两个算法一共就几十行代码都跑一遍对比学习曲线比拿着一堆理论纠结半天高效得多。6. 从这对“双胞胎”出发你的下一步该看什么Q-learning和Sarsa不是你学习的终点它们是整个RL算法树的根。弄懂这对双胞胎之后你再看后面一串算法会发现全都是熟面孔Expected Sarsa把Sarsa里的Q(s, a)换成对所有动作按策略概率加权求期望。它保留了Sarsa“按策略评估”的保守属性但减少了单次采样带来的方差线表上一般比Sarsa更稳。Double Q-learning用两套Q表交叉更新破解Q-learning的过估计问题。懂了对max的执念之后再看Double Q-learning的思路就觉得非常自然——它不过是用两套账本互相纠偏。DQNQ-learning 神经网络 经验回放 目标网络整个深度强化学习热潮的起点。你看DQN论文里那些“消除相关性”“防止过估计”的设计每一条都能在Q-learning的短板上找到对应。SARSA(λ)在Sarsa前面加一个资格迹eligibility trace实现多步TD更新。它不人为等待回合结束而是把最近走过的几步“记在账上”统一更新。这又是从“单步更新”到“多步更新”的全新维度。我的建议是不要急着跳到DQN先把表格版的Q-learning和Sarsa亲手写一遍。不需要用什么现成框架纯numpy几十行就行跑通那个悬崖实验画两条学习曲线出来你会有一种“这算法真的活了”的感觉。我就是靠这个实验彻底告别了对着公式死记硬背的学习方式。一段写在最后的心得如果你认真把上面所有实验都跑过一遍会发现一个很有意思的事实Q-learning和Sarsa没有绝对的优劣它们只是对“风险”有不同态度的两种决策者。一个盯着最优解攻坚一个守着实操稳扎稳打。现实中调参调得多了我反而觉得它们更像一对性格互补的伙伴——激进方案用来探上限保守方案用来保下限。做项目也一样先求安全落地再一步步挑战更短的路径。理解了这层“性格差异”你才算真正吃透了这对双胞胎。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑