第三章、DQN(Deep Q-Network)
0 前言
DQN是一个off-policy(离线策略)算法,它通过与环境交互获取采样数据(经验放回池),并利用这些数据训练一个神经网络,该神经网络是用来近似最优动作价值函数的。
在阅读下述内容之前,假设你以理解以下概念及内容:状态空间、动作空间、奖励、折扣回报、动作价值函数、最优动作价值函数及TD误差等。
1 DQN
我们已知加入能获取一个函数该函数告诉我们在某种情况下应该做什么动作是最好的,那么我们的任务就完成了,而这个函数实际上在DQN算法中就是最优动作价值函数,记为 Q ⋆ ( s , a ) Q_{\star}(s,a) Q⋆(s,a)。而事实上我们要获得该函数的显性表达式几乎是不可能完成的,因此我们需要进行近似,随着深度学习的不断发展,网络层数的增加以及激活函数的变化可以满足我们近似各种各样未知函数。因此在DQN中我们考虑使用一个神经网络来近似最优动作价值函数。
学习的目标:对于所有的 s s s(状态)和 a a a(动作),DQN预测 Q ( s , a ; w ) Q(s,a;w) Q(s,a;w)尽量的接近 Q ⋆ ( s , a ) Q_{\star}(s,a) Q⋆(s,a)
整体框架理解:
1、假设我们现在有一个神经网络,该神经网络的输入为状态,输出为不同动作的价值。
例:如下图所示现在的 D Q N DQN DQN模型他告诉我们在 s t s_t st这种环境下应该做动作 a 2 a_2 a2(即 Q ( a 2 ) Q(a_2) Q(a2)的值最大我们记作 Q t Q_t Qt),执行 a 2 a_2 a2与环境交互,环境变为 s t + 1 s_{t+1} st+1,将 s t + 1 s_{t+1} st+1输入到 D Q N DQN DQN中会获取到新的 Q t + 1 Q_{t+1} Qt+1这里我们只关注价值并不关注动作,因为它并不再与环境交互。
现在盘点一下我们有哪些量:
- s t s_t st:t时刻的状态。
- a t a_t at:t时刻的动作。
- Q t Q_t Qt:t时刻的价值。
- s t + 1 s_{t+1} st+1:t+1时刻的状态
- Q t + 1 Q_{t+1} Qt+1:t+1时刻的价值。
那么现在考虑的问题就变成了,我已知上述内容怎么来优化DQN,让它更接近最优动作价值函数?(如果你熟悉神经网络,你会发现现在我们要训练DQN缺少了一个最关键的东西,就是每个动作在该时刻下的真实价值,因为其实上面用的DQN得到的值其实都是预测的,是不准确的,但事实上我们没办法像图片分类那样给每个环境对应的结果打上标签,那怎么办呢?解决这个问题实际上用到就是伟大的TD算法。)
Q t Q_t Qt是t时刻的价值,是估计出来的结果,并不准确;同样的 Q t + 1 Q_{t+1} Qt+1是t+1时刻的价值,也是估计的结果,同样不准确。并且理想情况下其实 Q t Q_t Qt和 Q t + 1 Q_{t+1} Qt+1之间有一定的关系,关系式为 Q t = r t + γ ⋅ Q t + 1 Q_t=r_t+\gamma\cdot Q_{t+1} Qt=rt+γ⋅Qt+1,其中 r t r_t rt是t时刻选择的动作的价值。
那么是不是说,如果 r t r_t rt是真实的,或者说是根据我们期待的结果得到的一个奖励值,在这种情况下 r t + γ ⋅ Q t + 1 r_t+\gamma\cdot Q_{t+1} rt+γ⋅Qt+1(这就是所谓的TD目标)比 Q t Q_t Qt的值更准确。那么我们就可以让 Q t − r t + γ ⋅ Q t + 1 Q_t-r_t+\gamma\cdot Q_{t+1} Qt−rt+γ⋅Qt+1变小来优化DQN,这就是所谓的TD误差。
2 DQN算法
- 初始化 q n e t q_{net} qnet。
- 使用TD算法更新神经网络中的参数 w w w。
- 最终 q n e t q_net qnet收敛到最优动作价值函数。
具体做法:
step1:收集训练数据,实际上就是建立经验放回池。
经验放回池中是一系列的 ( s t , a t , r t , s t + 1 ) (s_t,a_t,r_t,s_{t+1}) (st,at,rt,st+1)的四元组。
经验放回池的获取可以通过任意的策略获取,通常选择 ϵ − g r e e d y \epsilon-greedy ϵ−greedy策略,该策略如下:
a t = { a r g m a x a Q ~ ( s t , a ) 当概率 ≥ ϵ 均匀抽取动作空间中的一个动作 当概率 < ϵ a_t=\begin{cases}argmax_a\widetilde{Q}(s_t,a) \quad\quad当概率\geq \epsilon\\均匀抽取动作空间中的一个动作 \quad\quad 当概率<\epsilon\end{cases} at={argmaxaQ (st,a)当概率≥ϵ均匀抽取动作空间中的一个动作当概率<ϵ
此处我们联动一下skrl
中的智能体DQN,会发现Decision making基本上与上述内容契合
step2:基于经验放回池更新 q n e t q_{net} qnet
若记 t t t时刻的网络为 q n e t ( w n o w ) q_{net}(w_now) qnet(wnow)
已知四元组序列为 ( s t , a t , r t , s t + 1 ) (s_t,a_t,r_t,s_{t+1}) (st,at,rt,st+1)
1、记 q ^ t = q n e t ( s t , a t , w n o w ) \hat{q}_t=q_{net}(s_t,a_t,w_{now}) q^t=qnet(st,at,wnow)
2、记 s t + 1 s_{t+1} st+1状态下,最大值为 q ^ t + 1 = m a x a q n e t ( s t + 1 , a t , w n o w ) \hat{q}_{t+1}=max_aq_{net}(s_{t+1},a_t,w_{now}) q^t+1=maxaqnet(st+1,at,wnow)
3、记 y ^ t = r t + γ ⋅ q ^ t + 1 \hat{y}_t=r_t+\gamma \cdot \hat{q}_{t+1} y^t=rt+γ⋅q^t+1,我们的目标实际上是希望 q ^ t \hat{q}_t q^t越接近 y ^ t \hat{y}_t y^t越好,因此记 δ t = q ^ t − y ^ t \delta_t=\hat{q}_t-\hat{y}_t δt=q^t−y^t
4、对DQN做反向传播,得到梯度: g t = ∇ w q n e t ( s t , a t , w n o w ) g_t=\nabla_wq_{net}(s_t,a_t,w_{now}) gt=∇wqnet(st,at,wnow)
5、更新 w n e w = w n o w − α ⋅ δ t ⋅ g t w_{new}=w_{now}-\alpha\cdot \delta_t\cdot g_t wnew=wnow−α⋅δt⋅gt
此处我们联动一下skrl
中的智能体DQN,会发现Learning algorithm基本上与上述内容契合
这里给出skrl
中DQN的经验放回池的建立:
# instantiate a memory as experience replay
memory = RandomMemory(memory_size=50000, num_envs=env.num_envs, device=device, replacement=False)
''':param memory_size: 放回池容量上限,控制每个内部存储结构的最大样本存储量:type memory_size: int:param num_envs: 并行环境数量,适用于同时运行多个强化学习环境的情况:type num_envs: int, optional:param device: 数据存储设备,自动选择GPU(若可用)或CPU,影响计算效率:type device: str or torch.device, optional:param replacement: 抽样方式:True为有放回抽样(保证批次大小),False为无放回抽样(可能返回小于请求批次的数据):type replacement: bool, optional
'''
后面我们将和PPO中的memory做对比。