[目录]
0.行文概述
1.Q-learning
1.1 基本概念回顾
1.2 算法原理
1.3 算法示例
2.Deep Q-Network
2.1 基本原理
2.2 目标网络
2.3 经验回放
3.总结
0. 行文概述
深度Q网络(Deep Q-Network, DQN)作为深度强化学习的里程碑式算法,通过将Q-learning与深度神经网络结合,解决了传统强化学习在高维状态空间中的维度灾难问题。本文以 “从Q-learning到DQN的核心演进” 为脉络展开:首先剖析Q-learning基于动态规划的贝尔曼方程更新机制及其局限性;继而深入探讨DQN如何通过神经网络函数逼近重构Q值估计,并针对训练稳定性问题提出目标网络与经验回放两大核心技术;最终揭示DQN在实现端到端决策智能中的理论意义与实践价值。全文通过算法原理推演、数学形式化表达与具体问题分析,系统构建从传统强化学习到深度强化学习的认知桥梁。
阅读本文需要默认读者了解神经网络的和强化学习基本原理与概念。如果读者对后者不够了解,建议先阅读本人该系列的第一篇文章【强化学习入门】I:基本原理与概念。
【强化学习入门】系列主要是喜提双项目的某大二本科生在学习强化学习时的笔记、思路和心得。
1. Q-learning
1.1 基本概念回顾
事实上,Q-Learning的概念在我的文章【强化学习入门】I:基本原理与概念的3.1节“Policy”的表示方法中已经提到过了。我们不妨回顾一下:
我们知道,Policy是一个将状态State映射为动作Action的函数,最简单的方式就是构建一张表格,分别列出各个状态下做出各个动作所估计的价值Value,选择最大Value的动作作为我们采取的动作。这张表格也就被称为:Q-table
那么现在,我们问题的核心就在于:如何构建这张Q-table?
1.2 算法原理
Q-learning 的核心是通过更新公式来逐步优化 Q 值表。以下是其工作原理的详细说明:
-
Q值表(Q-table)
Q-learning 使用一个二维表(Q-table)来存储每个状态-动作对的预期回报(Q值)。Q值表示在状态 s s s 下采取动作 a a a 的未来奖励期望。 Q ( s , a ) Q(s, a) Q(s,a) 定义为动作价值函数。即在 state s s s 下,做出 Action a a a,期望的回报 -
更新公式
Q值通过以下公式(贝尔曼公式)更新:
Q ( s , a ) ← Q ( s , a ) + α [ R ( s , a ) + γ max a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s, a) \leftarrow Q(s, a) + \alpha \left[ R(s,a) + \gamma \max_{a'} Q(s', a') - Q(s, a) \right] Q(s,a)←Q(s,a)+α[R(s,a)+γa′maxQ(s′,a′)−Q(s,a)]
其中:- α \alpha α 是学习率,控制新信息覆盖旧信息的速度。
- γ \gamma γ 是折扣因子,表示未来奖励的重要性。读者们可以回忆一下为什么需要对未来的奖励引入折扣因子。
- R ( s , a ) R(s,a) R(s,a) 是即时奖励。
- s ′ s' s′ 是新状态。$ \max_{a’} Q(s’, a’) $表示了对于未来的期望。
也有舍去学习率 α \alpha α的简化版本:
Q ( s , a ) ← R ( s , a ) + γ max a ′ Q ( s ′ , a ′ ) Q(s, a) \leftarrow R(s,a) + \gamma \max_{a'} Q(s', a') Q(s,a)←R(s,a)+γa′maxQ(s′,a′) -
探索与利用
智能体在选择动作时,通常使用 ϵ \epsilon ϵ-贪婪策略,即以概率 ϵ \epsilon ϵ 随机选择动作(探索),以概率 1 − ϵ 1 - \epsilon 1−ϵ 选择当前 Q值最高的动作(利用)。随着训练的进行, ϵ \epsilon ϵ 逐渐减小。
1.3 算法示例
只给公式或许难以让读者理解到Q-learning的整个运行流程,所以我们不妨以“控制一个Agent玩密室逃脱”为例。注意,此处的计算都以简化的贝尔曼方程为例。
如图所示,Agent会随机被刷新到 [ 0 , 5 ] [0,5] [0,5]这五个区域之中,而目标则是到达区域 5 5 5。各个区域之间的连通关系已经在图中给出,我们不妨将到达区域 5 5 5的 R e w a r d Reward Reward设置为100,其余设置为0,以展现游戏目标。
我们将上图进行一定简化,并标上 R e w a r d Reward Reward,可得下图:
-
第一步:初始化Q和R
Q表格与R表格类似,都是行为状态State,列为动作Action。表格中 − 1 -1 −1表示不可行的状态。
我们不妨假设,初始状态为 1 1 1。
-
第二步:随机尝试
根据R-table,当初始状态为 1 1 1时,我们只能走3 or 5(限制条件).虽然R矩阵中 R [ 1 , 5 ] R[1,5] R[1,5]是明晃晃的一百,但是Agent并不知道这一点,他只了解自己的Q-table。在自己的Q-table全为0的情况下,Agent肯定只能随机尝试了。
假如Agent选择了进入状态 5 5 5,那么Q-table的 Q ( 1 , 5 ) Q(1,5) Q(1,5)就会随之更新(不妨将折扣因子 γ \gamma γ定为0.8):
Q ( 1 , 5 ) = R ( 1 , 5 ) + 0.8 ∗ Max [ Q ( 5 , 1 ) , Q ( 5 , 4 ) , Q ( 5 , 5 ) ] = 100 + 0.8 ∗ 0 = 100 Q(1, 5) = R(1, 5) + 0.8 * \text{Max}[Q(5, 1), Q(5, 4), Q(5, 5)\text{]} = 100 + 0.8 * 0 = 100 Q(1,5)=R(1,5)+0.8∗Max[Q(5,1),Q(5,4),Q(5,5)]=100+0.8∗0=100
这时我们发现,获得了100的 R e w a r d Reward Reward,游戏结束。
-
第三步:迭代开始
在第一轮游戏中,我们仅更新了Q-table中的一个值。于是新的一轮游戏开始,假设我们初始状态选到了 3 3 3,我们又在Action [ 1 , 2 , 4 ] [1,2,4] [1,2,4]中选到了 1 1 1,接下来,可以更新 Q ( 3 , 1 ) Q(3,1) Q(3,1):
Q ( 3 , 1 ) = R ( 3 , 1 ) + 0.8 max ( Q ( 1 , 3 ) , Q ( 1 , 5 ) ) = 0 + 0.8 × max ( 0 , 100 ) = 80 Q(3, 1) = R(3, 1) + 0.8 \max(Q(1, 3), Q(1, 5)) \\ = 0 + 0.8 \times \max(0, 100) \\ = 80 Q(3,1)=R(3,1)+0.8max(Q(1,3),Q(1,5))=0+0.8×max(0,100)=80
同样的操作,往复进行。直到本轮游戏结束,直到Q-table完全更新。
2. Deep Q-Network
2.1 基本原理
通过上面的具体算法示例,想必读者们对于Q-learning的流程已经有了清晰的了解。不过,细心的读者肯定会提出质疑:上面的算法恐怕只能针对于Q-table维度较小的情况,然而在大多数实际问题中,状态和动作肯定是上百万或者上千万个(比如读取一张图片),这就造成了维度灾难("Curse of Dimensionality)。一张Q-table又如何能应付呢?
于是 Deep Q-Network(DQN) 算法应运而生。其基本思路也很简单:将Q-table替换为一个神经网络,于是所有的问题就迎刃而解了。
无论是Q-learning还是DQN,其核心目的都是在给定 S S S的情况下,找到Value最大的Action。这一操作被称为拟合Q-Function.Q-learning的手段是创造一个简单直白的Q-table,而DQN作为神经网络算法,其手段则是通过更新网络参数,而其核心又是损失函数。
2.2 目标网络
细心的读者可能会开始思考,一个常见的神经网络的损失函数往往是预测值与真实值之间的均方误差(MSE),而DQN是在预测给定状态下各动作的Value,这玩意儿的真实值又是如何确定的呢?
读者们不妨回忆一下Q-learning中更新Q 值的方法:贝尔曼方程:
Q ( s , a ) = R ( s , a ) + γ max a ′ Q ( s ′ , a ′ ) Q(s, a) = R(s,a) + \gamma \max_{a'} Q(s', a') Q(s,a)=R(s,a)+γa′maxQ(s′,a′)
在DQN中我们延续类似的思路:真实值用贝尔曼方程计算得到的Q来代替,而预测值则用神经网络计算出。
虽然DQN延续了Q-learning中贝尔曼方程的思想,但直接使用当前神经网络参数计算目标Q值会带来一个关键问题:目标值本身会随着神经网络的更新而剧烈波动。在传统Q-learning中,Q表的更新是直接且同步的,而神经网络的高度非线性特性会导致每次参数更新后,Q值的估计发生显著偏移。这相当于在训练过程中不断"移动目标",使损失函数陷入追逐动态目标的困境,严重降低学习稳定性。
为了解决这一问题,DQN创新性地引入了目标网络(Target Network)的概念。目标网络与主网络(预测Q值的网络)结构完全相同,但其参数更新采用延迟更新机制。具体而言,目标网络的参数 θ − \theta^- θ−每隔固定步数从主网络参数 θ \theta θ中复制,而在两次更新之间保持冻结状态。这种设计使得目标Q值的计算在短期内具有稳定性,为损失函数提供了相对固定的优化目标。
此时,贝尔曼方程中的目标Q值将由目标网络计算得到:
y i DQN = r + γ max a ′ Q ( s ′ , a ′ ; θ i − ) y_i^{\text{DQN}} = r + \gamma \max_{a'} Q(s', a'; \theta_i^-) yiDQN=r+γa′maxQ(s′,a′;θi−)
我们再重新解释一下各字母含义:
- a a a 是在状态 s s s 下采取的动作( s s s是当前状态)。
- r r r 是采取动作 a a a 后获得的即时奖励。
- s ′ s' s′ 是采取动作 a a a 后到达的新状态。
- a ′ a' a′表示在状态 s ′ s' s′下可以采取的所有动作
- θ − \theta^- θ−表示目标网络参数。
引入目标网络后,损失函数可以重新定义为:
L i ( θ i ) = E s , a , r , s ′ [ ( r + γ max a ′ Q ( s ′ , a ′ ; θ i − ) ⏟ 目标网络计算的稳定目标 − Q ( s , a ; θ i ) ⏟ 主网络的当前预测 ) 2 ] L_i(\theta_i) = \mathbb{E}_{s, a, r, s'} \left[ \left( \underbrace{r + \gamma \max_{a'} Q(s', a'; \theta_i^-)}_{\text{目标网络计算的稳定目标}} - \underbrace{Q(s, a; \theta_i)}_{\text{主网络的当前预测}} \right)^2 \right] Li(θi)=Es,a,r,s′
目标网络计算的稳定目标
r+γa′maxQ(s′,a′;θi−)−主网络的当前预测
Q(s,a;θi)
2
通过目标网络与主网络的解耦,DQN实现了短期目标稳定化与长期知识传递的平衡。这种机制类似于教师-学生模型:目标网络作为"经验丰富的教师"定期提供可靠的目标值,而主网络作为"学生"通过持续优化逐步逼近这些经过沉淀的知识。
一旦损失函数确定,剩下的优化方法、反向传播等操作就与一般的监督学习大同小异。
值得注意的是,DQN网络的输入是状态 S S S,而输出是动作 A A A,所以当动作空间为连续时,一般会采取离散化动作空间的方法。即对于连续动作空间,可以将其离散化,即把连续的动作值映射到有限的离散动作上。例如,对于一个连续的控制任务,可以将动作空间划分为几个区间,每个区间对应一个离散动作。这样,DQN的输出就变成了有限个离散动作的Q值。
并且,在实际运用中,对于离散动作空间,DQN的输出一般是使用Softmax函数来转换为概率分布。这样,每个动作的Q值可以表示为一个概率,Agent根据这个概率分布来选择动作。
2.2 经验回放
在【强化学习入门】II:从策略梯度到PPO算法中,已经强调过Off Policy之于On Policy的好处。而经验回放,即Experience Replay正是使强化学习模型实现Off Policy的关键。
经验回放的基本概念
经验回放的核心思想是将智能体在环境中的交互经验存储起来,然后在训练过程中随机抽取这些经验进行学习。具体来说,经验回放包括以下几个关键步骤:
- 经验存储:将智能体在环境中的交互经验存储到一个缓冲区(Experience Replay Buffer)中。每条经验通常是一个四元组 ( s , a , r , s ′ ) (s, a, r, s') (s,a,r,s′),其中:
- s s s 是当前状态(State)。
- a a a 是在状态 s s s 下采取的动作(Action)。
- r r r 是执行动作 a a a 后获得的奖励(Reward)。
- s ′ s' s′ 是执行动作 a a a 后进入的新状态(Next State)。
- 随机采样:在训练过程中,从经验回放缓冲区中随机抽取一批经验样本(通常是一个小批量,如32或64条经验)。
- 训练更新:使用这些随机抽取的经验样本更新神经网络的参数,从而优化Q值函数。
经验回放的作用
- 打破数据相关性:在强化学习中,智能体与环境的交互是连续的,相邻的经验之间存在很强的相关性。这种相关性可能导致神经网络的训练不稳定。通过随机采样,经验回放可以打破这种相关性,使训练更加稳定。
- 提高数据利用效率:智能体在环境中的每一次交互都可以被多次用于训练,而不是只使用一次就丢弃。这大大提高了数据的利用效率,尤其是在数据稀缺的情况下。
引入经验回放后,还能解决一个概念上的问题:DQN网络的输入到底是什么?因为根据损失函数的公式,我们可以发现有 ( s , a , r , s ′ ) (s, a, r, s') (s,a,r,s′)(用于计算 y i DQN y_i^{\text{DQN}} yiDQN),难道DQN网络的输入向量X有这麽长?
答案自然是不会。DQN网络的输入永远只有当前状态 s s s,而 y i DQN y_i^{\text{DQN}} yiDQN的计算则是使用经验回放缓冲区中取出的 ( s , a , r , s ′ ) (s, a, r, s') (s,a,r,s′)计算。
总结
本文写作主要参考深度强化学习DQN算法及训练。
写作本文的目的主要是发现大部分讲解DQN的文章要么来得太陡小白看不懂,要么就是没有提到DQN的两大核心改进,或者就算提到了读者也不明白为什么需要这样的改进。