[控场AI]
· 6 分钟阅读· 3,287 字

DQN入门:概念、代码与数学全解析

DQN入门:概念、代码与数学全解析

Reddit一页纸DQN笔记梳理了深度强化学习经典算法的概念、代码与数学基础。

本文基于Reddit上的一页纸DQN笔记,系统梳理了深度Q网络(DQN)的核心内容。文章首先对比传统Q Learning的表格法与DQN的神经网络函数近似,指出DQN通过神经网络解决连续状态空间问题,并引入经验回放和目标网络来稳定训练。接着,文章展示了DQN训练循环的伪代码,涵盖动作选择、经验存储、采样、损失计算和网络更新等关键步骤。最后,从数学角度解释了贝尔曼最优方程和均方贝尔曼误差(MSBE)损失函数,并说明了目标网络的作用。文章总结认为,该笔记以概念、代码和数学三位一体的方式为初学者提供了紧凑的入门材料,建议读者动手实现以加深理解。

深度强化学习(RL)的入门门槛常常让不少人望而却步,尤其是当DQN(Deep Q-Network)出现时,概念、代码与数学的三重交织更让人感到困惑。最近,Reddit上一位作者发布了一页纸的DQN笔记,试图用最简洁的方式拆解这一经典算法。本文基于该笔记,结合DQN的核心思想与实现细节,为你梳理一条清晰的学习路径。

Reddit原帖截图

DQN的核心概念:从表格到函数

传统Q Learning依赖一个表格来存储每个状态-动作对的Q值,但当状态空间连续或巨大时,表格法便不再可行。DQN的关键创新在于用神经网络来近似Q函数,即学习一个参数化的函数,输入状态(或状态-动作对),输出对应的Q值。这样一来,无需显式存储所有Q值,网络可以泛化到未见过的状态。作者在笔记中强调,DQN本质上是将Q Learning的更新目标转化为一个回归问题,通过最小化预测Q值与目标Q值之间的差距来训练网络。

这一转变带来了两个核心挑战:样本之间的相关性以及目标Q值的非平稳性。为此,DQN引入了经验回放(Experience Replay)和目标网络(Target Network)两大机制。经验回放通过存储并随机采样过去的转移来打破数据相关性,而目标网络则定期复制主网络的参数,以稳定训练目标。这些概念在笔记中均有简明扼要的说明。

Q Learning与DQN的关系:Q Learning是一种无模型的强化学习算法,它通过维护一个Q表来学习每个状态-动作对的价值。其更新规则基于贝尔曼方程:Q(s,a) ← Q(s,a) + α[r + γ max_a' Q(s',a') - Q(s,a)]。当状态空间巨大或连续时,Q表无法存储,DQN用神经网络参数化Q函数Q(s,a;θ)来近似Q表,从而将强化学习问题转化为函数拟合问题。这种函数近似方法使得算法能够泛化到未见过的状态,但也引入了训练不稳定等挑战。

经验回放(Experience Replay):经验回放是DQN中用于打破数据相关性的关键技术。在强化学习中,智能体产生的连续经验(状态、动作、奖励、下一状态)之间具有强相关性,直接用于训练神经网络会导致灾难性遗忘和训练不稳定。经验回放通过将经验存储在一个固定大小的缓冲区中,并从中随机采样小批量数据来更新网络,从而打破时间相关性,使数据更接近独立同分布。此外,经验回放还提高了数据利用率,因为每个经验可以被多次采样使用。

目标网络(Target Network):目标网络是DQN中用于稳定训练目标的机制。在标准Q Learning中,目标值r + γ max_a' Q(s',a')依赖于当前Q函数,这导致目标值随参数更新而不断变化,形成“移动目标”问题。DQN引入一个结构相同但参数固定的目标网络Q(s,a;θ^-)来计算目标值,并定期将主网络的参数复制到目标网络。这样,在一段时间内目标值保持稳定,减少了训练振荡,提高了收敛性。

代码实现:关键片段与逻辑

笔记中提供了代码片段,展示了DQN训练循环的核心步骤。以下是一个简化的伪代码框架,体现了主要的逻辑流:

# 初始化主网络Q和目标网络Q_target
# 初始化经验回放缓冲区D
for episode in range(num_episodes):
    state = env.reset()
    while not done:
        # 使用epsilon-greedy策略选择动作
        action = select_action(state, epsilon)
        next_state, reward, done = env.step(action)
        # 存储转移到D
        D.push((state, action, reward, next_state, done))
        # 从D中随机采样一个批次
        batch = D.sample(batch_size)
        # 计算目标Q值
        targets = compute_targets(batch, Q_target)
        # 计算损失并更新主网络
        loss = mse_loss(Q(batch.states, batch.actions), targets)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        state = next_state
    # 定期更新目标网络
    if episode % update_freq == 0:
        Q_target.load_state_dict(Q.state_dict())

作者在笔记中特别指出,目标Q值的计算方式取决于是否使用Double DQN等变体。在标准DQN中,目标Q值通常为reward + gamma * max(Q_target(next_state)),其中gamma是折扣因子。代码片段虽短,但涵盖了动作选择、经验存储、采样、损失计算和网络更新等关键环节。

数学基础:贝尔曼方程与损失函数

DQN的数学根基是贝尔曼最优方程。对于状态-动作对(s, a),最优Q值满足:

Q*(s, a) = E[r + gamma * max_a' Q*(s', a')]

其中期望是对随机转移和奖励而言。DQN使用神经网络Q(s, a; theta)来近似Q*,并通过最小化均方贝尔曼误差(MSBE)来学习参数theta:

L(theta) = E[(r + gamma * max_a' Q(s', a'; theta^-) - Q(s, a; theta))^2]

这里theta^-是目标网络的参数,定期从theta复制而来。笔记中解释了为何需要目标网络:如果使用同一个网络计算目标和预测,目标会随着参数更新而漂移,导致训练不稳定。通过固定目标网络一段时间,可以缓解这一问题。此外,笔记还提到了梯度下降的具体计算,即损失对theta的梯度,并强调了在计算目标时需停止梯度传播。

均方贝尔曼误差(MSBE):MSBE是DQN中常用的损失函数,定义为目标Q值与当前Q值之差的平方的期望。其表达式为L(θ) = E[(r + γ max_a' Q(s',a';θ^-) - Q(s,a;θ))^2]。最小化MSBE等价于使Q函数满足贝尔曼最优方程。在实际实现中,期望通过从经验回放缓冲区中采样的小批量数据来近似。梯度下降时,仅对当前Q网络的参数θ求导,目标网络参数θ^-视为常数,即停止梯度传播。这种半梯度方法虽然理论上不保证收敛,但在实践中表现良好。

折扣因子(γ):折扣因子γ∈[0,1]用于平衡即时奖励和未来奖励的重要性。γ接近0时,智能体更关注即时奖励;γ接近1时,智能体更重视长期回报。在DQN中,γ的选择影响算法的收敛性和最终策略,通常需要根据具体任务调整。

总结与进一步学习

这篇一页纸的笔记以紧凑的方式呈现了DQN的三大支柱:概念上从表格到函数的跃迁,代码上的经验回放与目标网络,数学上的贝尔曼方程与MSBE损失。对于初学者而言,这种将理论、实现与公式结合的笔记有助于快速建立整体认知。作者在Reddit帖子中表示,笔记保持了简短、连贯的风格,并附带了代码片段和必要的数学解释。如果你希望深入理解DQN,建议在阅读笔记后,动手实现一个简单的版本,例如在CartPole环境中训练,以直观感受算法的运行过程。

#DQN#强化学习#深度Q网络#Q Learning#贝尔曼方程#经验回放#目标网络
分享:

相关推荐