“Deep Q Network”的版本间的差异
| 第495行: | 第495行: | ||
| − | == | + | ==参考文献与延伸阅读== |
<references /> | <references /> | ||
2025年5月18日 (日) 16:27的版本
深度Q网络(Deep Q-Network, DQN)是一种基于深度学习的强化学习算法,它通过深度神经网络来近似最优动作价值函数(Q函数),能够直接从高维感知输入(如游戏画面像素)中学习最优决策策略。该算法的核心创新在于结合了经验回放机制和目标网络技术,有效解决了传统Q学习在非线性函数逼近中的稳定性问题,首次在Atari游戏上实现了从原始像素输入到控制指令的端到端学习,达到了人类水平的游戏表现。
背景
强化学习的基本概念与挑战
基本概念
强化学习(Reinforcement Learning, RL)是一种机器学习方法,强调智能体(agent)通过与环境的交互,在试错过程中学习策略,以最大化累积奖励。其核心在于解决“探索-利用”之间的权衡:既要尝试新的动作以发现潜在的高奖励策略(探索),又要利用已知的最优策略以获得即时收益(利用) 。
面临的挑战
尽管强化学习在游戏AI、机器人控制、推荐系统等领域取得了显著成果,但在实际应用中仍面临诸多挑战:
(1)样本效率低:强化学习通常需要大量的交互数据才能学习有效策略,这在数据获取成本高或交互受限的场景中尤为困难。
(2)泛化能力弱:在特定环境中训练出的策略,往往难以适应稍有变化的新环境,缺乏迁移学习能力。
(3)奖励设计困难:设计合适的奖励函数至关重要,不当的奖励设计可能导致智能体学习到与预期不符的行为。
(4)训练稳定性与收敛性问题:特别是在基于深度神经网络的模型中,训练过程可能不稳定,容易发生发散。策略或环境的微小变化可能导致性能的极大波动,使得难以获得一致的结果。在连续或高维动作空间的情况下,这种不稳定性更加明显,学习过程变得更复杂且难以预测。
Q-Learning 简介
Q-Learning 是强化学习中一种经典且广泛应用的无模型(model-free)算法,属于基于值(value-based)的方法。其核心目标是通过学习一个动作价值函数(Q函数),指导智能体在不同状态下选择最优动作,以最大化长期累积奖励。
举例老鼠在迷宫中寻找奶酪来理解Q-Learning :
(1)环境设定
- 智能体(Agent):一只老鼠,起始位置固定。
- 目标(Goal):在迷宫的右下角有一块奶酪,老鼠的任务是找到并吃到奶酪。
- 障碍(Obstacle):迷宫中某些位置有毒药,老鼠需要避免这些位置。
- 动作(Actions):老鼠可以选择向上、下、左、右移动。
- 奖励(Rewards):
- 吃到奶酪:+10
- 误入毒药:-10
- 其他移动:0
(2)Q-Learning 学习过程
老鼠通过不断尝试不同的路径,学习如何从起点移动到奶酪所在的位置,同时避免毒药。每次移动后,老鼠根据获得的奖励更新其对当前状态下各个动作的价值估计(即 Q 值)。随着学习的进行,老鼠逐渐形成一套策略,使其能够更快、更安全地找到奶酪。
(3)Q 值更新公式
Q-Learning 的核心在于通过以下公式更新 Q 值: [math]\displaystyle{ Q_{t+1}(s_t, a_t) = Q_t(s_t, a_t) + \alpha_t \left[ r_t + \gamma \max_{a} Q_t(s_{t+1}, a) - Q_t(s_t, a_t) \right] }[/math]
其中:
- [math]\displaystyle{ s_t }[/math]:当前状态
- [math]\displaystyle{ a_t }[/math]:当前动作
- [math]\displaystyle{ r_t }[/math]:即时奖励
- [math]\displaystyle{ s_{t+1} }[/math]:执行动作后的新状态
- [math]\displaystyle{ \alpha \in (0,1] }[/math]:学习率
- [math]\displaystyle{ \gamma \in [0,1) }[/math]:折扣因子
(4)策略选择:ε-贪婪策略
为了在探索新路径和利用已知最佳路径之间取得平衡,采用 ε-贪婪策略:
- 以概率 ε 随机选择一个动作(探索)
- 以概率 1 - ε 选择当前 Q 值最大的动作(利用)
随着训练的进行,逐渐减小 ε 的值,以减少探索,增加利用。
(5)学习过程
以下是老鼠在迷宫中学习的简要过程:
a.初始化:将所有状态-动作对的 Q 值初始化为 0。
b.选择动作:根据 ε-贪婪策略选择一个动作。
c.执行动作:老鼠移动到新的位置,获得相应的奖励。
d.更新 Q 值:根据 Q 值更新公式,更新当前状态下该动作的 Q 值。
e.重复:将新位置作为当前状态,重复步骤 2 至 4,直到达到终止条件(如找到奶酪或达到最大步数)。
通过多次迭代,老鼠能够学习到从起点到奶酪的最优路径,同时避免毒药。
该示例展示了 Q-Learning 如何通过与环境的交互,学习最优策略以最大化累积奖励。通过不断更新 Q 值,智能体能够在复杂的环境中找到最优路径。
深度学习与强化学习的融合背景
深度学习与强化学习的融合起源于两者互补的优势:强化学习擅长决策与策略优化,而深度学习擅长处理高维感知数据(如图像、语音、文本等)。传统强化学习方法在面对大规模状态空间(例如图像输入)时,因无法使用查表的方式存储 Q 值而表现不佳。为了解决这一瓶颈,研究者引入深度神经网络作为函数逼近器,用以估计状态-动作值函数(Q 值)或策略函数,从而大幅提升了强化学习在复杂环境中的泛化能力和实用性。
这一融合的代表性成果是 2015 年 DeepMind 提出的深度 Q 网络(DQN),首次在无需人工特征设计的情况下,仅凭像素输入便在多款 Atari 游戏中实现了超越人类水平的表现。
DQN 的提出及其在 Atari 游戏中的突破性成果
Deep Q-Network(DQN)是由DeepMind团队在2015年发表的论文[1]中提出的深度强化学习算法。该研究首次将深度神经网络与Q-learning结合,直接从高维感官输入(如Atari游戏的像素)学习控制策略,而无需手工设计特征。DQN在Atari 2600游戏上的表现达到或超越人类水平,标志着深度强化学习在复杂任务中的重大突破。
DQN的核心创新包括使用深度卷积神经网络(CNN)处理原始像素输入,模仿生物视觉系统的层次化特征提取能力。此外,为了解决传统强化学习在非线性函数逼近下的不稳定性,DQN引入了经验回放(Experience Replay)机制,通过存储并随机采样历史经验来打破数据相关性,提高训练稳定性。同时,采用目标网络分离技术,定期冻结目标Q网络的参数,减少训练过程中的波动。
在实验中,DQN在49款Atari 2600游戏上进行测试,仅以游戏屏幕像素和分数作为输入,使用相同的网络架构和超参数。结果显示,DQN在43款游戏中超越了此前所有强化学习方法,并在29款游戏中达到人类专业测试员水平的75%以上。例如,在“Breakout”中,DQN自主发现“侧边挖隧道”的高分策略,最终得分远超人类玩家;在“Space Invaders”中,DQN学会忽略无关视觉特征,专注于关键状态价值预测。
DQN的成功不仅验证了端到端强化学习的可行性,还揭示了深度神经网络与生物学习机制的相似性,如经验回放与海马体记忆重放的类比。然而,DQN仍存在训练数据需求大、对超长程规划任务(如“Montezuma’s Revenge”表现有限等挑战。尽管如此,DQN为后续深度强化学习研究奠定了基础,推动了从游戏AI到机器人控制等领域的广泛应用。
提出的模型
该示意图展示了深度Q网络(DQN)的典型架构设计,直观呈现了从原始游戏画面到控制指令的端到端处理流程。系统采用多级特征提取架构,左侧输入层接收预处理后的游戏画面(84×84像素,4帧堆叠),通过两个卷积层(Convolution)进行空间特征提取,其中网格状结构表示卷积核在空间维度上的特征映射过程。随后经由两个全连接层(Fully connected)实现高级特征的抽象与组合,最终输出层与游戏手柄控制指令直接关联,作为根据学到的动作价值Q来选择动作。该架构设计充分体现了DQN直接从原始像素学习控制策略的核心思想,通过卷积神经网络的特征提取能力与强化学习的决策机制相结合,实现了从感知到行动的完整映射。
模型的细节
该研究在模型设计上体现了显著的普适性特征,采用单一网络架构处理所有Atari游戏任务,仅需输入原始像素、动作空间和生命值等基本先验知识。在算法实现方面,创新性地引入了经验回放机制(experience replay),通过循环缓冲区存储历史转移样本(s_t, a_t, r_t, s_{t+1}),并采用均匀随机采样方式抽取小批量(minibatch size=32)进行训练。这种设计有效打破了数据间的时间相关性,显著提高了样本利用率和训练稳定性。
在奖励函数设计方面,研究者采用了归一化处理策略,将正向奖励设为+1,负向奖励设为-1,其余情况为0,这种标准化方法有效控制了误差范围并实现了跨游戏的统一训练速度。经验回放机制与奖励归一化的协同作用,使得算法能够在不同游戏间保持一致的性能表现。
针对大规模训练数据的高冗余特性,研究采用了RMSProp优化算法,其核心机制是通过将梯度除以其近期幅度的滑动平均值来调整学习率。训练过程中引入衰减系数ϵ,采用ϵ-greedy策略进行探索-利用权衡:在前1百万训练步中,ϵ值从1线性衰减至0.1,之后保持恒定。这种动态调整策略与经验回放机制相结合,有效避免了过早收敛问题,特别适合处理非平稳目标函数。值得注意的是,经验回放缓冲区的容量设置为1,000,000个样本,并在训练前预填充50,000帧数据以确保初始采样质量。
为提高计算效率,研究者对所有游戏采用了跳帧技术(每4帧处理1帧),在保证性能无明显下降的前提下显著提升了训练速度。这种时间抽象方法与经验回放机制协同工作,使得样本复杂度相比在线策略降低了约10倍。实验结果表明,移除经验回放会导致性能下降58.7%,充分验证了该机制的必要性。这些创新设计共同构成了DQN算法的核心框架,为后续深度强化学习研究奠定了重要基础。
具体算法及其训练流程
1. 初始化阶段 回放记忆库(Replay Memory):创建容量为N的经验存储库D,用于缓存历史转移数据。 动作-价值函数网络: 主网络Q:随机初始化网络参数θ,负责实时动作选择和价值估计。 目标网络Q−:初始参数θ−=θ,用于稳定化计算目标Q值。 超参数设定:设置训练总回合数M、单回合最大步数T、目标网络同步频率C、折扣因子γ、探索率ϵ等。
2. 回合(Episode)循环 对每个回合episode=1,2,...,M执行: 状态预处理:初始化环境观测x1,通过预处理函数ϕ生成初始状态表征ϕ1=ϕ(s1)。
3. 时间步(Timestep)循环 对每个时间步t=1,2,...,T执行: (1)动作选择: 探索策略:以概率ϵ随机选择动作at,促进环境探索。 利用策略:否则,根据主网络选择最优动作:at=arg maxa Q(ϕ(st),a;θ) (2)执行与环境交互: 执行动作at,获取奖励rt和下一帧图像x t+1。 预处理下一状态ϕt+1=ϕ(st+1)。 (3)存储转移数据: 将转移元组(ϕt,at,rt,ϕt+1)存入回放记忆库D。 (4)经验回放与网络更新: 随机采样:从D中均匀抽取小批量转移(ϕj,aj,rj,ϕj+1)。 目标Q值计算: [math]\displaystyle{ y_{j} = r_{j} + /gamma /max_{a} Q^{-}(ϕ_{j+1}, a) }[/math] 梯度下降: [math]\displaystyle{ ∇_{θ} 1/ {|B|} {/sum} (y_j-Q(ϕ_j,a_j;θ)^2 }[/math] (5)目标网络同步: 每隔C步将主网络参数θ复制至目标网络Q-,即θ-←θ。
Q-Learning 基础
马尔可夫决策过程(MDP)简介
马尔可夫决策过程(Markov Decision Process,简称 MDP)是强化学习的核心数学框架,用于建模智能体在不确定环境中通过试错学习最优策略的过程。它在马尔可夫过程的基础上引入了“动作”和“奖励”机制,广泛应用于人工智能、控制系统、经济学等领域。
MDP 的核心思想
在 MDP 中,智能体与环境的交互过程如下:
(1)智能体观察当前状态 st。
(2)根据策略 π,选择一个动作 at。
(3)环境根据状态转移概率 P,转移到下一个状态 st+1,并给予智能体奖励 rt。
(4)智能体根据获得的奖励和新的状态,更新策略 π,以期获得更高的累计奖励。
这一过程持续进行,智能体通过不断与环境交互,学习最优策略。
策略与价值函数
- 策略 π(a∣s):在状态 s 下选择动作 a 的概率分布。
- 状态值函数 Vπ(s):在策略 π 下,从状态 s 开始,期望获得的累计奖励。
- 动作值函数 Qπ(s,a):在策略 π 下,从状态 s 开始,采取动作 a 后,期望获得的累计奖励。
这些函数用于评估策略的优劣,指导策略的改进。
Q 值函数的定义与更新公式
定义
Q 值函数 Q(s, a) 表示智能体在状态 s 下采取动作 a 后,遵循某一策略所能获得的期望累积奖励。
更新公式
Q-Learning 算法使用以下更新公式来迭代 Q 值:
[math]\displaystyle{ Q_{t+1}(s_t, a_t) = Q_t(s_t, a_t) + \alpha_t \left[ r_t + \gamma \max_{a} Q_t(s_{t+1}, a) - Q_t(s_t, a_t) \right] }[/math]
其中,符号含义如下:
- [math]\displaystyle{ s_t }[/math]:当前状态
- [math]\displaystyle{ a_t }[/math]:当前动作
- [math]\displaystyle{ r_t }[/math]:即时奖励
- [math]\displaystyle{ s_{t+1} }[/math]:执行动作后的新状态
- [math]\displaystyle{ \alpha \in (0,1] }[/math]:学习率
- [math]\displaystyle{ \gamma \in [0,1) }[/math]:折扣因子
此公式基于贝尔曼方程的时序差分(TD)更新思想,逐步调整 [math]\displaystyle{ Q }[/math] 值函数以逼近最优策略。
ε-greedy 策略与探索-利用权衡
Q-learning 通常面临“探索(exploration)”与“利用(exploitation)”之间的权衡问题。为了解决这一问题,通常采用 ε-greedy 策略。ε-greedy 策略是一种简单而有效的动作选择策略,旨在平衡探索与利用。
- 利用(Exploitation):以 1−ϵ 的概率选择当前状态下 Q 值最大的动作,即选择已知的最佳动作。
- 探索(Exploration):以 ϵ 的概率随机选择一个动作,从而探索新的可能性。
其中,ϵ 是一个介于 0 和 1 之间的参数,控制探索的频率。较大的 ϵ 值鼓励更多的探索,而较小的 ϵ 值则倾向于更多的利用。
在实际应用中,通常会随着训练的进行逐步减小 ϵ 值,从而实现以下目标:
- 初期阶段:设置较大的 ϵ 值,鼓励智能体进行充分的探索。
- 后期阶段:逐步减小 ϵ 值,增加利用已知最佳策略的频率。
这种策略有助于智能体在学习初期获取足够的经验,在后期则能够稳定地执行最优策略。
Q-Learning 的收敛性
Q-Learning 收敛性的证明主要基于以下几点:
(1)Bellman 最优算子是压缩映射[2]
Bellman 最优算子 B 定义为: [math]\displaystyle{ (BQ)(s,a) = \mathbb{E} \left[ r(s,a) + \gamma \max_{a'} Q(s', a') \right] }[/math] 它满足: [math]\displaystyle{ \| BQ_1 - BQ_2 \|_\infty \leq \gamma \| Q_1 - Q_2 \|_\infty }[/math] 即B是以折扣因子γ为压缩率的压缩映射。
(2)Banach 不动点定理保证唯一固定点
因为B是压缩映射,存在唯一的固定点Q∗满足: [math]\displaystyle{ Q^* = B Q^* }[/math] 这就是最优状态-动作值函数。
(3)随机逼近框架中的收敛条件[3]
Q-Learning 通过随机采样和迭代逼近Q∗,在学习率满足以下条件时收敛: [math]\displaystyle{ \sum_{t=0}^\infty \alpha_t(s,a) = \infty, \quad \sum_{t=0}^\infty \alpha_t(s,a)^2 \lt \infty }[/math] 同时,算法需保证每个状态-动作对 (s,a) 被无限次访问。
收敛的关键条件:
充分探索:智能体必须保证所有对无限次访问,通常通过 ε-greedy 等策略实现。学习率衰减:学习率αt随时间衰减,但不宜过快。折扣因子限制:γ∈[0,1),保证未来奖励的影响递减。
在满足适当的学习率调节、充分探索、以及折扣因子约束的情况下,Q-Learning 算法能够以概率 1 收敛到最优值函数Q∗,其数学表达为: [math]\displaystyle{ \lim_{t \to \infty} Q_t(s,a) = Q^*(s,a) }[/math] 这为强化学习算法的理论可靠性提供了坚实基础。
Q-Learning 的局限性
Q-Learning 广泛应用于多种决策任务。在实际应用中,它的局限性主要体现在以下几个方面:(1)状态-动作空间维度灾难(Curse of Dimensionality):Q-Learning 使用 Q 表来存储每个状态-动作对的价值。当状态或动作空间非常大时,Q 表的尺寸会急剧膨胀,导致存储和更新变得不切实际。
例如,在具有数百万状态和动作的环境中,传统的 Q 表方法可能无法有效处理。为了解决这个问题,通常采用函数逼近方法,如线性函数逼近或深度神经网络,以估计 Q 值,从而避免直接使用庞大的 Q 表。
(2)在状态和动作空间较大的环境中,Q-Learning 的学习过程可能非常缓慢,通常需要大量的训练回合才能收敛到最优策略。这种慢收敛性使得 Q-Learning 在需要快速学习的应用场景中可能不太适用。[1]
(3)探索与利用的平衡问题:Q-Learning 依赖于探索(exploration)和利用(exploitation)之间的平衡。过度探索可能导致学习效率低下,而过度利用可能导致陷入局部最优解。例如,ε-greedy 策略通过引入随机性来平衡探索与利用,但选择合适的 ε 值仍然是一个挑战。
(4)对超参数敏感:Q-Learning 的性能对学习率(α)、折扣因子(γ)和探索率(ε)等超参数非常敏感。选择不当的超参数可能导致学习过程不稳定或收敛到次优解。例如,过高的学习率可能导致 Q 值更新过快,导致震荡;而过低的学习率可能导致学习过程过慢。
(5)对函数逼近的稳定性问题:当使用函数逼近(如神经网络)来估计 Q 值时,Q-Learning 可能出现不稳定或发散的情况,尤其是在非线性函数逼近器的情况下。
这种不稳定性主要源于估计目标值与当前 Q 值之间的相互依赖关系。为了解决这个问题,提出了 Double Q-Learning 等方法,通过使用两个独立的 Q 值估计器来减少过估计偏差,从而提高稳定性。[2]
DQN 的核心思想与结构
使用神经网络逼近 Q 值函数
DQN的⾏为值函数[math]\displaystyle{ Q(s,a;θ) }[/math] 利⽤神经⽹络逼近,属于⾮线性逼近。此处的值函数对应着⼀组参数,在神经⽹络⾥参数是每层⽹络的权重,用θ表示。 用公式表示的话,如下: [math]\displaystyle{ Q^{*}(s,a)≈Q(s,a;θ) }[/math]
其中:
- 输入:原始状态 s(如游戏画面像素矩阵)
- 输出:每个动作 a 对应的Q值(离散动作空间)
- 参数:θ 为神经网络的权重,通过梯度下降优化
在论文中DQN所用的网络结构是三个卷积层加两个全连接层,网络的输入是经过预处理后的数据,预处理指的是将210*160的游戏图像转化为84*84的图像等操作,得到算法结构中的具体代码实现和网络结构见图和以下代码:
核心意义:
- 端到端学习:直接从原始状态(如像素)映射到动作价值,无需手工设计特征。
*泛化能力:相似状态共享神经网络的特征表示,提升样本利用率。 *高维处理:卷积神经网络(CNN)可高效提取图像中的空间特征。
经验回放(Experience Replay)机制
通过经验回放可以令神经网络的训练收敛且稳定。这是因为训练神经⽹络时,存在的假设是训练数据是独⽴同分布的,但是通过强化学习采集的数据之间存在着关联性,利⽤这些数据进⾏顺序训练,神经⽹络当然不稳定。经验回放可以打破数据间的关联。在强化学习过程中,智能体将数据存储到⼀个数据库中,再利⽤均匀随机采样的⽅法从数据库中抽取数据,然后利⽤抽取的数据训练神经⽹络。 这种经验回放的技巧可以打破数据之间的关联性。
目标网络(Target Network)的引入与参数更新策略
为了更长远的提高稳定性,使用一个独立的神经Q网络去得到target y,即建立另一个独立的神经网络target network。每经过c次更新后,复制 network Q得到target network Q’,然后使用Q’去生成target y应用与接下来的c次更新。好处就是比起online Q-learning算法更稳定。因为online Q-learning每次更新在增加Q(st,at)的同时也增加了针对每个a的Q(st+1,a),从而增加了 target y,这又可能会引起策略的震荡甚至发散。所以目标网络(Target Network)的引入可以解决这一问题。
于是损失函数表示为(忽略无关的方差项) [math]\displaystyle{ L_{i}(θ_{i})=E_{s,a,r,s'}[(r+γ /max_{a'}Q(s',a',θ_{i}^{−})−Q(s,a,θ_{i}))^2] }[/math] 梯度为 [math]\displaystyle{ ▽_{θ_i} L_i ( θ_i ) = E_{s , a , r , s ′ }[ ( r + γ max _{a ′ }Q ( s ′ , a ′ , θ_{i}^{−} ) − Q ( s , a , θ_{i }) ) ▽ θ_i Q ( s , a , θ_i ) ] }[/math]
工程中,使用随机梯度下降 SGD 来完成优化,另外当令 [math]\displaystyle{ θ_{i}^{−} = θ_{i−1} }[/math]时,退化为原始的 Q-Learning 更新形式
DQN在pytorch中的简单完整实现
import torch
import torch.nn as nn
import torch.optim as optim
import random
from collections import deque
import gym
# 定义Q网络
class QNetwork(nn.Module):
def __init__(self, input_dim, output_dim):
super(QNetwork, self).__init__()
self.fc = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Linear(128, 128),
nn.ReLU(),
nn.Linear(128, output_dim)
)
def forward(self, x):
return self.fc(x)
# 定义DQN代理
class DQNAgent:
def __init__(self, state_dim, action_dim, lr=0.001, gamma=0.99, epsilon=1.0, epsilon_decay=0.995, min_epsilon=0.01, buffer_size=10000, batch_size=64):
self.state_dim = state_dim
self.action_dim = action_dim
self.gamma = gamma
self.epsilon = epsilon
self.epsilon_decay = epsilon_decay
self.min_epsilon = min_epsilon
self.batch_size = batch_size
self.q_network = QNetwork(state_dim, action_dim)
self.target_network = QNetwork(state_dim, action_dim)
self.target_network.load_state_dict(self.q_network.state_dict())
self.optimizer = optim.Adam(self.q_network.parameters(), lr=lr)
self.replay_buffer = deque(maxlen=buffer_size)
self.criterion = nn.MSELoss()
def choose_action(self, state):
if random.random() < self.epsilon:
return random.randint(0, self.action_dim - 1)
else:
state = torch.tensor([state], dtype=torch.float32)
q_values = self.q_network(state)
return torch.argmax(q_values).item()
def store_experience(self, state, action, reward, next_state, done):
self.replay_buffer.append((state, action, reward, next_state, done))
def update_network(self):
if len(self.replay_buffer) < self.batch_size:
return
batch = random.sample(self.replay_buffer, self.batch_size)
states, actions, rewards, next_states, dones = zip(*batch)
states = torch.tensor(states, dtype=torch.float32)
actions = torch.tensor(actions, dtype=torch.int64)
rewards = torch.tensor(rewards, dtype=torch.float32)
next_states = torch.tensor(next_states, dtype=torch.float32)
dones = torch.tensor(dones, dtype=torch.float32)
q_values = self.q_network(states).gather(1, actions.unsqueeze(1)).squeeze()
next_q_values = self.target_network(next_states).max(1)[0]
target_q_values = rewards + self.gamma * next_q_values * (1 - dones)
loss = self.criterion(q_values, target_q_values)
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
def update_target_network(self):
self.target_network.load_state_dict(self.q_network.state_dict())
def decay_epsilon(self):
self.epsilon = max(self.min_epsilon, self.epsilon * self.epsilon_decay)
# 环境
env = gym.make('CartPole-v1')
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.n
# 初始化代理
agent = DQNAgent(state_dim, action_dim)
# 训练循环
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.store_experience(state, action, reward, next_state, done)
agent.update_network()
state = next_state
total_reward += reward
agent.update_target_network()
agent.decay_epsilon()
print(f'Episode {episode + 1}/{episodes}, Total Reward: {total_reward}, Epsilon: {agent.epsilon:.3f}')
# 评估
state = env.reset()
done = False
while not done:
action = agent.choose_action(state)
state, _, done, _ = env.step(action)
env.render()
env.close()
该代码基于深度Q网络(DQN)算法,解决OpenAI Gym中的经典控制任务CartPole-v1。任务目标是控制小车左右移动,使竖直杆子尽可能长时间保持直立。智能体通过4维状态(小车位置、速度、杆子角度及角速度)感知环境,输出离散动作(左移/右移),最终实现稳定平衡超过500步的满分表现。 算法实现 Q值网络: 使用三层全连接神经网络(输入4维→128→128→输出2维)近似Q值函数,输出左右移动的动作价值。 目标网络与主网络分离,定期同步参数以稳定训练。 经验回放: 存储10,000条历史转移样本(状态、动作、奖励、下一状态、终止标志),训练时随机采样64条数据打破时序相关性。 训练机制: ε-贪婪策略动态衰减(初始ε=1.0,衰减率0.995,最低ε=0.01),平衡探索与利用。 基于贝尔曼方程计算目标Q值,通过均方误差损失更新网络,折扣因子γ=0.99。
DQN 的主要改进算法=
Double DQN:解决 Q 值过高估计问题
Double DQN的思想
在经典的 Q-Learning 及其深度版本 DQN(Deep Q-Network)中,动作值函数的估计存在系统性偏差,即过高估计(overestimation bias)。这种偏差源自于最大化操作:
<math> \max_{a} Q(s', a; \theta) </math>。当估计的 Q 值存在噪声时,直接选取最大 Q 值动作容易导致期望的过高估计,从而影响策略的稳定性和最终性能。为了减少 DQN 中的 Q 值过高估计,Double DQN 引入了两个 Q 网络:当前 Q 网络和目标 Q 网络[4]。
经典 DQN 的目标 Q 值计算公式为: [math]\displaystyle{ y_t^{\mathrm{DQN}} = r_t + \gamma \max_{a} Q(s_{t+1}, a; \theta^-) }[/math] 其中: [math]\displaystyle{ r_t }[/math] 是在时间步 [math]\displaystyle{ t }[/math] 获取的奖励, [math]\displaystyle{ \gamma }[/math] 是折扣因子, [math]\displaystyle{ \max_{a} Q(s_{t+1}, a; \theta^-) }[/math] 是在时间步 [math]\displaystyle{ t+1 }[/math] 下,通过目标网络 [math]\displaystyle{ \theta^- }[/math] 计算的最大 Q 值,选择下一个状态 [math]\displaystyle{ s_{t+1} }[/math] 中的最佳动作。
Double DQN目标 Q 值计算公式改为: [math]\displaystyle{ y_t^{\mathrm{DoubleDQN}} = r_t + \gamma Q\bigl(s_{t+1}, \arg\max_a Q(s_{t+1}, a; \theta); \theta^- \bigr) }[/math]
动作选择:依然通过当前 Q 网络 [math]\displaystyle{ Q(s_{t+1}, a; \theta) }[/math] 来选择下一个状态 [math]\displaystyle{ s_{t+1} }[/math] 中的最优动作,[math]\displaystyle{ a^* = \arg\max_a Q(s_{t+1}, a; \theta) }[/math],这个步骤使用的是当前网络 [math]\displaystyle{ \theta }[/math] 来选择动作。
动作评估:评估这个动作的 Q 值时,使用的是目标网络 [math]\displaystyle{ \theta^- }[/math],即评估选中的动作 [math]\displaystyle{ a^* }[/math] 对应的 Q 值:[math]\displaystyle{ Q(s_{t+1}, a^*; \theta^-) }[/math],通过这种方式,Double DQN 通过分开动作选择和动作评估,避免了经典 DQN 中同一网络同时执行选择和评估的操作,从而减少了因选择最大 Q 值而导致的过高估计偏差。
Double DQN的优势
传统 DQN 在更新时,直接用目标网络估计的最大 Q 值作为目标,这种“最大化”操作容易从噪声中挑选出偏大值,导致整体偏高。Double DQN 则先用当前网络挑选动作,再用目标网络计算价值,避免了单一网络同时负责选动作和评估动作价值所带来的偏差。Double DQN 是一种简单有效的改进策略,通过“动作选择”和“动作评估”分开估计,显著缓解了 Q 值过高估计问题,提高了深度强化学习算法的稳定性和性能,已成为深度强化学习领域的重要方法之一。
Dueling DQN:分离状态价值与优势函数
Dueling DQN的思想
Dueling DQN(Dueling Deep Q-Network)是对经典 DQN 的一种结构性改进,旨在提升智能体在复杂环境中的学习效率和稳定性[5]。
在传统的 DQN 中,Q 值函数 Q(s,a) 直接输出每个动作的价值。然而,在许多情况下,某些状态下的所有动作的价值差异较小,导致学习过程中的梯度更新效率低下。Dueling DQN 通过将 Q 值函数分解为状态价值函数 V(s) 和优势函数 A(s,a),使得网络能够分别评估状态的总体价值和各个动作的相对优势,从而提高学习效率。具体地,Dueling DQN 的 Q 值计算公式为: [math]\displaystyle{ Q(s, a) = V(s) + A(s, a) }[/math] 其中,V(s) 是状态s的价值,表示在该状态下智能体的期望回报;A(s,a) 是动作a相对于当前状态的优势,表示在该状态下采取动作a相对于其他动作的优势程度。
Dueling DQN 的网络结构在传统 DQN 的基础上进行了修改。
具体而言,网络的前几层共享,用于提取输入状态的特征;然后,网络分为两个分支:一个用于计算状态价值函数V(s),另一个用于计算优势函数 A(s,a)。最后,两个分支的输出被合并,得到每个动作的 Q 值估计。这种结构使得网络能够更有效地学习到状态的价值和动作的优势,从而提高学习性能。
Dueling DQN的优势
(1)提高学习效率:通过分离状态价值和动作优势,Dueling DQN 能够更好地聚焦于重要信息,减少无关因素干扰,提高学习效率。 (2)增强鲁棒性:对状态价值和优势的独立建模有助于缓解环境噪声和稀疏奖励带来的影响,提高算法的鲁棒性。 (3)提升泛化能力:Dueling 架构允许网络在未见过的环境中更快地推断出合理的 Q 值,增强了算法的泛化能力。
DRQN
DRQN的思想
Deep Recurrent Q-Network(DRQN)是对经典 DQN 的一种扩展,旨在解决部分可观察马尔可夫决策过程(POMDP)中的挑战[6]。在 POMDP 中,智能体无法获得完整的环境状态信息,传统的 DQN 依赖于完整的观察序列进行决策,可能导致性能下降。DRQN 通过引入递归神经网络(RNN),特别是长短期记忆(LSTM)网络,使智能体能够处理部分观察信息,保留历史信息,从而在部分可观察的环境中表现出更好的性能。DRQN 的核心思想是将传统 DQN 的全连接层替换为 LSTM 层,以便在每个时间步都能保留历史信息。具体而言,DRQN 的 Q 值计算公式为:[math]\displaystyle{ Q(s_t, a_t) = \text{LSTM}(h_{t-1}, [\phi(s_t), a_t]) }[/math] 其中,[math]\displaystyle{ h_{t-1} }[/math] 是上一时间步的隐藏状态,[math]\displaystyle{ \phi(s_t) }[/math] 是当前状态的特征表示,[math]\displaystyle{ a_t }[/math] 是当前动作。通过这种方式,DRQN 能够在每个时间步都考虑到历史信息,从而更好地应对部分可观察的环境。
DRQN 的网络结构通常包括以下几个部分: (1)卷积层(Convolutional Layers):用于从输入图像中提取特征。 (2)LSTM 层:用于处理时间序列数据,保留历史信息。 (3)全连接层(Fully Connected Layer):用于输出每个动作的 Q 值。 这种结构使得 DRQN 能够在每个时间步都考虑到历史信息,从而更好地应对部分可观察的环境。
DRQN的优势与局限
1.优势
(1)处理部分可观察环境:DRQN 能够在每个时间步都保留历史信息,从而在部分可观察的环境中表现出更好的性能。 (2)提高决策质量:通过引入 LSTM 层,DRQN 能够更好地捕捉时间序列中的长期依赖关系,从而提高决策质量。 (3)适应性强:DRQN 可以适应不同的环境和任务,具有较强的泛化能力。
2.局限
(1)训练难度:由于引入了 LSTM 层,DRQN 的训练过程可能比传统 DQN 更加复杂和困难。 (2)计算资源需求高:LSTM 层的引入增加了计算量,对硬件资源的要求更高。 (3)超参数调优复杂:LSTM 层引入了更多的超参数,需要进行精细的调优。
DQN 的应用领域
Atari 游戏中的应用与表现
机器人控制与路径规划
推荐系统中的策略优化
DQN 的局限性与挑战
对连续动作空间的处理困难
训练过程中的样本效率问题
策略收敛速度慢与稳定性问题
泛化能力与过拟合风险
参考文献与延伸阅读
- ↑ Mnih, V.; Kavukcuoglu, K. (2015). "Human-level control through deep reinforcement learning". Nature. 518 (7540): 529–533. doi:10.1038/nature14236. PMID 25719670.
- ↑ Overmars M G. Analyzing the convergence of Q-learning through Markov decision theory[D]. University of Twente, 2021.
- ↑ Even-Dar E, Mansour Y. Convergence of optimistic and incremental Q-learning[J]. Advances in neural information processing systems, 2001, 14.
- ↑ Van Hasselt H, Guez A, Silver D. Deep reinforcement learning with double q-learning[C]//Proceedings of the AAAI conference on artificial intelligence. 2016, 30(1).
- ↑ Wang Z, Schaul T, Hessel M, et al. Dueling network architectures for deep reinforcement learning[C]//International conference on machine learning. PMLR, 2016: 1995-2003.
- ↑ Hausknecht M J, Stone P. Deep Recurrent Q-Learning for Partially Observable MDPs[C]//AAAI fall symposia. 2015, 45: 141.
