核心内容
- 掌握 DP、MC、TD 三类价值估计方法分别需要什么信息、何时更新、误差来自哪里。
- 理解从已知模型到采样轨迹,再到一步自举更新的演进逻辑。
- 学会用 TD Error 连接价值评估、Q-Learning、Critic 训练等后续算法。
前面三节已经搭好了这章最重要的地基。3.1 的两台老虎机让我们看到 RL 最小的矛盾:动作要靠试出来,既要探索,也要利用。3.2 把这个问题推广到有状态变化的世界,用 MDP 描述“当前是什么状态、能做什么动作、动作之后会发生什么、拿到什么奖励”。3.3 又进一步引入状态价值函数
3.3 的最后已经埋下了这个问题:有了贝尔曼方程,并不等于我们已经会算价值。 贝尔曼方程告诉我们价值应该满足什么关系,矩阵形式也给出了一个理论上的解析解。但解析解依赖两个前提:状态数量不能太大,而且我们要知道环境的完整规则,也就是转移概率
现实任务往往卡在这两个前提上。CartPole 的物理规律也许还能写出来,围棋的状态已经多到无法穷举,大模型生成的 token 组合更是天文数字。更常见的情况是:环境像一个黑盒,智能体只能进去试一试,看到这一步拿了多少奖励、跳到了哪个下一状态,却拿不到完整的“世界说明书”。
于是问题变成了:不知道
强化学习历史上出现了三代经典方法来回答这个问题。它们不是三个平行的备选方案,而是一条逼近现实的演进线——每一代都在解决上一代的硬伤:
- DP(动态规划):已知模型时直接代入贝尔曼方程迭代,精确但需要知道一切 → 现实中做不到。
- MC(蒙特卡洛):抛开模型,跑完整局再看总分,回头修正每一步的判断 → 不用模型,但一局太长就得一直等。
- TD(时序差分):走一步就结合“眼前真实奖励”和“下一状态的猜测”修正当前估计 → 既不用模型,也不用等结束,是现代 RL 的绝对主力。
理解了这条演进线,许多后续设计就不再神秘:PPO 的 Critic 为什么用 TD 而不是 MC?DQN 为什么需要经验回放池?这三代方法是后续所有算法的基因。
::: info 核心概念
DP、MC、TD 的根本区别在于更新价值时用了多少信息:DP 需要完整的环境模型($P$ 和
核心公式
DP 策略评估更新 (DP Policy Evaluation Update):
$\leftarrow$ :赋值操作,表示用右边的计算结果来更新左边的旧值。$\sum_a \pi(a\mid s)$ :对当前状态下所有可能的动作按策略概率进行加权平均。$\sum_{s'} P(s'\mid s,a)$ :对采取动作后所有可能转移到的下一个状态按转移概率进行加权平均。
MC 价值更新 (MC Value Update):
$\alpha$ :学习率(Learning Rate),控制每次更新时向新目标迈进的步长大小($0 \sim 1$)。$G_t$ :蒙特卡洛采样的真实完整回报(从当前步一直到这局游戏结束)。
TD(0) 价值更新 (TD(0) Value Update):
$r$ :走这一步真实拿到的即时奖励。$\gamma V(s')$ :对未来收益的猜测(打折后的下一个状态的预估价值)。$r + \gamma V(s')$ :TD 目标(TD Target),即“眼前的真实奖励 + 对未来的猜测”。
TD Error (Temporal Difference Error):
$\delta$ :时序差分误差(TD Error),表示“现实发生的情况”与“你之前的预测”之间的差距。大于 0 说明有惊喜,小于 0 说明有惊吓。
先看最理想的情况:如果你完全知道环境的转移概率
在这种情况下,智能体不需要先和环境反复交互来猜规则。它可以直接把这些已知规则代入贝尔曼方程,让价值在状态之间一轮一轮传播。
这套不靠盲目试错,直接在已知模型上反复代公式的方法,就是贝尔曼在 1957 年提出的动态规划 1。
先看直觉:现实中什么时候会“完全知道”
$P$ 和$R$ ?答案通常是:当这个世界本来就是你定义出来的。比如一个迷宫小游戏的规则由你编写:“向右走一步扣 1 分,走到终点得 10 分,而且没有随机性,想往右走就一定能走到右边。”在这种场景下,DP 很自然:既然规则已知,就直接用数学递推算价值,不必靠大量试玩去估计平均结果。这也是为什么物流规划、库存管理这类规则明确的问题里,动态规划思想仍然常见。
DP 计算价值的核心叫做策略评估(Policy Evaluation)。公式看起来很眼熟:它就是把 3.3 的贝尔曼期望方程,从“真值应该满足的等式”改写成“用旧估计产生新估计”的更新规则:
反复对所有状态执行这个更新,$V$ 最终会收敛到
:::details 慢慢拆:这个公式从哪来?每一项是什么意思?
3.3 里我们已经得到过贝尔曼期望方程:
\sum_a \pi(a\mid s) \left[ R(s,a)
- \gamma \sum_{s'} P(s'\mid s,a) V^\pi(s') \right] $$
这行公式说的是:如果我们已经知道策略
- 先看策略
$\pi$ 在状态$s$ 下可能选择哪些动作; - 对每个动作,计算“这一步的奖励 + 下一状态的价值”;
- 最后按照动作概率加权平均。
问题在于:我们现在并不知道真正的
DP 的想法很朴素:既然不知道真值,那就先猜一个。
比如一开始把所有状态的价值都设成
然后用贝尔曼方程右边重新算一遍,得到下一轮估计
$$ V_{k+1}(s) \leftarrow \sum_a \pi(a\mid s) \left[ R(s,a)
- \gamma \sum_{s'} P(s'\mid s,a) V_k(s') \right] $$
这里:
-
$k$ 表示第几轮迭代。 -
$V_k(s)$ 是这一轮手里的旧估计。 -
$V_{k+1}(s)$ 是用贝尔曼方程算出来的新估计。
所以箭头
先固定一个动作
它分成两块:
第一块:眼前奖励
这是在状态
第二块:下一状态价值的平均
做完动作
如果“向右走”有
再乘上折扣因子
最后,策略
这就得到完整更新式:
可以把一次 DP 更新理解成三句话:
- 先用旧价值表
$V_k$ 看下一状态值多少。 - 再加上当前动作带来的即时奖励。
- 最后按策略
$\pi$ 对动作求平均,得到新价值表$V_{k+1}$ 。
不断重复这件事,价值会一轮一轮从终点、奖励高的地方、奖励低的地方向周围传播。最后,整张价值表会接近真正的
先画出这个最小例子。3 格走廊只有三个位置:
S --右走,奖励 -1--> M --右走,奖励 -1--> G
起点 中间 终点
-
$S$ :起点状态。 -
$M$ :中间状态。 -
$G$ :终点状态,价值固定为$0$ 。 - 策略很简单:每一步都只往右走。
- 折扣因子
$\gamma=1$ ,表示未来奖励不打折。
直觉上,$M$ 离终点只差 1 步,所以价值应该是
转移概率:$P(\text{M}|S,\text{右}) = 1$,$P(\text{G}|M,\text{右}) = 1$,其余为 0。
因为策略只有“向右走”一个动作,而且转移是确定的,所以通用 DP 更新式:
R(s,\text{右})+\gamma V_k(s_{\text{next}}) $$
在这个走廊里就变成两条具体公式:
终点不再继续走,所以:
现在再代入每一轮的数值。
迭代 0→1:初始时,所有状态都先猜成
代入上面的两条公式:
迭代 1→2:
这一轮要用上一轮刚算出的
迭代 2→3:
结果和上一轮一样,不再变化,说明已经收敛。
把上面的迭代过程汇总成表格,就是:
| 迭代 | V(S) | V(M) | V(G) |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | -1 | -1 | 0 |
| 2 | -2 | -1 | 0 |
| 3 | -2 | -1 | 0(收敛) |
经过 3 次迭代就收敛了,因为
这一步的含义是:
策略评估只是第一步。知道了
策略迭代是“评估策略 → 改进策略 → 再评估”的循环,理论上保证收敛到最优策略
:::details 慢慢拆:策略改进为什么一定有效?
策略迭代由两个交替步骤组成:
-
策略评估(Policy Evaluation):给定策略
$\pi$ ,用公式 3.4 迭代求解$V^\pi$ -
策略改进(Policy Improvement):用
$V^\pi$ 构造一个更好的策略$\pi'$
关键问题是:为什么第二步真的会让策略变好?
定义:
R(s,a)
- \gamma \sum_{s'} P(s'\mid s,a) V^\pi(s') $$
这句话的意思是:先在状态
新策略
也就是说,在每个状态里,先把每个动作的
因为
V^\pi(s) $$
这行公式只是在说一句很普通的话:从一堆动作里挑最高分,不会比原来那套选择更差。
把
$$ R(s,\pi'(s))
- \gamma \sum_{s'} P(s'\mid s,\pi'(s)) V^\pi(s') \geq V^\pi(s) $$
右边的
这就是策略改进定理。
当
这正是贝尔曼最优方程的条件——$\pi$ 已经是最优策略
可以直接用,这就是值迭代(Value Iteration)。策略迭代只是把同一件事拆成两步:
- 先把当前策略评估清楚。
- 再根据评估结果改策略。
这样做的好处是思路更清楚:先问“这套走法到底值多少分”,再问“有没有更好的第一步”。值迭代更像是每一步都直接用
值迭代和策略迭代不是抽象的公式——它们是肉眼可见的迭代过程。用一个 4×4 GridWorld 来展示每一步发生了什么。
import numpy as np
# 4×4 GridWorld
# S(0,0) → ... → G(3,3)
# 每步奖励 -1,4 个动作(上/下/左/右),γ=0.9
GRID = 4
ACTIONS = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 上下左右
GAMMA = 0.9
def step(state, action):
"""执行动作,返回 (next_state, reward)"""
nr = state[0] + action[0]
nc = state[1] + action[1]
if 0 <= nr < GRID and 0 <= nc < GRID:
return (nr, nc), -1
return state, -1 # 撞墙留在原地,照样扣分
def print_V(V, label=""):
"""打印 V 值矩阵"""
if label:
print(f" {label}")
for r in range(GRID):
print(" ", end="")
for c in range(GRID):
print(f"{V[r][c]:7.2f}", end=" ")
print()
print()
# ========== 值迭代 ==========
V = np.zeros((GRID, GRID))
print("===== 值迭代 =====")
print_V(V, "迭代 0(初始)")
for iteration in range(1, 11):
V_new = np.zeros((GRID, GRID))
for r in range(GRID):
for c in range(GRID):
if (r, c) == (3, 3):
continue # 终点 V=0
values = []
for a in ACTIONS:
(nr, nc), reward = step((r, c), a)
values.append(reward + GAMMA * V[nr][nc])
V_new[r][c] = max(values)
V = V_new.copy()
if iteration in [1, 2, 3, 5, 10]:
print_V(V, f"迭代 {iteration}")
print_V(V, "最终结果")预期输出(节选):
===== 值迭代 =====
迭代 0(初始)
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
迭代 1
-1.00 -1.00 -1.00 -1.00
-1.00 -1.00 -1.00 -1.00
-1.00 -1.00 -1.00 -1.00
-1.00 -1.00 -1.00 0.00
迭代 2
-1.90 -1.90 -1.90 -1.90
-1.90 -1.90 -1.90 -1.90
-1.90 -1.90 -1.90 -1.00
-1.90 -1.90 -1.00 0.00
迭代 5
-4.10 -4.10 -3.44 -2.71
-4.10 -3.44 -2.71 -1.90
-3.44 -2.71 -1.90 -1.00
-2.71 -1.90 -1.00 0.00
最终结果
-4.69 -4.10 -3.44 -2.71
-4.10 -3.44 -2.71 -1.90
-3.44 -2.71 -1.90 -1.00
-2.71 -1.90 -1.00 0.00
观察:$V$ 值从终点向外“扩散”。每轮迭代,比较准确的价值会向外多传播一格。这是因为值迭代每轮只把“一步之后”的估计拿回来用:第 1 轮先影响终点附近的格子,第 2 轮再影响离终点更远一格的状态,以此类推。
策略迭代与值迭代的区别在于:策略迭代交替执行“评估当前策略”和“改进策略”两个步骤,而值迭代直接在每步选最优动作。
# ========== 策略迭代 ==========
V = np.zeros((GRID, GRID))
policy = np.zeros((GRID, GRID), dtype=int) # 每个状态的动作编号
def policy_evaluation(V, policy, iterations=20):
"""用当前策略迭代计算 V"""
for _ in range(iterations):
V_new = np.zeros((GRID, GRID))
for r in range(GRID):
for c in range(GRID):
if (r, c) == (3, 3):
continue
a = ACTIONS[policy[r][c]]
(nr, nc), reward = step((r, c), a)
V_new[r][c] = reward + GAMMA * V[nr][nc]
V = V_new.copy()
return V
def policy_improvement(V, policy):
"""根据 V 改进策略,返回策略是否发生变化"""
stable = True
for r in range(GRID):
for c in range(GRID):
if (r, c) == (3, 3):
continue
values = []
for a in ACTIONS:
(nr, nc), reward = step((r, c), a)
values.append(reward + GAMMA * V[nr][nc])
best_action = np.argmax(values)
if best_action != policy[r][c]:
stable = False
policy[r][c] = best_action
return stable
print("===== 策略迭代 =====")
for iteration in range(1, 10):
V = policy_evaluation(V, policy)
stable = policy_improvement(V, policy)
action_names = ["↑", "↓", "←", "→"]
policy_str = ""
for r in range(GRID):
policy_str += " "
for c in range(GRID):
if (r, c) == (3, 3):
policy_str += " G "
else:
policy_str += f" {action_names[policy[r][c]]} "
policy_str += "\n"
print(f"第 {iteration} 轮:")
print(policy_str)
print_V(V)
if stable:
print(f"策略已收敛!共 {iteration} 轮")
break预期输出:
===== 策略迭代 =====
第 1 轮:
↑ ↑ ↑ ↑
↑ ↑ ↑ ↑
↑ ↑ ↑ ↓
↑ ↑ → G
-8.78 -8.78 -8.78 -8.78
-8.78 -8.78 -8.78 -8.78
-8.78 -8.78 -8.78 -8.78
-8.78 -8.78 -8.78 0.00
...
第 7 轮:
↓ ↓ ↓ ↓
↓ ↓ ↓ ↓
↓ ↓ ↓ ↓
→ → → G
策略已收敛!共 7 轮
策略迭代通常用较少的外层轮次收敛。原因是:策略迭代每轮内部做了多轮策略评估(把当前策略的
| 方法 | 收敛轮数 | 每轮计算量 | 特点 |
|---|---|---|---|
| 值迭代 | ~10 轮 | 每轮扫描所有状态一次 | 简单,每步只做一个 max 操作 |
| 策略迭代 | ~7 轮 | 每轮需要多次策略评估(内部迭代) | 外层更少,但每轮更重 |
在 4×4 的小格子里差别不大,但在大规模问题中,策略评估的内部循环本身就很昂贵——这就是为什么实践中值迭代更常用,而策略迭代的思想则体现在了后续的 Actor-Critic 架构中(第 6 章)。
换个角度看,DP 的强大来自一个很重的前提:它要求我们已经知道环境模型。
现实中,我们根本拿不到完整的说明书。你想让机械臂学会抓杯子,难道要先把机械臂和杯子所有微观物理碰撞的概率分布(转移概率
所以,DP 的精确性建立在两个条件上:规则已知,状态规模还算可控。它更像是一个理论基准,告诉我们“如果知道一切,价值应该怎样被算出来”。在实际中,面对那些不知道规则的环境,我们必须让智能体和环境交互,用采样数据来估计价值。
DP 的前提是“我知道环境模型”。但现实里更多时候,你并不知道模型。你不知道某个动作之后会转到哪里,也不知道奖励函数到底怎么写。那还能不能学?
蒙特卡洛的答案很直接:不知道规则,就亲自进去玩;玩完整局,再看最后总分。
比如你在玩一个陌生迷宫。站在路口
这一局从状态
如果只跑一次,运气成分太大;但如果从同一个状态
这就是蒙特卡洛方法:用很多次真实试玩的平均结果,替代你原本不知道的环境公式。 它的名字来自赌城 Monte Carlo,因为它本质上就是靠随机采样来估计平均值 2。
现在的问题是:每跑完一局,难道都要把过去所有总分重新平均一遍吗?
不用。我们只需要保留当前估计
这行公式可以这样读:
-
$V(s)$ :我原来以为状态$s$ 值多少分。 -
$G_t$ :这次真的从$s$ 出发跑完整局后,实际拿到多少分。 -
$G_t - V(s)$ :现实和预测差了多少。 -
$\alpha$ :每次改多少。它通常是一个小数,比如 0.1,意思是“不要一次全信新样本,只往新结果靠近 10%”。
比如你原本觉得这个路口值 0 分,结果这局从这里出发最后拿了 -10 分。如果
它不会一下子变成 -10,因为一次试玩可能只是运气不好;但它会先往 -10 的方向挪一点。多试很多次以后,$V(s)$ 就会逐渐靠近真实平均水平。
:::details 慢慢拆:MC 更新公式从哪来?
MC 的核心思想就是:用很多次完整回报的平均值来估计
假设状态
这就是学校里最普通的“求平均分”:把所有分数加起来,再除以次数。
问题是,RL 训练会跑很多很多局。如果每来一个新回报
我们希望只保留当前平均值
\frac{N \cdot V_N + G_{N+1}}{N+1} $$
这里的
继续整理一下:
V_N
- \frac{1}{N+1}(G_{N+1} - V_N) $$
这行公式很重要。它说明新平均值可以写成:
\text{旧估计}
- \text{步长} \times (\text{新样本} - \text{旧估计}) $$
这就是公式 3.5 的来源。
在严格求平均时,步长是
但在 RL 中,我们经常把它换成固定学习率
这样做是因为环境和策略可能一直在变。固定的
实际中常见选择是
-
$G_t > V(s)$ :实际比预测好 →$V$ 上调 -
$G_t < V(s)$ :实际比预测差 →$V$ 下调 -
$G_t = V(s)$ :预测准确 → 不动
这与人类学习的直觉完全一致——你预测考试能考 80 分($V(s)$),实际考了 90 分($G_t$),下次你就会调高对自己的评估。
"无偏"的定义:$\mathbb{E}[V(s)] = V^\pi(s)$,即估计值的期望等于真实值。
MC 用的是真实的完整回报
所以
形式化地,如果把每步奖励的波动粗略记作
MC 给出的估算是无偏(Unbiased) 的。什么是无偏?就是说在策略固定、采样足够多的情况下,样本平均会朝真实期望靠近。因为 MC 用的目标就是完整回报
但这也藏着 MC 最大的弱点:方差巨大。因为每一局游戏里,有很多后续状态和动作。你这一局结果很好,可能是因为当前状态真的好,也可能是因为后面某一步运气好;你这一局结果很差,也可能是当前状态的问题,也可能只是后面某个随机事件拖累了总分。
还是看迷宫。你站在同一个路口
如果只采样三次,$V(s)$ 会被这些偶然结果带着大幅摇摆。只有采样很多次以后,顺利的轨迹、倒霉的轨迹、普通的轨迹都被平均进去,估计才会稳定下来。
这就是高方差(High Variance):MC 的目标没有系统性偏差,但单次目标很不稳定。 为了让平均值可靠,通常需要大量完整轨迹。
还有个很致命的问题:用 MC 方法,你必须等游戏彻底结束,才能算账。 如果是打一局几分钟的游戏,还能接受。但如果是持续运行的推荐系统、机器人控制、网页 Agent 操作,任务可能很长,甚至没有自然终点。真正的问题在于:MC 必须等完整回报出现,才能更新早先状态的价值。 一旦 episode 很长,学习信号就来得太晚;如果任务没有终止状态,完整回报本身就难以定义。
MC 解决了“不知道环境规则”的问题,但它又带来一个新麻烦:必须等一整局结束,才知道总分
如果一局很短,比如 3 格走廊,等结束还可以接受。但如果任务很长呢?机器人走了 10 秒、网页 Agent 点了 5 次按钮、模型生成了 200 个 token,你不可能每次都等到全部结束再回头改第一个判断。
TD 的想法是:不用等最后总账,先用眼前这一步形成一个临时目标。
走一步以后,你至少知道两件事:
- 这一步真实拿到了多少奖励,记作
$r$ 。 - 下一状态
$s'$ 现在被你估计值多少分,记作$V(s')$ 。
于是 TD 说:虽然我还不知道完整结局,但我可以先把“这一步的真实奖励”和“下一站的预估价值”拼起来,得到一个临时目标:
这个量叫 TD Target。它的意思是:如果我从
举个 3 格走廊的例子:
每走一步奖励 -1,终点
从
- 这一步真实奖励是
$r=-1$ 。 - 下一站
$M$ 当前估计是$V(M)=0$ 。
所以 TD Target 是:
而你原来以为
下一次,当
信息就这样从终点一步步往前传。TD 不需要等完整回合结束,也不需要知道环境转移概率;它每走一步,就把已经发生的一点真实信息传回当前状态。
这就是自举(Bootstrapping):用“下一状态的当前估计”来帮助修正“当前状态的估计”。它不是乱猜,因为每次更新都至少包含一个真实发生的奖励
把“走一步就更新一次”写成公式,就是 TD(0) 更新:
这行公式可以这样读:
-
$V(s)$ :我原来以为当前状态$s$ 值多少分。 -
$r$ :这一步真实拿到的奖励。 -
$V(s')$ :下一状态$s'$ 现在估计值多少分。 -
$r + \gamma V(s')$ :TD Target,也就是“这一步真实奖励 + 打折后的下一站估计”。 -
$r + \gamma V(s') - V(s)$ :TD Error,也就是“新的临时目标”和“旧预测”之间差了多少。 -
$\alpha$ :学习率,控制每次把$V(s)$ 往 TD Target 挪多远。
所以 TD 更新不是神秘公式,它就是:
\text{旧估计}
- \alpha \times (\text{TD Target} - \text{旧估计}) $$
:::details 慢慢拆:TD 更新公式从哪来?为什么不用等结束?
贝尔曼方程的核心意思是:
\mathbb{E}\left[r + \gamma V^\pi(s') \mid s\right] $$
翻译一下:状态
DP 的做法是把所有可能动作、所有可能下一状态都列出来,精确算这个平均值。但这需要知道转移概率
TD 的做法更现实:我不列所有可能性,我只看这一次真实发生了什么。
实际走一步,观测到
这就是用一次真实采样代替 DP 的全概率求和。不需要知道
MC 和 TD 最大的区别在于:它们拿什么当更新目标。
| 方法 | 更新目标 | 需要等到什么时候? | 未来怎么处理? |
|---|---|---|---|
| MC | 等整局结束 | 全部用真实奖励 | |
| TD | 走一步就能更新 | 用 |
MC 的目标更“真实”,因为它等到了完整结果;TD 的目标更“及时”,因为它只等一步。
TD Target 里面的
这就是 TD 的偏差来源。只有当
MC 的
TD Target 只用了一个真实奖励
这就是 TD 的核心取舍:牺牲一点无偏性,换来更快、更稳定、更及时的更新。
在表格小环境里,只要每个状态都被访问足够多次,并且学习率逐渐变小,TD(0) 可以收敛到正确的价值函数。常见条件是:
-
$\sum_{t=0}^{\infty} \alpha_t = \infty$ (总学习量足够大) -
$\sum_{t=0}^{\infty} \alpha_t^2 < \infty$ (学习率衰减足够快)
不用先记证明。先记直觉:每次 TD 更新都不完美,但它不断把真实的一步奖励吸收进价值估计;随着下一状态估计越来越准,当前状态也会被带着越来越准。
还是 3 格走廊:
真实价值是:
假设刚开始全是 0,学习率
第一次从
第一次从
下一轮再从
于是
TD Error 就是 TD Target 和旧预测之间的差:
\underbrace{V(s)}_{\text{旧预测}} $$
它的符号很好读:
-
$\delta > 0$ :TD Target 比你原来想的更高,$V(s)$ 应该上调。 -
$\delta < 0$ :TD Target 比你原来想的更低,$V(s)$ 应该下调。 -
$\delta = 0$ :这一步看起来预测正好,不需要改。
:::details 慢慢拆:TD Error 为什么是学习信号?
如果
单步采样时,我们看不到完整平均值,只看到这一次真实发生的
这就是 TD Error。它可以理解成贝尔曼方程在这一次采样上的“没对齐程度”。
如果对所有可能的下一步取平均,TD Error 的期望是:
\mathbb{E}[r + \gamma V(s') \mid s]
- V(s) $$
当
所以 TD Error 的平均值越接近 0,说明价值函数越接近贝尔曼方程要求的自洽状态。
TD 更新可以写成:
如果用神经网络参数化
这看起来很像梯度下降,但它不是真正的梯度下降——因为 TD Target
- 价值更新的驱动信号:$V(s) \leftarrow V(s) + \alpha \delta$(本节)
- 优势函数的最简形式:$\hat{A}(s,a) = \delta = r + \gamma V(s') - V(s)$,衡量“这个动作比平均水平好多少”(第 6 章)
- GAE 的构建基石:$A^{\text{GAE}} = \sum_{l=0}^{\infty} (\gamma \lambda)^l \delta_{t+l}$,多个 TD Error 的指数衰减加权和(第 7 章)
这三种角色会在后面反复出现。先把 TD Error 记成一句话:它是价值函数没有对齐贝尔曼目标的那一小段差距。 :::
还是看 3 格走廊:
从
MC 必须等你走到
TD 只需要你从
所以 TD 的优势很清楚:它不等最终答案,而是用一步真实结果加下一站估计,边走边修。
:::details 思考题:TD Error 能不能永远为 0?
在确定性环境中,理论上可以:只要所有状态的
| DP | MC | TD | |
|---|---|---|---|
| 需要环境模型? | 是 | 否 | 否 |
| 需要完整轨迹? | 否 | 是 | 否 |
| 自举 | 是 | 否 | 是 |
| 偏差 | 无 | 无 | 有(但低方差) |
| 方差 | 低 | 高 | 中 |
| 代表场景 | 已知规则的小规模问题 | 有终止的采样任务 | 绝大多数无模型在线任务 |
演进逻辑:DP 精确但不现实 → MC 不需要模型但要等太久 → TD 不需要模型也不需要等。每一代都解决了前一代的核心局限。
学完这一节,我们获得了一项关键能力:从数据中估计价值函数。三种方法共享同一个核心——贝尔曼方程——只是“怎么拿到未来信息”的方式不同:
-
DP(动态规划):需要完美模型。直接用转移概率
$P$ 和奖励$R$ 精确迭代。它是理论基准,也就是“如果知道一切,价值该怎么算”。 -
MC(蒙特卡洛):不需要模型,但需要跑完一整局。用完整的真实回报
$G_t$ 更新。它的目标无偏,但方差很大,学习信号来得晚。 - TD(时序差分):不需要模型,走一步就更新。用“眼前的奖励 + 对未来的猜测($V(s')$)”来修正当前猜测。它有偏差但方差更低,是实际应用的主力。
- 统一视角(GPI):这些算法都可以拆解为“评估当前策略”和“根据价值改进策略”两个交替过程。
如果你是初学者,最应该掌握的是 TD。不是因为它最简单,而是因为它是现代 RL 的主力——PPO、SAC、TD3 等工业界广泛使用的算法都以 TD 为基础。理解了 TD Error 和自举的思想,你就能直接理解后续高级算法的核心。
此外,这条 MC→TD 的演进线不仅出现在价值估计中。在后续的第 5 章,我们将看到完全相同的演进出现在策略优化中:REINFORCE 就是策略版的 MC(跑完一整局用完整回报),Actor-Critic 就是策略版的 TD(走一步就用 TD Error 更新)。
现在,我们已经解决了“如果不知道环境模型,怎么估计