目录

Mathematical Foundations of Reinforcement Learning:强化学习的数学基石——从入门到精通的完整指南

Mathematical Foundations of Reinforcement Learning:强化学习的数学基石

目标读者:计算机科学/人工智能研究生、RL研究者、工程师 前置知识:概率论、线性代数基础 特色:网格世界(Grid World)贯穿全书的统一示例,数学严谨但叙述友好 难度定位:⭐⭐⭐⭐ 专家设计


§1 学习目标

完成本篇文章后,你将能够:

  1. 理解RL数学框架:从数学角度掌握策略、状态值、动作值等核心概念
  2. 掌握Bellman方程:推导和应用Bellman方程与Bellman最优方程
  3. 理解经典算法:Value Iteration、Policy Iteration、Q-Learning、Sarsa等
  4. 掌握Monte Carlo与TD方法:两种无模型学习方法的核心原理与对比
  5. 理解深度RL基础:DQN、Experience Replay、Policy Gradient、Actor-Critic
  6. 理解随机近似与SGD:理解RL算法的优化理论根基

§2 背景与动机:为何需要这本书

2.1 现有教材的局限

教材类型代表作局限
工程实现派Sutton & Barto《RL导论》数学推导较少,直觉多于证明
理论数学派Bertsekas《RL与最优控制》数学要求过高,对初学者不友好
深度学习派Spinning Up (OpenAI)侧重深度RL,缺乏理论基础

2.2 本书的独特定位

《Mathematical Foundations of Reinforcement Learning》 由西湖大学施若石(ShiYuzhao)教授编写,于2025年由Springer出版。本书定位:

  • 数学严谨但叙述友好:不是"显然可得",而是逐步推导
  • 统一示例贯穿全书:所有概念和算法都用网格世界(Grid World)阐释
  • 从基础到算法系统覆盖:10章内容形成完整知识体系
  • 配套资源丰富:54节配套视频(B站210万+播放)、PDF完整版、代码实现

2.3 影响力

指标数据
GitHub Stars15,384
Forks1,443
B站播放量210万+
YouTube视频54节(英/中双语)
第三方代码Python、MATLAB、R、C++

§3 核心概念:RL的数学基础

3.1 网格世界(Grid World)

本书统一使用网格世界作为示例环境:

  0   1   2   3
┌───┬───┬───┬───┐
│ S │   │   │ G │  S=起始点, G=目标点
├───┼───┼───┼───┤
│   │   │   │   │
├───┼───┼───┼───┤
│   │   │   │   │
└───┴───┴───┴───┘
Agent在4×3网格中移动

网格世界特性

  • 状态空间 S = {0, 1, …, 11}(12个格子)
  • 动作空间 A = {上, 下, 左, 右}
  • 奖励:每步-1(鼓励快速到达目标)
  • 终止条件:到达目标G

3.2 马尔夫决策过程(MDP)

RL问题建模为MDP:$(S, A, P, R, \gamma)$

# MDP五元组
class MDP:
    S: List[State]      # 状态空间
    A: List[Action]     # 动作空间
    P: Dict             # 转移概率 P(s'|s,a)
    R: Callable         # 奖励函数 R(s,a,s')
    gamma: float         # 折扣因子 γ ∈ [0,1]

核心关系

  • 策略 $\pi(a|s) = P(a_t|a_{t-1},…)$:状态到动作的概率分布
  • 状态值函数 $V^\pi(s) = E_\pi[G_t|S_t=s]$:从状态s出发的期望累积奖励
  • 动作值函数 $Q^\pi(s,a) = E_\pi[G_t|S_t=s, A_t=a]$:在状态s执行动作a的期望累积奖励

§4 核心方程:Bellman方程体系

4.1 回报(Return)与折扣因子

回报是累积折扣奖励:

$$G_t = R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + … = \sum_{k=0}^{\infty} \gamma^k R_{t+k+1}$$

折扣因子 $\gamma$ 的物理意义

  • $\gamma \to 0$:只关注立即奖励(短视)
  • $\gamma \to 1$:平等对待近期和远期奖励(长期规划)

4.2 Bellman方程

状态值函数的Bellman方程

$$V^\pi(s) = \sum_{a \in A} \pi(a|s) \sum_{s’ \in S} P(s’|s,a)[R(s,a,s’) + \gamma V^\pi(s’)]$$

含义:当前状态值 = 所有可能动作的加权平均(立即奖励 + 折扣未来值)

动作值函数的Bellman方程

$$Q^\pi(s,a) = \sum_{s’ \in S} P(s’|s,a)[R(s,a,s’) + \gamma \sum_{a’ \in A} \pi(a’|s’)Q^\pi(s’,a’)]$$

4.3 Bellman最优方程

最优状态值

$$V^(s) = \max_{a \in A} \sum_{s’ \in S} P(s’|s,a)[R(s,a,s’) + \gamma V^(s’)]$$

最优动作值

$$Q^(s,a) = \sum_{s’ \in S} P(s’|s,a)[R(s,a,s’) + \gamma \max_{a’ \in A} Q^(s’,a’)]$$


§5 经典算法:基于模型的规划方法

5.1 Value Iteration(值迭代)

核心思想:直接求解最优值函数,然后提取最优策略

def value_iteration(mdp, theta=1e-6, gamma=0.9):
    V = {s: 0 for s in mdp.S}
    
    while True:
        delta = 0
        for s in mdp.S:
            v = V[s]
            V[s] = max(sum(
                mdp.P(s'|s,a) * (mdp.R(s,a,s') + gamma * V[s'])
                for s' in mdp.S
            ) for a in mdp.A)
            delta = max(delta, abs(v - V[s]))
        
        if delta < theta:
            break
    
    # 提取最优策略
    policy = {}
    for s in mdp.S:
        policy[s] = argmax_a sum(
            mdp.P(s'|s,a) * (mdp.R(s,a,s') + gamma * V[s'])
            for s' in mdp.S
        )
    
    return V, policy

收敛性:保证收敛到唯一最优值函数( contraction mapping)

5.2 Policy Iteration(策略迭代)

核心思想:交替进行策略评估和策略改进

def policy_iteration(mdp, gamma=0.9):
    # 随机初始化策略
    policy = {s: random.choice(mdp.A) for s in mdp.S}
    
    while True:
        # 策略评估:求解 V^π
        V = evaluate_policy(policy, mdp, gamma)
        
        # 策略改进
        policy_stable = True
        for s in mdp.S:
            old_action = policy[s]
            policy[s] = argmax_a sum(
                mdp.P(s'|s,a) * (mdp.R(s,a,s') + gamma * V[s'])
                for s' in mdp.S
            )
            if old_action != policy[s]:
                policy_stable = False
        
        if policy_stable:
            break
    
    return V, policy

5.3 两者对比

特性Value IterationPolicy Iteration
每次迭代更新所有状态值评估当前策略 → 改进
收敛速度慢(每次扫描整个状态空间)快(通常少量迭代收敛)
每次迭代开销O(|S|^2·|A|)策略评估 O(|S|^2·|A|)
适用场景状态空间大、转移概率已知小到中型状态空间

§6 无模型方法:与环境交互学习

6.1 Monte Carlo方法

核心思想:通过完整episode采样估计值函数

def first_visit_mc(env, num_episodes, gamma=0.9, epsilon=0.1):
    Q = {s: {a: 0 for a in env.A} for s in env.S}
    returns = {s: {a: [] for a in env.A} for s in env.S}
    
    for episode in range(num_episodes):
        episode_history = []
        state = env.reset()
        
        while not env.done:
            # Epsilon-greedy策略
            if random.random() < epsilon:
                action = random.choice(env.A)
            else:
                action = argmax_a Q[state][a]
            
            next_state, reward, done = env.step(action)
            episode_history.append((state, action, reward))
            state = next_state
        
        # 计算回报
        G = 0
        for t in reversed(range(len(episode_history))):
            s, a, r = episode_history[t]
            G = r + gamma * G
            returns[s][a].append(G)
            Q[s][a] = mean(returns[s][a])
    
    return Q

MC vs DP

  • DP需要完整环境模型(P和R)
  • MC通过采样学习,无需环境模型
  • MC适用于episodic任务,DP适用于连续任务

6.2 Temporal-Difference (TD) Learning

核心思想:结合MC和DP的思想,通过bootstrapping逐步更新

TD(0)算法

$$V(s_t) \leftarrow V(s_t) + \alpha[R_{t+1} + \gamma V(s_{t+1}) - V(s_t)]$$

括号内为TD误差:$\delta_t = R_{t+1} + \gamma V(s_{t+1}) - V(s_t)$

def td_zero(env, num_steps, alpha=0.1, gamma=0.9, epsilon=0.1):
    V = {s: 0 for s in env.S}
    
    for _ in range(num_steps):
        state = env.reset()
        done = False
        
        while not done:
            if random.random() < epsilon:
                action = random.choice(env.A)
            else:
                action = argmax_a Q(state, a)  # 需要Q值
    
    return V

6.3 Sarsa与Q-Learning

Sarsa(On-policy TD控制)

$$Q(s,a) \leftarrow Q(s,a) + \alpha[R + \gamma Q(s’,a’) - Q(s,a)]$$

def sarsa(env, num_episodes, alpha=0.1, gamma=0.9, epsilon=0.1):
    Q = defaultdict(lambda: defaultdict(float))
    
    for episode in range(num_episodes):
        state = env.reset()
        action = epsilon_greedy(Q, state, epsilon)
        done = False
        
        while not done:
            next_state, reward, done = env.step(action)
            next_action = epsilon_greedy(Q, next_state, epsilon)
            
            if done:
                td_target = reward
            else:
                td_target = reward + gamma * Q[next_state][next_action]
            
            td_error = td_target - Q[state][action]
            Q[state][action] += alpha * td_error
            
            state = next_state
            action = next_action
    
    return Q

Q-Learning(Off-policy TD控制)

$$Q(s,a) \leftarrow Q(s,a) + \alpha[R + \gamma \max_{a’} Q(s’,a’) - Q(s,a)]$$

def q_learning(env, num_episodes, alpha=0.1, gamma=0.9, epsilon=0.1):
    Q = defaultdict(lambda: defaultdict(float))
    
    for episode in range(num_episodes):
        state = env.reset()
        done = False
        
        while not done:
            action = epsilon_greedy(Q, state, epsilon)
            next_state, reward, done = env.step(action)
            
            # 关键区别:使用max_a' Q(s',a')
            td_target = reward + gamma * max(Q[next_state].values())
            td_error = td_target - Q[state][action]
            Q[state][action] += alpha * td_error
            
            state = next_state
    
    return Q

§7 深度强化学习:从表格到函数逼近

7.1 Value Function Approximation

当状态空间连续或巨大时,使用函数逼近 $V(s) \approx \hat{V}(s; w)$

梯度下降

$$\Delta w = \alpha (V^\pi(s) - \hat{V}(s; w)) \nabla_w \hat{V}(s; w)$$

7.2 Deep Q-Network (DQN)

DQN的核心创新:

  1. Experience Replay(经验回放):存储到replay buffer,随机采样打破相关性
  2. Target Network(目标网络):分离目标计算,提高稳定性
class DQN:
    def __init__(self, state_dim, action_dim):
        self.q_network = NeuralNetwork(state_dim, action_dim)
        self.target_network = NeuralNetwork(state_dim, action_dim)
        self.replay_buffer = ReplayBuffer(capacity=100000)
        self.gamma = 0.99
        self.epsilon = 1.0
    
    def train_step(self, batch_size=32):
        states, actions, rewards, next_states, dones = self.replay_buffer.sample(batch_size)
        
        # 使用目标网络计算目标Q值
        with torch.no_grad():
            next_q = self.target_network(next_states).max(1)[0]
            target_q = rewards + (1 - dones) * self.gamma * next_q
        
        # 更新Q网络
        current_q = self.q_network(states).gather(1, actions)
        loss = MSE(current_q, target_q)
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()
    
    def update_target_network(self):
        # 定期同步目标网络
        self.target_network.load_state_dict(self.q_network.state_dict())

7.3 DQN变种概览

变种核心改进
Double DQN使用Double Q解决Q值过估计问题
Dueling DQN分离V(s)和A(s,a)估计
Prioritized Replay优先回放TD误差大的样本
Noisy Nets用噪声替代epsilon-greedy探索

§8 策略梯度与Actor-Critic

8.1 策略梯度基础

目标:直接优化策略参数 $\theta$

$$J(\theta) = V^{\pi_\theta}(s_0)$$

策略梯度定理

$$\nabla_\theta J(\theta) = E_{\tau \sim \pi_\theta}[\sum_{t=0}^{T-1} \nabla_\theta \log \pi_\theta(a_t|s_t) G_t]$$

8.2 REINFORCE算法

def reinforce(env, num_episodes, gamma=0.99, lr=0.001):
    policy_network = PolicyNetwork()
    optimizer = torch.optim.Adam(policy_network.parameters(), lr=lr)
    
    for episode in range(num_episodes):
        log_probs = []
        rewards = []
        state = env.reset()
        done = False
        
        while not done:
            action, log_prob = policy_network.sample(state)
            log_probs.append(log_prob)
            state, reward, done = env.step(action)
            rewards.append(reward)
        
        # 计算回报
        G = 0
        returns = []
        for r in reversed(rewards):
            G = r + gamma * G
            returns.insert(0, G)
        
        # 策略梯度更新
        policy_loss = []
        for log_prob, G in zip(log_probs, returns):
            policy_loss.append(-log_prob * G)
        
        optimizer.zero_grad()
        sum(policy_loss).backward()
        optimizer.step()

8.3 Actor-Critic架构

Actor(策略)和Critic(值函数)结合:

class ActorCritic:
    def __init__(self, state_dim, action_dim):
        self.actor = PolicyNetwork(state_dim, action_dim)
        self.critic = ValueNetwork(state_dim)
    
    def update(self, state, action, reward, next_state, done, gamma=0.99):
        # Critic更新:TD(0)
        value = self.critic(state)
        with torch.no_grad():
            next_value = self.critic(next_state)
            td_target = reward + (1 - done) * gamma * next_value
        critic_loss = F.mse_loss(value, td_target)
        
        # Actor更新:使用TD误差作为advantage
        advantage = td_target - value
        action_log_prob = self.actor.log_prob(state, action)
        actor_loss = -(action_log_prob * advantage.detach())
        
        # 联合更新
        self.actor_optimizer.zero_grad()
        self.critic_optimizer.zero_grad()
        (actor_loss + critic_loss).backward()
        self.actor_optimizer.step()
        self.critic_optimizer.step()

§9 书籍资源与学习路径

9.1 章节结构

部分章节核心内容
第一部分:基础工具第1章基本概念(状态、动作、策略、奖励)
第2章Bellman方程(状态值与动作值)
第3章Bellman最优方程
第二部分:算法第4章Value Iteration与Policy Iteration
第5章Monte Carlo方法
第6章随机近似与SGD
第7章TD学习(Sarsa、Q-Learning)
第8章值函数逼近与DQN
第9章策略梯度方法
第10章Actor-Critic方法

9.2 配套资源

资源链接说明
英文视频YouTube Playlist54节全套课程
中文视频B站(210万+播放)施老师原版授课
PDF全文GitHub仓库免费下载
代码实现第三方Python/MATLAB见GitHub仓库

B站视频链接

9.3 学习建议

入门路径

  1. 先看施老师B站视频,建立直觉
  2. 阅读第1-3章,理解数学框架
  3. 实现网格世界上的各种算法
  4. 学习第7章TD方法,掌握Q-Learning
  5. 进阶第8-10章,理解深度RL基础

代码实践

  • 官方提供网格世界环境(Python/MATLAB)
  • 第三方Python实现:zhoubay/Code-for-Mathematical-Foundations-of-Reinforcement-Learning
  • 建议先跑通网格世界实验,再尝试CartPole等 Gym 环境

§10 常见问题

Q1:需要多少数学基础? A:概率论(期望、方差、条件概率)和线性代数(矩阵运算)即可。附录包含基础知识回顾。

Q2:和Sutton的书相比有什么区别? A:本书更强调数学推导和算法设计动机,Sutton的书更注重直觉和应用。本书可作为Sutton的"数学补充"。

Q3:代码在哪里? A:官方不提供算法代码(作业需要自己实现),但GitHub有多个第三方实现。

Q4:如何获取PDF? A:直接从GitHub仓库下载,或购买Springer印刷版。


相关资源

  • GitHub仓库:https://github.com/MathFoundationRL/Book-Mathematical-Foundation-of-Reinforcement-Learning
  • 作者主页:https://www.shiyuzhao.net
  • B站视频:https://space.bilibili.com/2044042934
  • Springer书籍页面:https://link.springer.com/book/9789819739431