强化学习系列——时序差分学习(SARSA与Q-Learning)

强化学习系列——时序差分学习(SARSA与Q-Learning)

  • 介绍
    • 一、基本概念回顾
    • 二、时序差分学习(TD Learning)思想
      • 1. TD(0) 公式
    • 三、TD与蒙特卡洛、动态规划的比较
    • 四、状态-动作值的TD学习:SARSA与Q-learning
      • 1. SARSA(on-policy)
      • 2. Q-Learning(off-policy)
    • 五、TD(λ) —— 广义TD方法
      • 1. λ-返回(n步回报加权平均):
      • 2. 实现方式:**Eligibility Traces(资格迹)**
    • 六、TD学习的优点
    • 七、与深度学习结合:Deep Q-Network(DQN)
    • 八、总结
  • 代码示例
    • SARSA
    • Q-Learning
    • ✅ Q-learning 示例代码(使用 Gym)
      • 环境:FrozenLake-v1(4x4)
    • 输出解释
    • ✅ 运行前准备
    • ✅ 测试训练好的策略

时序差分学习(Temporal-Difference Learning, TD Learning)是强化学习中一种关键的值函数估计方法,结合了蒙特卡洛方法(Monte Carlo)动态规划(Dynamic Programming)的优点。它在智能体与环境交互的过程中,通过对当前经验进行更新,逐步逼近真实的值函数。


介绍

一、基本概念回顾

  • 强化学习环境一般建模为一个马尔可夫决策过程(MDP),用一个五元组表示:

    ( S , A , P , R , γ ) (\mathcal{S}, \mathcal{A}, P, R, \gamma) (S,A,P,R,γ)

    • S \mathcal{S} S:状态空间
    • A \mathcal{A} A:动作空间
    • P ( s ′ ∣ s , a ) P(s'|s,a) P(ss,a):状态转移概率
    • R ( s , a ) R(s,a) R(s,a):奖励函数
    • γ ∈ [ 0 , 1 ) \gamma \in [0,1) γ[0,1):折扣因子
  • 目标是学习一个策略 π \pi π 下的状态值函数或状态-动作值函数:

    • 状态值函数:

      V π ( s ) = E π [ ∑ t = 0 ∞ γ t R t + 1 ∣ S 0 = s ] V^\pi(s) = \mathbb{E}_\pi \left[ \sum_{t=0}^{\infty} \gamma^t R_{t+1} \mid S_0 = s \right] Vπ(s)=Eπ[t=0γtRt+1S0=s]

    • 状态-动作值函数:

      Q π ( s , a ) = E π [ ∑ t = 0 ∞ γ t R t + 1 ∣ S 0 = s , A 0 = a ] Q^\pi(s,a) = \mathbb{E}_\pi \left[ \sum_{t=0}^{\infty} \gamma^t R_{t+1} \mid S_0 = s, A_0 = a \right] Qπ(s,a)=Eπ[t=0γtRt+1S0=s,A0=a]


二、时序差分学习(TD Learning)思想

TD方法的核心思想是利用从环境中获得的一个步长的估计来更新当前状态的值,而不必等到整个回合结束。

1. TD(0) 公式

最简单的TD方法是 TD(0),更新公式如下:

V ( S t ) ← V ( S t ) + α [ R t + 1 + γ V ( S t + 1 ) − V ( S t ) ] V(S_t) \leftarrow V(S_t) + \alpha \left[ R_{t+1} + \gamma V(S_{t+1}) - V(S_t) \right] V(St)V(St)+α[Rt+1+γV(St+1)V(St)]

其中:

  • α \alpha α:学习率
  • R t + 1 + γ V ( S t + 1 ) R_{t+1} + \gamma V(S_{t+1}) Rt+1+γV(St+1) 是对 V ( S t ) V(S_t) V(St)TD目标
  • δ t = R t + 1 + γ V ( S t + 1 ) − V ( S t ) \delta_t = R_{t+1} + \gamma V(S_{t+1}) - V(S_t) δt=Rt+1+γV(St+1)V(St)TD误差

因此更新可简写为:

V ( S t ) ← V ( S t ) + α δ t V(S_t) \leftarrow V(S_t) + \alpha \delta_t V(St)V(St)+αδt


三、TD与蒙特卡洛、动态规划的比较

方法 是否需要模型 更新时机 收敛性
蒙特卡洛 回合结束后 有限状态下收敛
动态规划 批量同步更新 依赖完整模型
时序差分 每步实时更新 收敛更快,更稳定

四、状态-动作值的TD学习:SARSA与Q-learning

1. SARSA(on-policy)

SARSA 是一个on-policy 的方法,表示用当前策略采样,并使用当前策略的行为值函数进行更新。

Q ( S t , A t ) ← Q ( S t , A t ) + α [ R t + 1 + γ Q ( S t + 1 , A t + 1 ) − Q ( S t , A t ) ] Q(S_t, A_t) \leftarrow Q(S_t, A_t) + \alpha \left[ R_{t+1} + \gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t) \right] Q(St,At)Q(St,At)+α[Rt+1+γQ(St+1,At+1)Q(St,At)]

2. Q-Learning(off-policy)

Q-learning 是一个off-policy方法,使用当前策略采样,但用最优动作进行更新:

Q ( S t , A t ) ← Q ( S t , A t ) + α [ R t + 1 + γ max ⁡ a Q ( S t + 1 , a ) − Q ( S t , A t ) ] Q(S_t, A_t) \leftarrow Q(S_t, A_t) + \alpha \left[ R_{t+1} + \gamma \max_{a} Q(S_{t+1}, a) - Q(S_t, A_t) \right] Q(St,At)Q(St,At)+α[Rt+1+γamaxQ(St+1,a)Q(St,At)]


五、TD(λ) —— 广义TD方法

TD(λ) 是 TD 的一个广义形式,结合了 TD(0) 和蒙特卡洛方法,通过引入一个迹衰减因子 λ

1. λ-返回(n步回报加权平均):

定义 n n n-步回报为:

G t ( n ) = R t + 1 + γ R t + 2 + ⋯ + γ n − 1 R t + n + γ n V ( S t + n ) G_t^{(n)} = R_{t+1} + \gamma R_{t+2} + \cdots + \gamma^{n-1} R_{t+n} + \gamma^n V(S_{t+n}) Gt(n)=Rt+1+γRt+2++γn1Rt+n+γnV(St+n)

TD(λ)使用不同步长的回报加权平均:

G t λ = ( 1 − λ ) ∑ n = 1 ∞ λ n − 1 G t ( n ) G_t^\lambda = (1 - \lambda) \sum_{n=1}^\infty \lambda^{n-1} G_t^{(n)} Gtλ=(1λ)n=1λn1Gt(n)

然后用 G t λ G_t^\lambda Gtλ 来更新值函数:

V ( S t ) ← V ( S t ) + α ( G t λ − V ( S t ) ) V(S_t) \leftarrow V(S_t) + \alpha (G_t^\lambda - V(S_t)) V(St)V(St)+α(GtλV(St))

2. 实现方式:Eligibility Traces(资格迹)

资格迹是一种跟踪哪些状态最近被访问的机制:

E t ( s ) = γ λ E t − 1 ( s ) + 1 ( S t = s ) E_t(s) = \gamma \lambda E_{t-1}(s) + \mathbf{1}(S_t = s) Et(s)=γλEt1(s)+1(St=s)

更新规则为:

V ( s ) ← V ( s ) + α δ t E t ( s ) V(s) \leftarrow V(s) + \alpha \delta_t E_t(s) V(s)V(s)+αδtEt(s)

这是一种“前向-后向等价”实现方式。


六、TD学习的优点

  • 不依赖环境模型(model-free)
  • 可以在线、逐步学习
  • 收敛速度快于蒙特卡洛
  • 可扩展到函数逼近(如DQN)

七、与深度学习结合:Deep Q-Network(DQN)

强化学习系列——深度Q网络(DQN算法)

在实际问题中(如图像输入),状态空间往往极其庞大,无法保存所有状态值。此时引入神经网络函数逼近器进行值函数估计,结合TD更新目标:

Loss = ( y t − Q ( s t , a t ; θ ) ) 2 \text{Loss} = \left( y_t - Q(s_t, a_t; \theta) \right)^2 Loss=(ytQ(st,at;θ))2

y t = R t + 1 + γ max ⁡ a Q ( s t + 1 , a ; θ − ) y_t = R_{t+1} + \gamma \max_a Q(s_{t+1}, a; \theta^-) yt=Rt+1+γamaxQ(st+1,a;θ)

其中 θ \theta θ 是当前网络参数, θ − \theta^- θ 是目标网络参数。


八、总结

时序差分学习提供了一种高效、可扩展的值函数估计方法,其基本形式 TD(0)、进阶形式 SARSA 和 Q-learning、以及广义形式 TD(λ),构成了强化学习算法的核心基础。

代码示例

SARSA

import numpy as np

# 定义环境
num_states = 5
num_actions = 3
Q = np.zeros((num_states, num_actions))  # 动作值函数
rewards = np.array([[-1, 0, -1],  # 状态0的奖励表
                    [-1, -1, 0],  # 状态1的奖励表
                    [0, -1, -1],  # 状态2的奖励表
                    [-1, 0, -1],  # 状态3的奖励表
                    [-1, -1, 0]])  # 状态4的奖励表
gamma = 0.8  # 折扣因子
alpha = 0.1  # 学习率
epsilon = 0.1  # ε-greedy策略的ε值

# 定义SARSA算法
def sarsa(num_episodes):
    for episode in range(num_episodes):
        state = 0  # 初始状态
        action = epsilon_greedy(state)  # 初始动作

        while state != num_states - 1:  # 直到达到终止状态
            next_state = action  # 下一个状态为当前动作
            next_action = epsilon_greedy(next_state)  # 下一个动作

            # 使用SARSA更新动作值函数
            Q[state, action] += alpha * (rewards[state, action] + gamma * Q[next_state, next_action] - Q[state, action])

            state = next_state
            action = next_action

# ε-greedy策略
def epsilon_greedy(state):
    if np.random.uniform(0, 1) < epsilon:
        action = np.random.randint(num_actions)  # 随机选择一个动作
    else:
        action = np.argmax(Q[state])  # 选择具有最大动作值的动作
    return action

# 运行SARSA算法
sarsa(num_episodes=100)

# 输出结果
print("最优动作值函数:")
print(Q)

Q-Learning

下面是一个Q-learning的简单实现示例,使用 OpenAI Gym 中的经典环境 FrozenLake(冰湖):


✅ Q-learning 示例代码(使用 Gym)

环境:FrozenLake-v1(4x4)

  • 动作:上下左右(共4个动作)
  • 状态:16个位置
  • 目标:从起点走到终点,避免掉进冰窟
import gym
import numpy as np
import random

# 创建环境
env = gym.make("FrozenLake-v1", is_slippery=False)  # 禁用滑动以简化学习

# Q表初始化:状态数 × 动作数
state_size = env.observation_space.n
action_size = env.action_space.n
Q = np.zeros((state_size, action_size))

# 超参数
alpha = 0.1        # 学习率
gamma = 0.99       # 折扣因子
epsilon = 1.0      # 探索率(ε-greedy)
epsilon_min = 0.01
epsilon_decay = 0.995
episodes = 1000
max_steps = 100

# 训练过程
for episode in range(episodes):
    state = env.reset()[0]
    done = False

    for _ in range(max_steps):
        # ε-greedy 策略选择动作
        if random.uniform(0, 1) < epsilon:
            action = env.action_space.sample()
        else:
            action = np.argmax(Q[state, :])

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

        # Q值更新
        best_next_action = np.argmax(Q[next_state, :])
        td_target = reward + gamma * Q[next_state, best_next_action]
        td_error = td_target - Q[state, action]
        Q[state, action] += alpha * td_error

        state = next_state

        if done:
            break

    # 衰减 ε
    epsilon = max(epsilon_min, epsilon * epsilon_decay)

# 显示学习到的Q表
print("Learned Q-table:")
print(np.round(Q, 2))

输出解释

  • Q-table 是一个 16 × 4 16 \times 4 16×4 的矩阵,每一行表示一个状态,每一列表示一个动作。

  • 训练完成后,可以用 Q-table 导出策略:

    π ( s ) = arg ⁡ max ⁡ a Q ( s , a ) \pi(s) = \arg\max_a Q(s,a) π(s)=argamaxQ(s,a)


✅ 运行前准备

安装 Gym(如果尚未安装):

pip install gym

✅ 测试训练好的策略

# 测试策略
state = env.reset()[0]
env.render()
for _ in range(20):
    action = np.argmax(Q[state])
    state, reward, done, _, _ = env.step(action)
    env.render()
    if done:
        print("Reached goal!" if reward == 1 else "Fell into hole!")
        break

你可能感兴趣的:(深度学习,算法,Pytorch,人工智能)