机器学习之Q学习

目录

  1. 简介
  2. 基础概念
  3. Q学习算法
  4. 数学原理
  5. 探索与利用
  6. 算法实现
  7. 收敛性与改进
  8. 应用场景
  9. 常见问题
  10. 参考文献

简介

Q学习(Q-Learning)是一种无模型强化学习算法,由 Watkins 和 Dayan 在 1992 年提出。它属于值迭代方法,通过学习状态-动作值函数(Q函数)来找到最优策略。

核心思想

Q学习的核心思想是通过与环境的交互,学习每个状态-动作对的长期累积回报期望值,即Q值。智能体根据Q值选择动作,从而逐步逼近最优策略。

主要特点

  • 无模型:不需要知道环境的转移概率和奖励函数
  • 离策略:学习的是最优策略,而不必遵循当前策略
  • 收敛性:在满足一定条件下保证收敛到最优Q函数

基础概念

马尔可夫决策过程 (MDP)

Q学习基于马尔可夫决策过程,由以下五元组定义:

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

其中:

  • S \mathcal{S} S:状态空间,所有可能状态的集合
  • A \mathcal{A} A:动作空间,所有可能动作的集合
  • P \mathcal{P} P:状态转移概率, P ( s ′ ∣ s , a ) \mathcal{P}(s'|s,a) P(ss,a) 表示在状态 s s s 执行动作 a a a 后转移到状态 s ′ s' s 的概率
  • R \mathcal{R} R:奖励函数, R ( s , a , s ′ ) \mathcal{R}(s,a,s') R(s,a,s) 表示执行动作后的即时奖励
  • γ \gamma γ:折扣因子, γ ∈ [ 0 , 1 ] \gamma \in [0,1] γ[0,1],表示未来奖励的重要性

Q函数

Q函数 Q ( s , a ) Q(s,a) Q(s,a) 表示在状态 s s s 下执行动作 a a a,并遵循最优策略所能获得的期望累积回报:

Q ( s , a ) = E [ ∑ t = 0 ∞ γ t r t ∣ s 0 = s , a 0 = a , π ∗ ] Q(s,a) = \mathbb{E}\left[\sum_{t=0}^{\infty} \gamma^t r_t \mid s_0 = s, a_0 = a, \pi^*\right] Q(s,a)=E[t=0γtrts0=s,a0=a,π]

贝尔曼最优方程

最优Q函数满足贝尔曼最优方程:

Q ∗ ( s , a ) = E [ r + γ max ⁡ a ′ Q ∗ ( s ′ , a ′ ) ∣ s , a ] Q^*(s,a) = \mathbb{E}\left[r + \gamma \max_{a'} Q^*(s',a') \mid s,a\right] Q(s,a)=E[r+γamaxQ(s,a)s,a]


Q学习算法

算法流程

Q学习通过迭代更新Q值来逼近最优Q函数。更新规则如下:

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)]

其中:

  • α \alpha α:学习率,控制更新的步长
  • r t + 1 r_{t+1} rt+1:执行动作 a t a_t at 后获得的即时奖励
  • s t + 1 s_{t+1} st+1:执行动作后的下一个状态

伪代码

初始化 Q(s,a) 为任意值,Q(terminal,·) = 0
对于每个回合:
    初始化状态 s
    对于每个时间步:
        根据策略(如 ε-贪婪)从 Q(s,·) 选择动作 a
        执行动作 a,观察奖励 r 和新状态 s'
        Q(s,a) ← Q(s,a) + α[r + γ max_a' Q(s',a') - Q(s,a)]
        s ← s'
        直到 s 为终止状态

数学原理

时序差分学习

Q学习属于时序差分(TD)学习方法,结合了蒙特卡洛方法和动态规划的优点。TD误差定义为:

δ t = r t + 1 + γ max ⁡ a ′ Q ( s t + 1 , a ′ ) − Q ( s t , a t ) \delta_t = r_{t+1} + \gamma \max_{a'} Q(s_{t+1},a') - Q(s_t,a_t) δt=rt+1+γamaxQ(st+1,a)Q(st,at)

TD误差衡量了当前估计与目标值之间的差异。

收敛性证明

Q学习在以下条件下保证收敛到最优Q函数:

  1. 遍历性:所有状态-动作对被无限次访问
  2. 学习率条件
    ∑ t = 0 ∞ α t = ∞ , ∑ t = 0 ∞ α t 2 < ∞ \sum_{t=0}^{\infty} \alpha_t = \infty, \quad \sum_{t=0}^{\infty} \alpha_t^2 < \infty t=0αt=,t=0αt2<
  3. 折扣因子 γ ∈ [ 0 , 1 ) \gamma \in [0,1) γ[0,1)

常用学习率调度: α t = 1 1 + visits ( s , a ) \alpha_t = \frac{1}{1 + \text{visits}(s,a)} αt=1+visits(s,a)1


探索与利用

ε-贪婪策略

在Q学习中,常用 ε-贪婪策略平衡探索与利用:

π ( a ∣ s ) = { 1 − ε + ε ∣ A ∣ , if  a = arg ⁡ max ⁡ a ′ Q ( s , a ′ ) ε ∣ A ∣ , otherwise \pi(a|s) = \begin{cases} 1 - \varepsilon + \frac{\varepsilon}{|\mathcal{A}|}, & \text{if } a = \arg\max_{a'} Q(s,a') \\ \frac{\varepsilon}{|\mathcal{A}|}, & \text{otherwise} \end{cases} π(as)={1ε+Aε,Aε,if a=argmaxaQ(s,a)otherwise

其中 ε \varepsilon ε 是探索概率,通常随时间衰减。

其他探索策略

  1. 玻尔兹曼(Softmax)策略
    π ( a ∣ s ) = exp ⁡ ( Q ( s , a ) / τ ) ∑ a ′ exp ⁡ ( Q ( s , a ′ ) / τ ) \pi(a|s) = \frac{\exp(Q(s,a)/\tau)}{\sum_{a'} \exp(Q(s,a')/\tau)} π(as)=aexp(Q(s,a)/τ)exp(Q(s,a)/τ)
    其中 τ \tau τ 是温度参数,控制探索程度。

  2. Upper Confidence Bound (UCB)
    a t = arg ⁡ max ⁡ a [ Q ( s , a ) + c ln ⁡ t N ( s , a ) ] a_t = \arg\max_a \left[ Q(s,a) + c \sqrt{\frac{\ln t}{N(s,a)}} \right] at=argamax[Q(s,a)+cN(s,a)lnt ]

  3. Thompson Sampling:基于贝叶斯推断的探索策略


算法实现

Python实现示例

import numpy as np
from collections import defaultdict

class QLearningAgent:
    def __init__(self, state_space, action_space, 
                 learning_rate=0.1, discount_factor=0.99, 
                 epsilon=1.0, epsilon_decay=0.995, epsilon_min=0.01):
        """
        Q学习智能体
        
        参数:
            state_space: 状态空间大小
            action_space: 动作空间大小
            learning_rate: 学习率 α
            discount_factor: 折扣因子 γ
            epsilon: 探索概率 ε
            epsilon_decay: ε衰减率
            epsilon_min: ε最小值
        """
        self.q_table = defaultdict(lambda: np.zeros(action_space))
        self.alpha = learning_rate
        self.gamma = discount_factor
        self.epsilon = epsilon
        self.epsilon_decay = epsilon_decay
        self.epsilon_min = epsilon_min
        self.action_space = action_space
    
    def choose_action(self, state):
        """ε-贪婪策略选择动作"""
        if np.random.random() < self.epsilon:
            # 探索:随机选择动作
            return np.random.randint(self.action_space)
        else:
            # 利用:选择Q值最大的动作
            return np.argmax(self.q_table[state])
    
    def learn(self, state, action, reward, next_state, done):
        """
        Q值更新
        
        Q(s,a) ← Q(s,a) + α[r + γ max_a' Q(s',a') - Q(s,a)]
        """
        current_q = self.q_table[state][action]
        
        if done:
            target_q = reward
        else:
            target_q = reward + self.gamma * np.max(self.q_table[next_state])
        
        # TD误差更新
        self.q_table[state][action] += self.alpha * (target_q - current_q)
        
        # 衰减探索概率
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay

简单迷宫问题示例

class MazeEnvironment:
    def __init__(self):
        self.grid_size = 5
        self.start = (0, 0)
        self.goal = (4, 4)
        self.obstacles = [(2, 2), (3, 1), (1, 3)]
        self.state = self.start
        
        # 动作:上、下、左、右
        self.actions = [0, 1, 2, 3]  # 0:上, 1:下, 2:左, 3:右
        self.action_map = {
            0: (-1, 0),  # 上
            1: (1, 0),   # 下
            2: (0, -1),  # 左
            3: (0, 1)    # 右
        }
    
    def reset(self):
        self.state = self.start
        return self.state
    
    def step(self, action):
        row, col = self.state
        dr, dc = self.action_map[action]
        
        new_row, new_col = row + dr, col + dc
        
        # 检查边界
        if 0 <= new_row < self.grid_size and 0 <= new_col < self.grid_size:
            # 检查障碍物
            if (new_row, new_col) not in self.obstacles:
                self.state = (new_row, new_col)
        
        # 计算奖励
        if self.state == self.goal:
            reward = 10
            done = True
        else:
            reward = -0.1  # 每步小惩罚,鼓励快速到达目标
            done = False
        
        return self.state, reward, done

# 训练Q学习智能体
def train_q_learning():
    env = MazeEnvironment()
    agent = QLearningAgent(
        state_space=env.grid_size * env.grid_size,
        action_space=4,
        learning_rate=0.1,
        discount_factor=0.95,
        epsilon=1.0,
        epsilon_decay=0.995
    )
    
    episodes = 1000
    
    for episode in range(episodes):
        state = env.reset()
        total_reward = 0
        done = False
        
        while not done:
            action = agent.choose_action(state)
            next_state, reward, done = env.step(action)
            agent.learn(state, action, reward, next_state, done)
            state = next_state
            total_reward += reward
        
        if episode % 100 == 0:
            print(f"Episode {episode}, Total Reward: {total_reward}, Epsilon: {agent.epsilon:.3f}")
    
    return agent

# 运行训练
trained_agent = train_q_learning()

收敛性与改进

收敛性问题

  1. 学习率选择:过大会导致震荡,过小会导致收敛缓慢
  2. 探索策略:探索不足可能陷入局部最优
  3. 状态空间:大规模状态空间导致Q表过大

改进方法

1. 深度Q网络 (DQN)

使用神经网络近似Q函数,解决大规模状态空间问题:

Q ( s , a ; θ ) ≈ Q ∗ ( s , a ) Q(s,a;\theta) \approx Q^*(s,a) Q(s,a;θ)Q(s,a)

DQN的核心技术:

  • 经验回放:存储经验并随机采样
  • 目标网络:稳定训练过程
2. Double Q-Learning

解决Q学习的高估问题:

Q ( s , a ) ← Q ( s , a ) + α [ r + γ Q ( s ′ , arg ⁡ max ⁡ a ′ Q ( s ′ , a ′ ; θ ) ; θ ′ ) − Q ( s , a ; θ ) ] Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma Q(s', \arg\max_{a'} Q(s',a';\theta); \theta') - Q(s,a;\theta) \right] Q(s,a)Q(s,a)+α[r+γQ(s,argamaxQ(s,a;θ);θ)Q(s,a;θ)]

3. 优先经验回放

根据TD误差的绝对值对经验进行优先级采样。

4. Dueling DQN

将Q函数分解为状态价值和优势函数:

Q ( s , a ; θ , α , β ) = V ( s ; θ , β ) + A ( s , a ; θ , α ) Q(s,a;\theta,\alpha,\beta) = V(s;\theta,\beta) + A(s,a;\theta,\alpha) Q(s,a;θ,α,β)=V(s;θ,β)+A(s,a;θ,α)

5. 多步Q学习

使用n步回报加速学习:

G t ( n ) = r t + 1 + γ r t + 2 + ⋯ + γ n − 1 r t + n + γ n max ⁡ a ′ Q ( s t + n , a ′ ) G_t^{(n)} = r_{t+1} + \gamma r_{t+2} + \cdots + \gamma^{n-1} r_{t+n} + \gamma^n \max_{a'} Q(s_{t+n},a') Gt(n)=rt+1+γrt+2++γn1rt+n+γnamaxQ(st+n,a)


应用场景

1. 游戏AI

Q学习及其变体在游戏中广泛应用:

  • Atari游戏:DQN在57个Atari游戏中达到人类水平
  • 围棋:AlphaGo结合了Q学习和蒙特卡洛树搜索
  • 即时战略游戏:如StarCraft II

2. 机器人控制

  • 路径规划:在未知环境中寻找最优路径
  • 机械臂控制:学习复杂的运动技能
  • 自动驾驶:决策与控制策略学习

3. 资源调度

  • 数据中心调度:优化任务分配
  • 网络路由:动态路由决策
  • 云计算资源分配

4. 推荐系统

  • 个性化推荐:学习用户偏好
  • 广告投放:优化广告展示策略

5. 金融交易

  • 算法交易:学习交易策略
  • 投资组合优化

常见问题

Q1: Q学习与SARSA的区别?

Q学习是离策略算法,学习最优Q值:
Q ( s , a ) ← Q ( s , a ) + α [ r + γ max ⁡ a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma \max_{a'} Q(s',a') - Q(s,a) \right] Q(s,a)Q(s,a)+α[r+γamaxQ(s,a)Q(s,a)]

SARSA是在策略算法,学习当前策略的Q值:
Q ( s , a ) ← Q ( s , a ) + α [ r + γ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma Q(s',a') - Q(s,a) \right] Q(s,a)Q(s,a)+α[r+γQ(s,a)Q(s,a)]

SARSA更保守,考虑实际执行的动作;Q学习更激进,直接学习最优值。

Q2: 如何选择学习率α和折扣因子γ?

  • 学习率α:通常在0.01到0.3之间,可以随时间衰减
  • 折扣因子γ:根据任务性质选择:
    • 短期任务:γ = 0.8-0.9
    • 长期任务:γ = 0.95-0.99

Q3: Q学习何时会失败?

  1. 非马尔可夫环境:状态信息不完整
  2. 连续状态空间:需要函数近似
  3. 延迟奖励:奖励信号稀疏或延迟
  4. 探索不足:陷入局部最优

Q4: 如何处理连续动作空间?

Q学习本身适用于离散动作空间,处理连续动作需要:

  1. 动作离散化:将连续动作离散化
  2. 使用策略梯度方法:如REINFORCE、Actor-Critic
  3. DDPG(Deep Deterministic Policy Gradient):结合DQN和策略梯度

附录

A. Q学习变体对比

算法 类型 主要特点 适用场景
Q-Learning 离策略 学习最优Q值 离散状态和动作
SARSA 在策略 学习当前策略Q值 需要保守策略
Expected SARSA 在策略 使用期望值 减少方差
Double Q-Learning 离策略 减少高估 高估问题严重
DQN 离策略 深度网络近似 大规模状态空间
Dueling DQN 离策略 分解状态价值和优势 需要状态价值估计

B. 常用超参数范围

参数 符号 典型范围 说明
学习率 α 0.01-0.3 控制更新步长
折扣因子 γ 0.9-0.99 控制未来奖励权重
探索概率 ε 0.01-1.0 初始值,随时间衰减
衰减率 ε_decay 0.99-0.999 控制ε衰减速度

C. 性能评估指标

  1. 累积回报:每个回合的总奖励
  2. 收敛速度:达到稳定性能所需的回合数
  3. 稳定性:性能的波动程度
  4. 样本效率:达到目标性能所需的经验数量
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐