菜单

深度Q网络

相关源文件

本文档提供了 labml_nn 仓库中深度Q网络(DQN)实现的技术概述。它涵盖了核心算法、模型架构、优先经验回放和训练过程。有关其他强化学习算法(如近端策略优化)的信息,请参阅近端策略优化

1. DQN 算法概述

深度Q网络结合了Q学习与深度神经网络,用于近似离散动作空间下的动作价值函数。此实现包括对原始DQN算法的几项重要扩展

  1. 对偶网络架构 - 分离状态价值和动作优势估计
  2. 优先经验回放 - 更频繁地采样重要转换
  3. 双Q学习 - 减少Q值中的过高估计偏差

来源: labml_nn/rl/dqn/__init__.py12-17 labml_nn/rl/dqn/experiment.py9-12

2. 最优动作价值函数

DQN算法旨在找到最优动作价值函数Q*(s,a),它表示在状态s下采取动作a并随后遵循最优策略时的预期回报

$$Q^*(s,a) = \max_\pi \mathbb{E} \Big[r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + ... | s_t = s, a_t = a, \pi\Big]$$

这可以用贝尔曼方程表示

$$Q^(s,a) = \mathop{\mathbb{E}}{s' \sim \varepsilon} \Big[r + \gamma \max{a'} Q^ (s', a') | s, a\Big]$$

来源: labml_nn/rl/dqn/__init__.py34-48

3. 神经网络架构

3.1 对偶网络架构

此实现使用对偶网络架构,将Q函数分解为状态价值(V)和动作优势(A)

$$Q(s,a) = V(s) + \Big(A(s,a) - \frac{1}{|\mathcal{A}|} \sum_{a' \in \mathcal{A}} A(s,a')\Big)$$

这种架构允许网络学习哪些状态是有价值的,而无需学习每个动作对每个状态的影响。

来源: labml_nn/rl/dqn/model.py18-46

3.2 网络实现

该网络包括

  1. 卷积层 - 处理84×84的游戏帧
    • 3个带ReLU激活的卷积层
  2. 价值流 - 估计状态价值V(s)
    • 全连接层 (512→256→1)
  3. 优势流 - 估计动作优势A(s,a)
    • 全连接层 (512→256→4)

最终的Q值通过结合价值流和优势流计算得出。

来源: labml_nn/rl/dqn/model.py49-106

4. 训练过程

4.1 损失函数

DQN使用带有目标网络的时间差分(TD)学习,以提供稳定的训练目标

$$\mathcal{L}i(\theta_i) = \mathop{\mathbb{E}}{(s,a,r,s') \sim U(D)} \Bigg[\bigg(r + \gamma \textcolor{orange}{Q}\Big(s', \mathop{\operatorname{argmax}}_{a'} \textcolor{cyan}{Q}(s', a'; \textcolor{cyan}{\theta_i}); \textcolor{orange}{\theta_i^{-}}\Big) - Q(s,a;\theta_i)\bigg) ^ 2\Bigg]$$

其中

  • $\theta_i$ - 在线网络的参数
  • $\theta_i^{-}$ - 目标网络的参数(定期更新)
  • $D$ - 经验回放缓冲区

此实现使用Huber损失而非MSE,以提高对异常值的稳定性。

来源: labml_nn/rl/dqn/__init__.py50-99 labml_nn/rl/dqn/__init__.py102-165

4.2 双Q学习

为减少过高估计偏差,双Q学习将动作选择和评估分离开来

  1. 在线网络选择最佳动作: $\mathop{\operatorname{argmax}}_{a'} Q(s', a'; \theta_i)$
  2. 目标网络评估该动作: $Q(s', \mathop{\operatorname{argmax}}_{a'} Q(s', a'; \theta_i); \theta_i^{-})$

来源: labml_nn/rl/dqn/__init__.py68-99 labml_nn/rl/dqn/experiment.py164-205

5. 优先经验回放

5.1 优先采样

优先经验回放(PER)以与TD误差成比例的概率采样转换

$$P(i) = \frac{p_i^\alpha}{\sum_k p_k^\alpha}$$

其中

  • $p_i = |\delta_i| + \epsilon$ 是优先级(TD误差加上一个小的常数)
  • $\alpha$ 决定了优先级的程度($\alpha$=0表示均匀采样)

5.2 重要性采样校正

为了纠正非均匀采样引入的偏差,应用了重要性采样权重

$$w_i = \bigg(\frac{1}{N} \frac{1}{P(i)}\bigg)^\beta$$

其中 $\beta$ 在训练过程中从初始值退火到1。

5.3 二叉线段树实现

此实现使用二叉线段树,以高效计算

  1. 优先级的累积和(用于采样)
  2. 最小优先级(用于重要性权重的归一化)

这为两项操作提供了O(log n)的性能。

来源: labml_nn/rl/dqn/replay_buffer.py20-277

6. 训练循环实现

Trainer 类管理整个DQN训练过程

  1. 初始化

    • 创建模型和目标模型
    • 创建优先经验回放缓冲区
    • 设置探索策略
    • 初始化环境工作器
  2. 采样循环

    • 使用ε-贪婪策略采样动作
    • 从环境中收集转换
    • 将转换存储到经验回放缓冲区
  3. 训练循环

    • 从经验回放缓冲区采样批次
    • 使用双Q学习计算TD目标
    • 更新网络参数
    • 更新经验回放缓冲区中的优先级
    • 定期更新目标网络

6.1 关键参数

参数描述默认
updates(更新次数)总更新次数1,000,000
epochs(周期数)每次更新的训练周期数8
n_workers(工作器数量)并行环境数量8
worker_steps(每个工作器步数)每次更新每个工作器的步数4
mini_batch_size(小批量大小)训练批次大小32
update_target_model(目标模型更新频率)目标网络更新频率250
learning_rate(学习率)初始学习率1e-4

来源: labml_nn/rl/dqn/experiment.py38-252 labml_nn/rl/dqn/experiment.py254-290

6.2 探索策略

此实现使用带有线性时间表的ε-贪婪探索策略

  • 从ε = 1.0开始(100%随机动作)
  • 在25,000次更新后降至0.1
  • 在训练中点进一步降至0.01

来源: labml_nn/rl/dqn/experiment.py109-127 labml_nn/rl/dqn/experiment.py67-73

7. 代码组织

DQN实现主要分为四个文件

  1. __init__.py - 主要算法定义和损失函数
  2. model.py - 对偶网络架构实现
  3. replay_buffer.py - 优先经验回放实现
  4. experiment.py - 训练循环和环境交互

该系统通过 labml_nn.rl.game 模块中的 Worker 类与游戏环境进行交互。

来源: labml_nn/rl/dqn/__init__.py1-166 labml_nn/rl/dqn/model.py1-107 labml_nn/rl/dqn/replay_buffer.py1-278 labml_nn/rl/dqn/experiment.py1-291