🏠 总目录📚 本教程 05 · 蒙特卡洛与时序差分 ← →
📑 本页目录(点开跳转)

05 · 蒙特卡洛与时序差分

⏱ 20 分钟 | ⭐ 不知道规则时,怎么学


🎯 一句话

不知道环境规则?那就去试。 蒙特卡洛(MC):试完一整局,用真实结果更新。 时序差分(TD):每走一步就更新,用「猜测」去修正「猜测」。⭐


🎲 一、蒙特卡洛:跑完整局再算账

关键信息

💡 人话:玩完一局,看看每个局面最后实际得了多少分,然后把估计值往真实值方向调一点。

✅ 优点 ❌ 缺点
无偏:G 是真实回报,不含猜测 方差大:一局的运气影响很大
不需要知道环境模型 必须等回合结束 ⭐
概念简单 不能用于没有终点的任务

⚠️ 「必须等回合结束」是致命的: 下一盘围棋 200 步、一段对话几十轮、机器人可能永远不停 —— 等到结束才更新一次,学习效率太低。


⚡ 二、时序差分:走一步就更新

核心想法:不等真实的 G 了,用「一步奖励 + 对下一状态的估计」来代替它。

$$V(s_t) \leftarrow V(s_t) + \alpha\big[\underbrace{r_{t+1} + \gamma V(s_{t+1})}_{\text{TD 目标}} - V(s_t)\big]$$

方括号里那一坨叫 TD 误差 $\delta_t$:

$$\delta_t = r_{t+1} + \gamma V(s_{t+1}) - V(s_t)$$

💡 人话翻译:

「我原本以为这里值 5 分。走了一步拿到 1 分,发现下一个地方值 6 分。 那这里应该值 1 + 0.9×6 = 6.4 分才对。我低估了 1.4 分,赶紧往上调一点。」

🔑 这就是「用猜测修正猜测」(bootstrapping)

结果对照

MC: V(s) ← V(s) + α[ G − V(s)] G 是真实的 ✅
TD: V(s) ← V(s) + α[r + γV(s') − V(s)] V(s') 是【猜的】⭐
听起来很不靠谱:拿一个估计值去更新另一个估计值?
但它确实收敛,而且通常比 MC 快得多

💡 为什么它能work:

因为 r 是真实的。每次更新都注入了一点真实信息, 这些真实信息会顺着状态链条一步步传播回去 —— 传播得慢,但方向是对的。


⚖️ 三、MC vs TD:一张表说清

蒙特卡洛 MC 时序差分 TD
何时更新 回合结束后 每一步 ⭐
偏差 无偏 ✅ 有偏(用了估计值)
方差 大 ❌ 小 ✅
能否用于无限回合 ❌ ✅ ⭐
收敛速度 慢 通常快得多 ⭐
对初值敏感 否 是

🔑 这是一个典型的偏差-方差权衡 (🔗 数学原理第 8 章): MC 用真值但噪声大;TD 引入偏差换来方差大幅下降。 实践中 TD 几乎总是赢 —— 因为方差才是强化学习的主要敌人。

💡 一个直观的例子说清差别

信息关系

你每天上班,估计通勤要多久。
周一:出门估 30 分钟→路上堵车→实际 50 分钟
MC 的做法:
等到到达公司,才知道是 50 分钟
把「出门时的估计」直接往 50 调
TD 的做法:
刚上高速就发现堵了,此刻重新估计「还要 40 分钟」
立刻把「出门时的估计」往 (已花10分 + 40分) = 50 调 ⭐
不用等到公司
⭐ TD 的优势:坏消息一出现就能学,不用等结局

🌉 四、中间地带:n 步 TD 与 TD(λ)

对照

TD(0): 只看 1 步 r₁ + γV(s₁)

2 步 : r₁ + γr₂ + γ²V(s₂)

n 步 : r₁ + · + γⁿ⁻¹rₙ + γⁿV(sₙ)

MC : 看到底(n = ∞)

⭐ TD(0) 和 MC 是同一条光谱的两端

TD(λ):把所有 n 步的结果按 λ 加权平均,一个参数在两端之间滑动。

💡 实践中的常用值:n = 5 左右,或者 GAE(第 10 章)里 λ = 0.95。 纯 TD(0) 偏差偏大,纯 MC 方差偏大,中间最好 —— 这几乎是所有现代算法的选择。


🔨 五、能跑的代码

import numpy as np

def td0(env, policy, n_episodes=5000, alpha=0.1, gamma=0.9):
    V = np.zeros(env.n_states)
    for _ in range(n_episodes):
        s = env.reset()
        done = False
        while not done:
            a = policy(s)
            s2, r, done = env.step(a)
            target = r + gamma * V[s2] * (not done)   # ⭐ 终止态没有未来
            V[s] += alpha * (target - V[s])           # ⭐ 核心就这一行
            s = s2
    return V

⚠️ 两个必踩的坑:

坑 后果 修法
终止态忘了乘 (not done) 把不存在的"下一状态价值"算进去 → 价值虚高、不收敛 ⭐ 终止时 target 只有 r
α 设成固定值且偏大 一直震荡不收敛 从 0.1 起,或让 α 随访问次数衰减

📉 六、关于学习率 α

$$V(s) \leftarrow V(s) + \alpha[\text{目标} - V(s)]$$

算一算

α = 1 :完全相信最新一次的经验(噪声全吃进来)

α = 0.1 :每次挪 10%,相当于对最近约 10 次经验做平均 ⭐

α → 0 :几乎不更新

⭐ 直觉:α 就是「你多信任最新这一次经验」

💡 收敛的理论条件:α 要逐渐衰减(Σα=∞ 且 Σα²<∞,比如 α=1/次数)。 但实践中几乎都用固定的小 α —— 因为环境常常在变(尤其 RLHF 里策略一直在动), 固定 α 能持续跟踪变化,衰减到 0 反而学不动了。


🔗 七、和站内其他章的关系

相关的地方 这里的位置
第 3 章贝尔曼方程 TD 目标就是贝尔曼方程的右边 ⭐
第 4 章动态规划 DP 用真实 P 算期望;TD 用采样代替期望
数学原理 08 MC vs TD 是标准的偏差方差权衡
ML基础 09学习率 α 是同一个概念

⭐ 一句话串起前五章: 动态规划用「已知的 P」算期望,MC 用「采样的真实回报」,TD 用「采样一步 + 自己的估计」。 三者在解同一个贝尔曼方程,只是右边那一项怎么来的不同。


✅ 检查点

  1. MC 和 TD 各自什么时候更新?
  2. TD 误差的公式是什么?用人话说它在算什么?
  3. 什么是 bootstrapping?为什么"用猜测修正猜测"能work?
  4. MC 和 TD 在偏差、方差上各是什么情况?为什么实践中 TD 通常赢?
  5. 用通勤那个例子说明 TD 的优势。
  6. TD(0) 和 MC 是什么关系?中间地带是什么?实践常用哪里?
  7. 代码里终止态为什么要乘 (not done)?不乘会怎样?
  8. 理论上 α 该衰减,为什么实践中常用固定值?
👀 答案
  1. MC 在回合结束后用真实回报 G 更新;TD 每走一步就更新。
  2. δ = r + γV(s') − V(s)。人话:"我原以为这里值 5 分,走一步拿到 1 分且下个地方值 6 分,那这里该值 1+0.9×6=6.4,我低估了,往上调。"
  3. 用一个估计值 V(s') 去更新另一个估计值 V(s)。能work是因为 r 是真实的——每次更新都注入一点真实信息,顺着状态链条一步步传播回去。
  4. MC 无偏但方差大;TD 有偏但方差小。实践 TD 通常赢,因为方差才是强化学习的主要敌人。
  5. 出门估 30 分钟,刚上高速就发现堵车。TD 此刻就能更新(已花10分+还要40分=50分);MC 必须等到公司才知道。坏消息一出现就能学,不用等结局。
  6. 同一条光谱的两端:TD(0) 看 1 步,MC 看到底(n=∞),中间是 n 步 TD 和 TD(λ)。实践常用 n=5 左右或 GAE 的 λ=0.95 ——纯 TD(0) 偏差大、纯 MC 方差大,中间最好。
  7. 因为终止态没有未来。不乘会把不存在的"下一状态价值"算进去,导致价值虚高、不收敛。
  8. 因为环境常常在变(尤其 RLHF 里策略一直在动),固定 α 能持续跟踪变化;衰减到 0 反而学不动了。

🛑 可以停在这里

⚡ 走神救援

先记住这几件事

下一节 👉 06-Q-learning与SARSA.md ⭐

打卡记录保存在你的浏览器里,首页能看到总进度