跳转至

01 - 时序差分学习基础

学习时间: 3-4小时 重要性: ⭐⭐⭐⭐⭐ 强化学习最核心的算法框架 前置知识: 蒙特卡洛方法、贝尔曼方程


🎯 学习目标

完成本章后,你将能够: - 理解TD学习的基本思想和TD误差 - 掌握TD(0)算法的完整推导和实现 - 理解TD与MC、DP的关系和区别 - 掌握TD学习的收敛性分析 - 能够实现并调试TD预测算法


1. 时序差分学习简介

1.1 从MC到TD:关键洞察

蒙特卡洛方法的局限: - 必须等待episode结束才能更新 - 高方差(使用实际回报) - 不适用于连续任务(无终止状态)

动态规划的局限: - 需要完整的模型(转移概率P和奖励R) - 计算量大

时序差分学习的突破

结合MC的采样和DP的自举,实现在线学习

Text Only
MC: G_t = R_{t+1} + γR_{t+2} + γ²R_{t+3} + ...  (等待完整episode)
DP: V(s) = Σ π(a|s) Σ p(s',r|s,a)[r + γV(s')]  (需要模型)
TD: V(s) ← V(s) + α[R_{t+1} + γV(s') - V(s)]   (自举+采样)

1.2 TD的核心思想

自举(Bootstrapping): - 使用当前的估计值来更新估计值 - 不需要等待最终回报 - 可以在线学习(每步都更新)

关键公式

\[V(S_t) \leftarrow V(S_t) + \alpha [R_{t+1} + \gamma V(S_{t+1}) - V(S_t)]\]

直观理解

Text Only
新估计 = 旧估计 + 学习率 × (目标 - 旧估计)

目标 = 即时奖励 + 折扣 × 下一个状态的估计值

1.3 TD误差

定义TD误差

\[\delta_t = R_{t+1} + \gamma V(S_{t+1}) - V(S_t)\]

TD误差的意义: - 衡量当前估计与"更好的估计"之间的差距 - 如果δ > 0:当前状态比预期好,应该增加V(s) - 如果δ < 0:当前状态比预期差,应该减少V(s)

与MC误差的对比

Text Only
MC误差: G_t - V(S_t)  (需要等到episode结束才能计算)
TD误差: R_{t+1} + γV(S_{t+1}) - V(S_t)  (每步都可以计算)


2. TD(0)算法

2.1 算法流程

TD(0)用于策略评估

Text Only
初始化: V(s) = 0, ∀s

对每个episode:
    初始化状态s

    当s不是终止状态时:
        执行动作a ~ π(·|s), 观察r, s'

        TD误差: δ = r + γV(s') - V(s)

        更新: V(s) ← V(s) + α × δ

        s ← s'

2.2 代码实现

Python
import numpy as np
from collections import defaultdict

def td_zero_prediction(env, policy, alpha=0.1, gamma=0.9, num_episodes=1000):
    """
    TD(0)策略评估

    参数:
        env: 环境
        policy: 策略,state -> action probabilities
        alpha: 学习率
        gamma: 折扣因子
        num_episodes: episode数量

    返回:
        V: 状态值函数估计
    """
    V = defaultdict(float)  # defaultdict访问不存在的键时返回默认值

    for episode in range(num_episodes):
        state, _ = env.reset()
        done = False

        while not done:
            # 根据策略选择动作
            action = np.random.choice(len(policy[state]), p=policy[state])

            # 执行动作
            next_state, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated

            # TD更新
            td_target = reward + gamma * V[next_state] * (not done)
            td_error = td_target - V[state]
            V[state] += alpha * td_error

            state = next_state

        if (episode + 1) % 100 == 0:
            # 计算当前策略的平均回报
            avg_reward = evaluate_policy(env, policy, V)
            print(f"Episode {episode + 1}/{num_episodes}, Avg Reward: {avg_reward:.2f}")

    return V

def evaluate_policy(env, policy, V, num_episodes=10):
    """评估策略的平均回报"""
    total_rewards = []

    for _ in range(num_episodes):
        state, _ = env.reset()
        done = False
        episode_reward = 0

        while not done:
            action = np.argmax(policy[state])
            next_state, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
            episode_reward += reward
            state = next_state

        total_rewards.append(episode_reward)

    return np.mean(total_rewards)

2.3 学习率的选择

学习率α的影响

α值 效果
太大(如0.5) 震荡,可能不收敛
适中(如0.1) 稳定收敛
太小(如0.01) 收敛慢
衰减(如1/t) 理论上保证收敛

常用学习率方案

Python
# 1. 常数学习率
alpha = 0.1

# 2. 线性衰减
alpha = max(0.01, 0.1 - episode * 0.0001)

# 3. 指数衰减
alpha = 0.1 * (0.995 ** episode)

# 4. 理论上保证收敛
alpha = 1 / (episode + 1)

3. TD vs MC vs DP

3.1 三者的关系

Text Only
            采样(Sampling)
    MC ←————————→ TD ←————————→ DP
      (无自举)   (自举+采样)   (无采样)
            自举(Bootstrapping)

3.2 详细对比

特性 DP MC TD(0)
需要模型
自举
采样
在线更新
每步计算 O(S²A) O(1) O(1)
偏差 0 0 >0
方差
连续任务

3.3 偏差-方差权衡

MC目标\(G_t\)(实际回报) - 无偏:\(\mathbb{E}[G_t] = V^\pi(S_t)\) - 高方差:包含很多随机步骤的累积

TD目标\(R_{t+1} + \gamma V(S_{t+1})\)(自举目标) - 有偏:\(\mathbb{E}[R_{t+1} + \gamma V(S_{t+1})] \neq V^\pi(S_t)\)(除非V已经收敛) - 低方差:只包含一步随机性

直观理解: - MC像"事后总结"(准确但慢) - TD像"边做边学"(快但可能有偏差)


4. TD学习的收敛性

4.1 收敛定理

定理(TD(0)的收敛性)

在满足以下条件时,TD(0)以概率1收敛到\(V^\pi\): 1. 策略\(\pi\)是固定的 2. 所有状态被无限次访问 3. 步长满足Robbins-Monro条件: $\(\sum_t \alpha_t = \infty, \quad \sum_t \alpha_t^2 < \infty\)$

4.2 收敛速率

定理(TD(0)的收敛速率)

使用步长\(\alpha_t = 1/t\)

\[\mathbb{E}[\|V_t - V^\pi\|^2] = O\left(\frac{1}{t}\right)\]

与MC的比较: - MC:\(O(1/\sqrt{n})\) 收敛速率 - TD:\(O(1/t)\) 收敛速率

TD收敛更快,但有偏差。

4.3 随机逼近视角

TD作为随机逼近

TD更新可以写成:

\[V_{t+1} = V_t + \alpha_t [h(V_t) + \xi_t]\]

其中: - \(h(V) = T^\pi V - V\)(贝尔曼残差) - \(\xi_t\) 是噪声

这符合Robbins-Monro随机逼近框架。


5. 批量TD学习

5.1 批量更新

思想:收集一批数据后,进行多次更新。

Python
def batch_td_learning(env, policy, alpha=0.1, gamma=0.9,
                      batch_size=100, num_batches=100):
    """
    批量TD学习

    收集batch_size个transition,然后进行多次更新
    """
    V = defaultdict(float)

    for batch_idx in range(num_batches):
        # 收集数据
        transitions = []
        for _ in range(batch_size):
            state, _ = env.reset()
            done = False

            while not done and len(transitions) < batch_size:
                action = np.random.choice(len(policy[state]), p=policy[state])
                next_state, reward, terminated, truncated, _ = env.step(action)
                done = terminated or truncated
                transitions.append((state, action, reward, next_state, done))
                state = next_state

        # 批量更新(多次遍历数据)
        for _ in range(10):  # 每个batch更新10次
            for state, action, reward, next_state, done in transitions:
                td_target = reward + gamma * V[next_state] * (not done)
                td_error = td_target - V[state]
                V[state] += alpha * td_error

        if (batch_idx + 1) % 10 == 0:
            print(f"Batch {batch_idx + 1}/{num_batches}")

    return V

5.2 批量vs在线

特性 在线TD 批量TD
内存需求
计算效率
收敛稳定性
样本效率

6. 实践练习

练习1:实现TD(0)并观察收敛

Python
# 使用附录中的GridWorld环境
from gridworld import GridWorld

env = GridWorld(size=5)

# 定义随机策略
n_states = env.get_state_space()
n_actions = env.get_action_space()
random_policy = np.ones((n_states, n_actions)) / n_actions

# 运行TD(0)
V = td_zero_prediction(env, random_policy, alpha=0.1, num_episodes=1000)

# 可视化值函数
import matplotlib.pyplot as plt

V_matrix = np.array([V[s] for s in range(n_states)]).reshape(5, 5)  # 重塑张量形状  # np.array创建NumPy数组
plt.imshow(V_matrix, cmap='viridis')
plt.colorbar()
plt.title('Value Function from TD(0)')
plt.show()

练习2:比较不同学习率

Python
alphas = [0.01, 0.05, 0.1, 0.3, 0.5]
results = {}

for alpha in alphas:
    V = td_zero_prediction(env, random_policy, alpha=alpha, num_episodes=500)
    results[alpha] = V

# 比较最终值函数的差异
for alpha, V in results.items():
    print(f"α={alpha}: Mean V = {np.mean(list(V.values())):.3f}")

练习3:TD vs MC对比

Python
# 实现MC预测(首次访问)
def mc_prediction(env, policy, gamma=0.9, num_episodes=1000):
    V = defaultdict(float)
    returns = defaultdict(list)

    for episode in range(num_episodes):
        episode_data = []
        state, _ = env.reset()
        done = False

        while not done:
            action = np.random.choice(len(policy[state]), p=policy[state])
            next_state, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
            episode_data.append((state, reward))
            state = next_state

        # 计算回报
        G = 0
        visited = set()
        for t in range(len(episode_data) - 1, -1, -1):
            state, reward = episode_data[t]
            G = gamma * G + reward

            if state not in visited:  # 首次访问
                visited.add(state)
                returns[state].append(G)
                V[state] = np.mean(returns[state])

    return V

# 对比TD和MC
td_V = td_zero_prediction(env, random_policy, alpha=0.1, num_episodes=1000)
mc_V = mc_prediction(env, random_policy, gamma=0.9, num_episodes=1000)

# 计算差异
diffs = [abs(td_V[s] - mc_V[s]) for s in range(n_states)]
print(f"Mean absolute difference: {np.mean(diffs):.4f}")

7. 本章总结

核心概念回顾

Text Only
时序差分学习 = 采样 + 自举

关键公式:
├── TD更新: V(s) ← V(s) + α[R + γV(s') - V(s)]
├── TD误差: δ = R + γV(s') - V(s)
└── 目标: R + γV(s') (自举目标)

与MC和DP的关系:
├── MC: 使用实际回报 G_t (无自举)
├── TD: 使用自举目标 (自举+采样)
└── DP: 使用期望 (无采样)

收敛性:
├── 步长条件: Σα=∞, Σα²<∞
├── 收敛速率: O(1/t)
└── 有偏但低方差

学习路径

Text Only
下一步学习:
├── SARSA算法 - On-Policy TD控制
├── Q-Learning算法 - Off-Policy TD控制
└── 探索与利用 - 平衡探索和利用

✅ 自测问题

  1. TD误差和MC误差有什么区别?为什么TD误差可以每步计算?

  2. TD学习为什么有偏差?这种偏差会随着训练消失吗?

  3. 比较TD(0)和MC的优缺点。在什么情况下你会选择TD而不是MC?

  4. Robbins-Monro条件的两个要求分别有什么意义?

  5. 设计一个实验验证TD(0)的收敛性。你会如何设置实验?


📚 延伸阅读

  1. Sutton & Barto《Reinforcement Learning: An Introduction》
  2. 第6章:Temporal-Difference Learning

  3. Sutton (1988)

  4. "Learning to predict by the methods of temporal differences"
  5. TD学习的开创性论文

  6. Dayan (1992)

  7. "The convergence of TD(λ) for general λ"
  8. TD(λ)收敛性的经典证明

准备好学习具体的TD控制算法了吗? 下一章我们将学习SARSA算法。

→ 下一步:02-SARSA算法.md