上一篇强化学习基础的结尾留了一个悬念:那个 20 行的表格 Q-learning 在 4 格走廊上完美收敛,但如果把 Q 表格换成神经网络,"一切都开始不收敛了"。
这篇文章就来讲这条路线:Value-based 方法。它的核心信念极其简洁——
如果我能准确知道"在每个状态下、每个动作的长期价值",那最优策略就是免费的副产品:。
问题在于,这个 表格在 Atari 里有大约 行,在围棋里更多。于是整个故事就变成了:如何用一个神经网络稳定地逼近 。DQN 之后那一长串改进(Double、Dueling、优先回放、多步、分布式……)看起来像一堆零散的 trick,但每一个都在修一个具体的 bug。这篇文章的写法就是:问题 → 方法 → 公式 → 效果。
从 Q-learning 说起
时序差分:用估计去更新估计
上一篇讲了,如果模型 已知,直接用价值迭代就能解。现在模型未知,我们只有一条条采样出来的经验 。怎么办?
最朴素的想法是蒙特卡洛(MC):跑完一整条轨迹,把实际拿到的回报 当作 的样本,做平均。这样做无偏,但必须等到回合结束,而且方差很大(一条轨迹里所有的随机性都累加进了 )。
时序差分(Temporal Difference, TD) 的想法要聪明得多:不用等到最后,走一步就能学。因为贝尔曼方程告诉我们
那就用括号里的东西当作"标签",去更新 。定义 TD error:
更新规则就是朝着减小 TD error 的方向挪一小步:
这就是 Q-learning。它最迷人也最危险的地方在于:用自己的估计来更新自己的估计,这叫 自举(bootstrapping)。好处是不用等回合结束、方差小;坏处是如果估计本身错了,错误会自我强化。
MC、TD、DP 三者对比
| 维度 | 动态规划(DP) | 蒙特卡洛(MC) | 时序差分(TD) |
|---|---|---|---|
| 需要模型 | 需要 | 不需要 | 不需要 |
| 需要完整轨迹 | 不需要 | 需要 | 不需要(走一步就学) |
| 是否自举 | 是 | 否 | 是 |
| 偏差 | 无(模型准确时) | 无偏 | 有偏(初期估计不准) |
| 方差 | 无 | 高 | 低 |
| 适用性 | 小规模、模型已知 | 回合制任务 | 通用,最主流 |
一句话记忆:MC 用真实回报换低偏差,TD 用自举换低方差。中间还有连续的谱系(-step return、TD()),后面会讲到。
表格 Q-learning 为什么能收敛
在表格情形下,Q-learning 的收敛有严格保证,条件是:
- 每个状态-动作对被访问无限多次(充分探索)
- 学习率满足 Robbins-Monro 条件:,
有意思的是,条件里完全不要求数据由什么策略产生。这就是 Q-learning 是 off-policy 算法的根源:TD target 里用的是 ,它评估的永远是"贪心策略",而不是"实际采样时用的策略"。所以你可以用 -greedy 去探索、甚至用完全随机的策略采数据,学到的仍然是最优 。这个性质极其宝贵——它意味着数据可以复用、可以来自别处,是后面经验回放能成立的前提。
对照组:SARSA 与悬崖行走
把 TD target 里的 换成"实际采取的下一个动作",就得到 SARSA(名字来自 ):
这一字之差让它变成了 on-policy 算法:它评估的是"包含探索行为的当前策略"。经典的悬崖行走(cliff walking) 实验把两者的差异展示得很清楚:

- Q-learning 学到的是最优路径:紧贴悬崖边走,路程最短。但训练过程中因为 -greedy 会随机走动,贴着悬崖时偶尔会掉下去,所以训练期间的实际回报更差。
- SARSA 学到的是绕远的安全路径。因为它的 target 里包含了"下一步可能会随机乱走"这件事,于是主动远离悬崖,训练期间表现更好。
结论:如果你在乎的是"最终部署的最优策略",选 off-policy;如果你在乎的是"学习过程中不能出事故"(真机、线上系统),on-policy 的保守性反而是优点。
从表格到函数逼近
为什么必须逼近
表格法有两个致命限制:
- 存不下:Atari 的状态是 的像素,状态数天文级
- 不泛化:表格里每个状态各自为政,见过 100 万个局面之后,遇到第 100 万零一个仍然一无所知
我们希望的是:,其中 是一个神经网络的参数。相似的状态自然会得到相似的 值,这就是泛化。
Fitted Q Iteration:把 RL 变成一串监督回归
最直接的做法是 Fitted Q Iteration(FQI):既然 TD target 可以算出来,那就把它当标签,做一次标准的监督回归。收集一批数据 ,然后反复:
- 用当前网络 给每条数据算标签:
- 训练一个新网络 去拟合 ,即最小化
用神经网络实现就是 Neural Fitted Q (NFQ)。这个视角很重要:它揭示了深度 RL 的本质就是"一串不断变化标签的监督学习问题"。
为什么它会崩
但直接把这个思路做成在线的、随机梯度的版本,训练经常发散。原因就是上一篇提到的致命三角,这里具体展开:
| 问题 | 具体表现 |
|---|---|
| 标签非平稳 | 标签 里的 就是我们正在更新的参数。参数一动,标签就跟着动,等于"追一个自己在动的目标" |
| 数据强相关 | 在线采样得到的连续状态几乎一样,一个 mini-batch 内样本高度相关,梯度估计有严重偏差,网络会对最近的经验过拟合 |
| 自举放大误差 | 某个状态的 被高估后,会通过 传播到它的所有前驱状态,正反馈循环 |
| 参数共享的干扰 | 更新一个状态的 会不可避免地改变其他状态的 ,可能把已经学好的地方破坏掉(灾难性干扰) |
DQN 的贡献,就是用两个非常朴素的工程手段,把前两个问题压住了。
DQN:让深度网络 + Q-learning 真的能跑
2015 年的 DQN 用同一套网络结构和超参数,在 49 个 Atari 游戏上达到甚至超过人类水平。它的损失函数是:
和 NFQ 相比,公式上只多了两个记号: 和 。但正是这两个东西起了决定性作用。
关键设计一:经验回放(Experience Replay)
把每一条交互经验 存进一个容量固定的缓冲池 (通常 条),训练时从池中随机采样 mini-batch。

它同时解决了两个问题:
- 打破时间相关性:随机采样让 mini-batch 内的样本近似独立,梯度估计更接近真实梯度
- 提高样本效率:一条经验可以被反复使用几十次,而不是用一次就扔(这正是 off-policy 性质带来的红利)
顺带还有一个好处:它把训练数据的分布平滑了,避免了策略突变导致的训练震荡。
关键设计二:目标网络(Target Network)
再复制一份网络参数 专门用来算标签,每隔 步(比如 10000 步)才同步一次 。
这相当于把"追自己动的目标"变成了"追一个每隔一段时间才跳一次的目标",在每个区间内标签是固定的,退化成了标准监督回归。代价是引入了一点滞后(标签用的是旧参数,稍微过时),换来的是稳定性。后来常见的变体是软更新:
平滑地跟随,DDPG/TD3/SAC 都用这个(第三篇会见到)。
网络结构与工程细节
DQN 的网络输入是状态,输出是所有动作的 值(一次前向就能拿到 ,不必对每个动作各跑一次):
1 | 状态 s (84×84×4) |
那些论文里不太起眼、但少了就跑不起来的细节:
| 细节 | 做法 | 为什么 |
|---|---|---|
| 帧堆叠 | 最近 4 帧拼成一个状态 | 单帧不满足马尔可夫性(看不出速度) |
| 跳帧(frame skip) | 每 4 帧决策一次,动作重复 | 省算力,且相邻帧信息冗余 |
| 奖励裁剪 | 奖励 clip 到 | 不同游戏分数量级差异巨大,统一超参 |
| Huber loss | 误差大时退化为线性 | TD error 偶尔很大,平方损失梯度会爆 |
| 退火 | 从 1.0 线性降到 0.1 | 早期多探索,后期多利用 |
| 梯度裁剪 | 按范数裁剪 | 防止个别异常样本破坏网络 |
核心代码
用 PyTorch 写出来,DQN 的核心其实只有十几行:
1 | import torch, torch.nn.functional as F |
注意 (1.0 - done) 这一项:终止状态之后没有未来,不能再自举。这是新手最常见的 bug 之一,写错了会导致价值被系统性高估。
DQN 家族:每个改进修哪个 bug
DQN 能跑,但远不完美。接下来这一串改进,建议按"它在修什么"来记,而不是按名字记。
Double DQN:修 max 带来的过估计
问题。TD target 里的 有一个统计学上的系统性偏差。因为对于任何有噪声的估计,
也就是说, 会优先挑中那些"恰好被高估"的动作。噪声本身是零均值的,但经过 筛选后就变成了正偏差。而且这个偏差会通过自举一层层传播、累积,导致 值整体虚高,策略被误导。

方法。把"选哪个动作"和"评估这个动作值多少"用两套参数分开:
在线网络说"我觉得 最好",目标网络说"那我来给 打分"。两者的噪声不相关,被同时高估的概率就小得多。
效果。实现代价近乎为零(只改一行),Atari 上的 值估计明显更接近真实值,得分显著提升。这是性价比最高的改进之一。
1 | # Double DQN:只改标签的计算方式 |
Dueling Network:修"很多状态下动作无关紧要"
问题。在很多状态下,选哪个动作根本不重要(比如赛车游戏里前方空旷的直道,任何动作差别都很小)。但标准 DQN 必须为每个动作独立学一个 值,样本被浪费在学习"这些动作其实都差不多"这件事上。
方法。把网络拆成两个头:一个估状态价值 ,一个估优势 ,再合起来:
1 | ┌──→ 全连接 ──→ V(s) 标量 |
减去优势均值这一步是必需的:否则 和 之间存在一个常数的自由度(、 给出同样的 ),无法唯一确定,训练会漂移。
效果。 的更新会受益于所有动作的样本(而不是只有被选中那个动作的样本),学习效率更高,在动作数多的游戏上提升明显。
Prioritized Experience Replay:修"均匀采样浪费算力"
问题。均匀采样意味着那些已经学得很好、TD error 接近 0 的经验,和那些"意外的、还没学明白"的经验被同等对待。而在稀疏奖励任务里,含有奖励的那几条经验可能只占回放池的万分之一。
方法。按 TD error 的大小分配采样概率——越"意外"的经验越值得学:
控制优先级的强度( 退化为均匀采样)。但这样采样引入了偏差(改变了期望所对应的分布),需要用重要性采样权重纠正:
从一个较小值退火到 1:训练早期允许有偏(快速学习),后期逐渐无偏(保证收敛)。
效果。在 Rainbow 的消融实验里,它是贡献最大的两个改进之一,在稀疏奖励任务上尤其明显。代价是实现复杂(需要 sum-tree 数据结构做 采样)和额外的超参。
Multi-step Returns:调节偏差-方差的旋钮
问题。单步 TD 的自举太"近视":奖励信号每次只能往前传播一格(回忆上一篇价值迭代那张表,传播 3 格要 3 轮)。在长视野任务里,信息扩散得太慢。
方法。用 步真实奖励 + 第 步的自举:
是 DQN, 是蒙特卡洛。 就是偏差-方差的旋钮: 越大,用的真实信息越多(偏差小),但方差越大。实践中 通常最好。

顺便提一句理论上的瑕疵:Q-learning 是 off-policy 的,严格来说多步回报需要重要性采样修正(Retrace、Tree-backup 等算法就是干这个的)。但实践中当 较小、策略变化不快时,直接忽略修正效果也很好——这是深度 RL 里典型的"理论上不严谨但工程上有效"的例子。
Distributional RL:学分布而不是期望
问题。 是回报的期望,但期望丢掉了大量信息。"稳定拿 10 分"和"一半概率 0 分、一半概率 20 分"的期望相同,但风险截然不同。而且用一个标量去拟合一个多峰分布,网络内部的表示会很别扭。
方法(C51)。让网络直接输出回报的分布。把可能的回报值离散成固定的 51 个原子 (比如均匀分布在 ),网络对每个动作输出这 51 个原子的概率。分布版的贝尔曼算子是:
即:把下一状态的分布整体乘以 再平移 ,然后投影回固定的原子网格上(因为缩放平移后原子位置会错开),最后用交叉熵损失训练。
QR-DQN 反过来做:固定概率(均匀的分位数),让网络输出分位数的位置,用分位数回归损失训练,避免了投影这一步,效果更好。
效果。得分提升明显,而且训练更稳定。一个反直觉的点:即使我们最终只用期望去做决策(),学分布这件事本身也提升了性能——因为它给网络提供了更丰富的训练信号(一种辅助任务式的正则化效果)。
Noisy Nets:让探索可学习
问题。-greedy 的探索是盲目的:它以固定概率完全随机地乱按,不管当前状态。在需要"连续做出十几个特定动作才能拿到第一个奖励"的游戏(如 Montezuma's Revenge)里,随机乱按几乎不可能碰对。
方法。把网络权重变成带噪声的参数:
其中 都是可学习的。每次前向采样一次噪声,于是网络的输出本身带随机性,产生的探索是状态相关的、且有时间一致性的(一次采样在整个前向过程中固定)。更妙的是 由梯度自己学:网络会在还不确定的地方保持大噪声,在已经确定的地方自动把噪声降下来。
效果。取代了 -greedy,在需要深度探索的游戏上提升显著,且少了一个需要手调的退火超参。
Rainbow:把它们全部装上
Rainbow 把上面六项(Double + Dueling + PER + Multi-step + Distributional + Noisy)组合到一起,在 Atari 上大幅超过各个单项。它的消融实验结论比算法本身更有价值:
| 移除的组件 | 性能损失 | 结论 |
|---|---|---|
| Prioritized Replay | 很大 | 关键 |
| Multi-step | 很大 | 关键 |
| Distributional | 较大 | 重要 |
| Noisy Nets | 中等 | 有用 |
| Dueling | 小 | 视任务而定 |
| Double | 小(在分布式框架下) | 分布式 RL 已部分缓解过估计 |

值得注意的是 Double 的边际贡献变小了——因为 distributional RL 本身就抑制了过估计。这提示我们:这些 trick 之间不是简单叠加的关系,有些在修同一个 bug。
一张汇总表
| 改进 | 修的问题 | 核心改动 | 代价 |
|---|---|---|---|
| 经验回放 | 数据相关、样本浪费 | 缓冲池 + 随机采样 | 内存 |
| 目标网络 | 标签非平稳 | 冻结一份参数算标签 | 更新滞后 |
| Double DQN | 过估计 | 选动作与评估解耦 | 几乎为零 |
| Dueling | 动作无关状态浪费样本 | 结构略复杂 | |
| 优先回放 | 均匀采样低效 | 按 TD error 采样 + IS 纠偏 | 实现复杂、多超参 |
| Multi-step | 信息传播慢 | 步回报 | 方差上升 |
| Distributional | 期望丢信息 | 学回报分布 | 计算量、输出维度 |
| Noisy Nets | 探索盲目 | 可学习的参数噪声 | 参数量翻倍 |
再往后
绕不过去的墙:连续动作空间
Value-based 方法的所有操作都依赖 和 。动作离散时,一次前向输出所有动作的 值,取最大即可。但机械臂的动作是 7 个连续的关节力矩, 变成了一个在每一步决策时都要解一遍的非凸优化问题,完全不可行。
离散化行不行?7 个维度每维切 10 档就是 个动作,且丢掉了动作空间的连续结构。这就是 value-based 路线的天花板,也是下一篇 policy gradient 存在的根本理由:既然 难算,那就训练一个网络专门输出这个 。
规模化:分布式与长记忆
- Ape-X / R2D2:把数据采集和学习分离——几百个 actor 并行在环境里跑、往共享的优先回放池里灌数据,一个 learner 专心更新参数。回放池的吞吐量成了新的性能来源。R2D2 进一步在网络里加入 LSTM 处理部分可观测,并解决了"回放里存储 RNN 隐状态"的一系列工程问题。
- Agent57:结合内在动机的探索、元控制器自适应调节 与探索强度,第一次在全部 57 个 Atari 游戏上超过人类基准。
离线设定:外推误差
如果只给一个固定数据集、不允许交互(Offline RL),DQN 类方法会失败得很惨。原因在 这一项: 会主动去挑那些数据集中从未出现过的动作,而网络在这些动作上的输出纯属外推,往往严重偏高;这个虚高的值又通过自举传播开来,最终整个 函数被污染。这叫 外推误差(extrapolation error)。
主流的应对思路是"保守":
- BCQ:限制 只在"数据集中可能出现的动作"里取
- CQL:在损失里加一项,主动压低那些没在数据里出现过的动作的 值
- IQL:用期望分位数回归隐式地做 ,完全避免对未见动作求值
什么时候该选 value-based
| 适合 | 不适合 |
|---|---|
| 动作空间离散且不大 | 连续或超高维动作空间 |
| 交互成本高,需要复用数据 | 需要显式随机策略(博弈、部分可观测) |
| 有大量历史数据可灌进回放池 | 奖励极稀疏且需要长程探索(需额外机制) |
| 需要评估"每个动作值多少" | 需要严格的策略改进保证 |
实践踩坑清单
按我踩过的频率排序:
- 忘了
(1 - done):终止状态继续自举, 值持续膨胀,是最常见的静默 bug - 目标网络同步太频繁:等于没有目标网络,训练发散;太慢则学习停滞。Atari 上常用 步
- 过大:任务实际视野只有几十步却用 ,方差和自举误差都被放大
- 回放池太小:退化成在线学习,样本相关性回来了;太大则含有太多过时策略的数据
learn_start太早:池子里只有几百条高度相关的数据就开始训练,网络先过拟合到一个错误的解上- 没做奖励缩放:奖励量级 时 TD error 巨大,配合平方损失直接梯度爆炸
- 只看 loss 不看 值:DQN 的 loss 不单调下降是正常的(标签在变)。真正该监控的是平均 值——如果它持续上升不收敛,几乎肯定是过估计发散了
- 退火太快:过早停止探索,锁死在局部最优
小结
- Value-based 方法的信条是"估准 ,策略免费"。TD 学习用自举把贝尔曼方程变成可采样的更新规则;Q-learning 因为 target 里用了 而天然 off-policy,这使得数据复用成为可能。
- 表格换成神经网络后,标签非平稳和数据强相关两个问题让训练发散。DQN 用目标网络和经验回放分别压住它们,这是深度 RL 的起点。
- 后续改进各修一个具体 bug:Double 修 的过估计、Dueling 修样本利用率、优先回放修采样效率、多步回报调节偏差-方差、分布式 RL 保留回报的完整信息、Noisy Nets 让探索可学习。Rainbow 的消融告诉我们优先回放和多步回报最关键,且这些 trick 之间存在功能重叠。
- 它的天花板是连续动作空间: 不可解。这直接催生了下一篇的主题。
下一篇进入 Policy gradient methods:不再绕道价值函数,而是直接把策略参数化,对期望回报求梯度。我们会从 REINFORCE 的高方差问题出发,看基线和优势函数如何降方差,为什么 TRPO/PPO 要限制更新步长,以及 DDPG/SAC 如何攻克连续控制——最后连到当下 LLM 训练里的 RLHF 与 GRPO。