Hana's Blog
RL笔记(8):DQNBlur image

引言(Introduction)#

在之前的 Q-Learning 算法中,我们使用一个矩阵(Q-Table)来记录每个状态动作对 (s,a)(s,a) 的价值。 这种方法有两个致命局限:

  1. 内存限制:如果状态空间很大(例如围棋 1017010^{170}),表格根本存不下。这被称为维度灾难 (Curse of Dimensionality)
  2. 泛化能力差:对于没见过的状态,表格无法给出估计,而在连续状态空间中,几乎很难遇到完全一样的状态。

为了解决这个问题,我们引入函数拟合 (Function Approximation)深度Q网络 (Deep Q-Network, DQN) 使用一个神经网络 Qω(s,a)Q_\omega(s, a) 来近似 Q(s,a)Q^*(s, a),输入状态 ss,输出所有离散动作的 Q 值。


深度 Q 网络 (DQN)#

核心定义#

在 DQN 中,我们使用参数为 ω\omega 的神经网络来拟合动作价值函数。

  • 输入:状态 ss(例如游戏的屏幕像素)。
  • 输出:每个动作 aAa \in \mathcal{A} 对应的价值 Q(s,a)Q(s,a)

损失函数#

类似于 Q-Learning,我们希望神经网络的输出逼近 TD Target。 对于一条数据 (si,ai,ri,si)(s_i, a_i, r_i, s_i^\prime),目标是最小化均方误差:

J(ω)=12Ni=1N[Qω(si,ai)预测值(ri+γmaxaQω(si,a))TD Target]2J(\omega)=\frac{1}{2N}\sum_{i=1}^{N}\left[ \underbrace{Q_\omega(s_i,a_i)}_{\text{预测值}} - \underbrace{\left(r_i+\gamma \max_{a^\prime}Q_\omega(s_i^\prime,a^\prime)\right)}_{\text{TD Target}} \right]^2

然而,直接这样训练是不稳定的。DQN 引入了两大“法宝”来解决这个问题。


创新一:经验回放 (Experience Replay)#

在一般的监督学习中,我们假设训练数据是独立同分布 (i.i.d) 的。但在强化学习中,智能体采集的数据是序列相关的(现在的状态依赖于上一秒的状态)。

做法: 维护一个回放缓冲区 (Replay Buffer) R\mathcal{R}

  1. 智能体与环境交互,将产生的数据 (st,at,rt,st+1)(s_t, a_t, r_t, s_{t+1}) 存入缓冲区。
  2. 训练时,从缓冲区中随机采样一个批次 (Batch) 的数据进行梯度下降。

作用

  1. 打破相关性:随机采样消除了数据之间的时间相关性,满足独立同分布假设,稳定网络训练。
  2. 提高样本效率:一条经验数据可以被多次采样利用,而不是用完即弃。

创新二:目标网络 (Target Network)#

在原版 Q-Learning 中,TD Target 的计算也依赖于当前网络参数 ω\omega

yi=ri+γmaxaQω(si,a)y_i = r_i + \gamma \max_{a'} Q_\omega(s'_i, a')

这就好比“在射箭的同时,靶子也在动”。更新 ω\omega 会同时改变预测值和目标值,容易导致震荡发散。

做法: 引入一个结构相同但参数独立的目标网络 (Target Network),参数记为 ω\omega^-。 计算目标值时使用 ω\omega^-,更新网络时优化 ω\omega

yi=ri+γmaxaQω(si,a)y_i = r_i + \gamma \max_{a'} Q_{\omega^-}(s'_i, a')

更新规则

  • 训练网络 ω\omega:每个 step 都进行梯度下降更新。
  • 目标网络 ω\omega^-:每隔 CC 步(例如 1000 步),将 ω\omega 的值复制给 ω\omega^- (ωω\omega^- \leftarrow \omega)。

💡 直觉:固定住靶子一会儿,让射手(训练网络)安心瞄准,等射手练好了,再把靶子挪到新的位置。


DQN 算法伪代码#

  Initialize main network Qω and target network Qω with weights ω  Initialize replay buffer R  For episode e=1E do:Initialize state sFor step t=1T do:Select action a using ϵ-greedy based on Qω(s)Execute a, observe r,sStore transition (s,a,r,s) in RIf R>batch_size:Sample batch {(si,ai,ri,si)}i=1N from RCalculate targets: yi=ri+γmaxaQω(si,a)Update ω by minimizing 1N(Qω(si,ai)yi)2Every C steps: ωωssEnd For  End For\begin{aligned} & \bullet \; \text{Initialize main network } Q_\omega \text{ and target network } Q_{\omega^-} \text{ with weights } \omega \\ & \bullet \; \text{Initialize replay buffer } \mathcal{R} \\ & \bullet \; \textbf{For } \text{episode } e = 1 \to E \textbf{ do}: \\ & \bullet \qquad \text{Initialize state } s \\ & \bullet \qquad \textbf{For } \text{step } t = 1 \to T \textbf{ do}: \\ & \bullet \qquad \qquad \text{Select action } a \text{ using } \epsilon\text{-greedy based on } Q_\omega(s) \\ & \bullet \qquad \qquad \text{Execute } a, \text{ observe } r, s' \\ & \bullet \qquad \qquad \text{Store transition } (s, a, r, s') \text{ in } \mathcal{R} \\ & \bullet \qquad \qquad \textbf{If } |\mathcal{R}| > \text{batch\_size}: \\ & \bullet \qquad \qquad \qquad \text{Sample batch } \{(s_i, a_i, r_i, s'_i)\}_{i=1}^N \text{ from } \mathcal{R} \\ & \bullet \qquad \qquad \qquad \text{Calculate targets: } y_i = r_i + \gamma \max_{a'} Q_{\omega^-}(s'_i, a') \\ & \bullet \qquad \qquad \qquad \text{Update } \omega \text{ by minimizing } \frac{1}{N}\sum (Q_\omega(s_i, a_i) - y_i)^2 \\ & \bullet \qquad \qquad \qquad \textbf{Every } C \text{ steps: } \omega^- \leftarrow \omega \\ & \bullet \qquad \qquad s \leftarrow s' \\ & \bullet \qquad \textbf{End For} \\ & \bullet \; \textbf{End For} \end{aligned}

进阶 1:Double DQN#

问题:过高估计 (Overestimation)#

DQN 在计算目标值时使用了 max\max 操作:yi=r+γmaxaQ(s,a)y_i = r + \gamma \max_{a'} Q(s', a')。 由于神经网络本身存在估计误差,max\max 操作倾向于选择那些被高估的值。这种最大化偏差 (Maximization Bias) 会导致 Q 值普遍偏大,影响策略学习。

解决方案#

解耦选择与评估

  • 选择动作:使用当前网络 QωQ_\omega 来决定哪个动作最好(即 argmax)。
  • 评估价值:使用目标网络 QωQ_{\omega^-} 来计算那个动作的价值。

Double DQN 目标公式

yi=ri+γQω(si,argmaxaQω(si,a))y_i = r_i + \gamma Q_{\omega^-}(s'_i, \underset{a'}{\operatorname{argmax}} Q_\omega(s'_i, a'))

进阶 2:Dueling DQN#

核心思想#

在很多状态下,状态本身的价值选择什么动作更重要。 例如:在赛车游戏中,如果前面是死胡同(状态差),无论你向左转还是向右转(动作),价值都很低。 Dueling DQN 改变了网络结构,将 Q 值分解为两部分:

  1. 状态价值函数 (Value Function) V(s)V(s):仅与状态有关。
  2. 优势函数 (Advantage Function) A(s,a)A(s,a):与动作有关,表示动作 aa 相比平均情况好多少。
Q(s,a)=V(s)+A(s,a)Q(s, a) = V(s) + A(s, a)

可辨识性问题 (Identifiability)#

如果直接用 V+AV+A,网络会出现唯一性问题(VV 加 10,AA 减 10,总和 QQ 不变)。为了让 VVAA 能被唯一确定,我们需要强行约束 AA 的某种性质。

聚合公式 (Aggregation): 通常让优势函数 AA 对于某个状态的均值为 0,或者最大值为 0。

Q(s,a;θ,α,β)=V(s;θ,β)+(A(s,a;θ,α)1AaA(s,a;θ,α))Q(s,a;\theta,\alpha,\beta)=V(s;\theta,\beta) + \left( A(s,a;\theta,\alpha) - \frac{1}{|\mathcal{A}|}\sum_{a^\prime}A(s,a^\prime;\theta,\alpha) \right)

或者:

Q(s,a;θ,α,β)=V(s;θ,β)+(A(s,a;θ,α)maxaA(s,a;θ,α))Q(s,a;\theta,\alpha,\beta)=V(s;\theta,\beta) + \left( A(s,a;\theta,\alpha) - \max_{a^\prime}A(s,a^\prime;\theta,\alpha) \right)

优点

  • 在动作对环境影响不大的状态下,能更快地学习状态价值 VV
  • 极大地提高了训练效率和稳定性。
RL笔记(8):DQN
https://hana-blog.top/blog/rl-note-8
Author 菊花花
Published at December 17, 2025
Comment seems to stuck. Try to refresh?✨