通俗讲解深度强化学习经典算法——DQN

一、序言

DQN算法是 DeepMind 团队在2015年提出的算法,该论文发表在 Nature 上,此后的一些DQN相关算法(如Double DQN、Dueling DQN、D3QN)都是在其基础上改进的。DQN可以说使强化学习进入到了深度强化学习时代,意义非常重大。
论文地址:Mnih, V., Kavukcuoglu, K., Silver, D. et al. Human-level control through deep reinforcement learning. Nature 518, 529–533 (2015).

二、算法介绍

2.1 核心思想

DQN的核心思想就是训练一个Q网络,这个Q网络输入当前环境的状态,输出为agent所有动作的Q值,agent选择具有最大Q值的动作作为当前时刻的行动,以此循环往复直至回合结束。
上述就是DQN的整体思想。此外,为了更好地训练Q网络以及保证算法的稳定性,论文提出了经验回放缓冲池、目标网络的思想,后续会详细讲解。

2.2 Q网络意义

在强化学习场景中,我们通过选择动作从而得到下一个状态,我们期望选择这个动作后一直到回合结束所能获得的回报最大,也就是说这个状态所能得到回报的数学期望最大。所以Q网络的Q值可以简单理解为当前状态的每个动作直到回合结束所能得到累计回报的数学期望最大值
那么接下来核心思想就是怎么训练出这样一个Q网络,用它来指导agent选择动作。

2.3 训练Q网络

agent的探索过程为:agent根据当前环境状态 s t s_t st选择动作 a t a_t at,环境根据 a t a_t at的好坏给一个奖励 r t r_t rt,最后环境会转移到下一个状态 s t + 1 s_{t+1} st+1。上述就是一步agent的操作,然后将上述提到的 s t s_t st a t a_t at r t r_t rt s t + 1 s_{t+1} st+1作为一个元组保存到一个列表中,后续用装满( s t s_t st a t a_t at r t r_t rt s t + 1 s_{t+1} st+1)的列表去更新Q网络。上述用到的思想就是经验回放,这个列表也就是经验回放缓冲池
具体的更新用到了时序差分的思想,结合 DQN 之后简单概括如下: s t s_t st的状态价值函数 V t V_t Vt我们不确定, s t + 1 s_{t+1} st+1的状态价值函数 V t + 1 V_{t+1} Vt+1我们也不确定,但是由 s t s_t st变到 s t + 1 s_{t+1} st+1时环境给的奖励是已知的。这就利用上了经验回放缓冲池中我们事先保存的元组( s t s_t st a t a_t at r t r_t rt s t + 1 s_{t+1} st+1),将 s t s_t st代入 Q 网络得到估测的 V t V_t Vt,将 s t + 1 s_{t+1} st+1代入 Q 网络得到估测的 V t + 1 V_{t+1} Vt+1,这两个值都是估测出来的,我们通过训练让它被估测的更准确一些。
在这里给出 Q-learning 的更新公式
Q ( s t , a t ) ← Q ( s t , a t ) + α [ r t + γ max ⁡ a ′ Q ( s t + 1 , a ′ ) − Q ( s t , a t ) ] Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[ r_t + \gamma \max_{a'} Q(s_{t+1}, a') - Q(s_t, a_t) \right] Q(st,at)Q(st,at)+α[rt+γamaxQ(st+1,a)Q(st,at)]其中: Q ( s t , a t ) Q(s_t, a_t) Q(st,at) 是在状态 s t s_t st 下选择动作 a t a_t at 的 Q 值。 α \alpha α 是学习率,控制 Q 值的更新幅度。 r t r_{t} rt 是在时间步 t t t 时获得的奖励。 γ \gamma γ 是折扣因子,用于衡量未来奖励的重要性。 max ⁡ a ′ Q ( s t + 1 , a ′ ) \max_{a'} Q(s_{t+1}, a') maxaQ(st+1,a) 是在新状态 s t + 1 s_{t+1} st+1 下可能获得的最大 Q 值。
在DQN算法中,更新思想也同Q-learning一样:我们使用Q网络计算出等式左右两边的值,更新网络参数使得等式左边的值无限接近等式右边的值。
在这里有人可能会有疑问:等式两边的值都是估计出来的,为什么要让等式左边的值去趋紧右边的值呢?这是因为等式右边的 r t r_t rt是确定的,它是环境根据我们做的 a t a_t at所反馈给我们的,它是确定的,不是估计的。
通过上述更新策略就可以训练处一个Q网络完成我们的需求了,但是DQN作者发现按照上述方法更新效果并不好,因为我们让等式左边趋近于等式右边,但是等式左右两边都是一个Q网络估算出来的,换而言之,我们在让一个动态变化的Q网络趋近于一个也在动态变化的Q网络,也就是说回归问题中的目标函数一直在变,这将会导致训练不稳定。所以为了解决这个问题,DQN使用了另一个非常重要的思想——目标Q网络,目标网络就是一个和Q网络结构一样的网络,但是参数被固定住,不随着Q网络更新而实时更新,在Q网络更新几次后再将目标网络的参数更新。
添加了目标网络之后,我们使用目标网络估算等式右边 Q ( s t + 1 , a ′ ) Q(s_{t+1}, a') Q(st+1,a)的值,这样就完美解决了回归问题中的不稳定问题。

2.4 实现代码

上述更新过程的核心代码如下:

q = q_net(states).gather(1, actions)  # 使用 Q网络估算当前状态 s_t的 Q值
max_target_q_net = target_q_net(next_states).max(1).values.unsqueeze(1)  # 使用目标 Q网络估算下一时刻状态 s_{t+1}的 Q值
target_q = rewards + (1 - ends) * GAMMA * max_target_q_net  # 计算目标 Q值,让 Q网络拟合这个值

# 使用 MSELoss梯度下降更新 q_net
loss = nn.MSELoss()(q, target_q)
q_net_optimizer.zero_grad()
loss.backward()
q_net_optimizer.step()

# 每更新 q_net UPDATE_TARGET次之后更新一次目标网络
if update_count % UPDATE_TARGET == 0:
	target_q_net.load_state_dict(q_net.state_dict())

DQN完整可运行代码见Github仓库,仓库的DQN目录下即为DQN算法完整代码,DQN目录下有三个文件,运行main方法即可训练,训练完成后运行test方法即可测试。
Github仓库地址:deep-reinforcement-learning

三、参考文献

[1]. https://www.nature.com/articles/nature14236
[2]. https://hrl.boyuai.com/
[3]. https://blog.csdn.net/qq_47997583/article/details/124457346

03-08
### DQN深度强化学习算法介绍 #### 一. 概念概述 DQN (Deep Q-Network) 是一种结合了深度神经网络与Q-Learning的方法,用于解决高维状态空间下的决策问题。传统Q-Learning通过查找表的形式存储每一个状态下采取不同行动所获得的价值量(Q值),然而这种方法面对复杂环境时效率极低甚至不可行,因为随着状态数目的增加,所需内存呈指数级增长[^1]。 为了克服这一挑战,研究人员提出了利用深层卷积神经网络作为函数逼近器的思想,使得模型可以直接从原始像素输入中提取特征并预测相应的Q值,而无需显式构建庞大的查表结构。此外,该框架还融入了两项关键技术——经验重放缓冲池(experience replay buffer)以及固定的目标Q网络(target network)[^3]。 #### 二. 关键技术解析 ##### 经验重放缓冲池(Experience Replay Buffer) 此机制允许代理将经历过的交互事件(即<state, action, reward, next_state>四元组)存入一个队列式的记忆库内,在训练过程中随机抽取样本批次来进行更新操作。这样做不仅打破了数据之间的关联性,提高了泛化能力;而且有助于稳定梯度下降过程中的参数调整方向。 ##### 固定目标Q网络(Target Network) 为了避免频繁变动的学习目标造成优化困难的情况发生,DQN采用双网路架构:一个是不断迭代改进的工作网络(evaluation network), 另外则是定期同步权重给前者的影子副本—目标网络。后者仅用来计算TD误差而不参与反向传播环节,从而确保每次估计都相对平稳可靠。 #### 三. 实现案例展示 下面给出一段简化版的Python代码片段,展示了如何使用TensorFlow/Keras搭建一个基本形式的DQN: ```python import numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from collections import deque class SimpleDQN: def __init__(self, state_size, action_size): self.state_size = state_size self.action_size = action_size self.memory = deque(maxlen=2000) self.gamma = 0.95 # 折扣因子 self.epsilon = 1.0 # 探索率初始值 self.epsilon_min = 0.01 self.epsilon_decay = 0.995 self.learning_rate = 0.001 self.model = self._build_model() def _build_model(self): model = Sequential() model.add(Dense(24, input_dim=self.state_size, activation='relu')) model.add(Dense(24, activation='relu')) model.add(Dense(self.action_size, activation='linear')) model.compile(loss="mse", optimizer="adam") return model def remember(self, state, action, reward, next_state, done): self.memory.append((state, action, reward, next_state, done)) def act(self, state): if np.random.rand() <= self.epsilon: return np.random.choice(self.action_size) act_values = self.model.predict(state) return np.argmax(act_values[0]) def train(self, batch_size=32): minibatch = random.sample(self.memory, batch_size) for state, action, reward, next_state, done in minibatch: target = reward if not done: target = (reward + self.gamma * np.amax(self.model.predict(next_state)[0])) target_f = self.model.predict(state) target_f[0][action] = target self.model.fit(state, target_f, epochs=1, verbose=0) if self.epsilon > self.epsilon_min: self.epsilon *= self.epsilon_decay ``` 上述代码定义了一个简单的DQN类`SimpleDQN`,其中包含了创建两层全连接隐藏层组成的评估网络(`_build_model`)、保存历史轨迹(`remember`)、依据当前策略选取行为(`act`)以及基于采样得到的小批量数据执行一次完整的训练循环(`train`)等功能模块。 对于更具体的应用场景比如路径规划,则可以参照MATLAB环境下实现的具体实例[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值