强化学习算法—DQN

Q-Learning

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从Q-Learning到DQN

  • 维度灾难

在上面的简单分析中,我们使用表格来表示Q(s,a),但是这个在现实的很多问题上是几乎不可行的,因为状态实在是太多。使用表格的方式根本存不下。
举Atari为例子。
计算机玩Atari游戏的要求是输入原始图像数据,也就是210x160像素的图片,然后输出几个按键动作。总之就是和人类的要求一样,纯视觉输入,然后让计算机自己玩游戏。那么这种情况下,到底有多少种状态呢?有可能每一秒钟的状态都不一样。因为,从理论上看,如果每一个像素都有256种选择,那么就有 25 6 210 × 160 256^{210\times160} 这简直是天文数字。所以,我们是不可能通过表格来存储状态的。我们有必要对状态的维度进行压缩,解决办法就是 价值函数近似Value Function Approximation

  • 值函数近似(value function approximation)

什么是值函数近似呢?说起来很简单,就是用一个函数来表示 Q ( s , a ) Q(s, a) 。即:
Q ( s , a ) = f ( s , a ) Q(s, a) = f(s, a)
f f 可以是任意类型的函数,比如线性函数:
Q ( s , a ) = w 1 s + w 2 a + b Q(s, a) = w_{1}s + w_{2}a + b 其中 w 1 , w 2 b w_{1}, w_{2},b 是函数 f f 的参数,那么就有:
Q ( s , a ) = f ( s , a , w ) Q(s, a) = f(s, a, w)
为什么叫近似,因为我们不知道 Q Q 值的实际分布情况,本质上就是用一个函数来近似 Q Q 值的分布,所以可以说是:
Q ( s , a ) Q(s, a)\approx

  • 高维度状态输入,低维度动作输出的表示问题

对于Atari游戏而言,这是一个高维状态输入(原始图像),低维动作输出(只有几个离散的动作,比如上下左右)。那么怎么来表示这个函数f呢?
难道把高维s和低维a加在一起作为输入吗?
必须承认这样也是可以的。但总感觉有点别扭。特别是,其实我们只需要对高维状态进行降维,而不需要对动作也进行降维处理。
那么,有什么更好的表示方法吗?
当然有,怎么做呢?

其实就是 Q ( s ) f ( s , w ) Q(s) \approx f(s, w) ,只把状态 s s 作为i输入,但是输出的时候输出每一个动作的 Q Q 值,也就是输出每一个动作的向量 [ Q ( s , a ) 1 , Q ( s , a 2 ) , Q ( s , a 3 ) , . . . , Q ( s , a n ) ] [Q(s, a)_{1}, Q(s, a_{2}), Q(s, a_{3}), ..., Q(s, a_{n})] ,记住这里输出的是一个值,只不过是包含了所有动作的 Q Q 值的向量而已。这样我们就只要输入状态 S S ,而且同时可以得到所有动作的Q值,也将更方便的进行 Q L e a r n i n g Q-Learning 中动作的选择与 Q Q 值更新(这一点后面大家会理解)。

  • Q Q 值神经网络化

终于到了和深度学习相结合的一步了。
意思很清楚,就是我们用一个深度神经网络来表示这个函数 f f
以DQN为例,输入是经过处理的4个连续的 8484 8484 图像,然后经过两个卷积层,两个全连接层,最后输出包含每一个动作 Q Q 值的向量。
对于这个网络的结构,针对不同的问题可以有不同的设置。如果大家熟悉Tensorflow,那么肯定知道创建一个网络是多么简单的一件事。
总之 ,用神经网络来表示 Q Q 值非常简单, Q Q 值也就变成了用 Q Q 网络(Q-Network)来表示。接下来就到了很多人都会困惑的问题,那就是怎么训练Q网络呢?

  • DQN算法

我们知道,神经网络的训练是一个最优化问题,最优化一个损失函数 l o s s f u n c t i o n loss function ,也就是标签和网络的偏差,目标是让损失函数最小化。为此,我们需要样本,巨量的有标签数据,然后通过反向传播使用梯度下降的方法来更新神经网络的参数 。
所以,要训练Q网络,我们要能够为Q网络提供有标签的样本。
所以,问题就变成:如何为Q网络提供有标签的样本?
答案就是利用Q-learning算法和
大家回想一下Q-learning算法,Q值的更新依靠Reward和Q值计算出来的目标Q值:
Q ( S t , A t ) Q ( S t , A t ) + α [ R t + 1 + γ m a x a Q ( S t + 1 , a ) Q ( S t , A t ) ] Q(S_{t}, A_{t}) \leftarrow Q(S_{t}, A_{t}) + \alpha [R_{t+1} + \gamma \underset{a}{max} Q(S_{t+1}, a) - Q(S_t, A_t)]
因此,我们把目标Q值作为标签不就可以了。我们的目标不就是让Q值趋近于目标Q值吗?
因此,Q网络训练的损失函数就是:在这里插入图片描述
其中:
在这里插入图片描述
求倒可得:
在这里插入图片描述
既然确定了损失函数,也就是cost,确定了获取样本的方式。那么DQN的整个算法也就成型了!
接下来就是如何训练的问题了。

  • DQN训练

我们这里分析第一个版本的DQN,也就是NIPS2013提出的DQN。
具体的算法主要涉及到Experience Replay,也就是经验池的技巧,也就是如何存储样本及采样问题。
由于玩Atari采集的样本是一个时间序列,样本之间具有连续性,如果每次得到样本就更新Q值,受样本分布影响,效果会不好。因此,一个很直接的想法就是把样本先存起来,然后随机采样如何?这就是Experience Replay的意思。按照脑科学的观点,人的大脑也具有这样的机制,就是在回忆中学习。

那么上面的算法看起来很长,其实就是反复实验,然后存储数据。接下来数据存到一定程度,就每次随机采样数据,进行梯度下降。也就是:

在DQN中增强学习Q-Learning算法和深度学习算法的SGD训练是同步进行的。

通过Q-Learning获取无限量的训练样本,然后对神经网络进行训练。

记忆库(Experience Replay)和 固定Q-目标(Fixed Q-target)
DQN中有两个神经网络,一个参数相对固定的网络,叫做target-net,用来获取Q-target的数值,另一个叫做eval-net,用来获取Q-eval的数值。
我们在训练神经网楼哦时用到的损失函数(loss function),实际上就是 l o s s = Q t a r g e t Q e v a l loss = Q_{target}-Q_{eval}
反向传播真正训练的网络只有一个,就是eval-net。target-net只做正向传播得到Q-target( Q t a r g e t = R + γ m a x a Q ( s , a ) Q_{target} = R + \gamma \underset{a}{max}Q(s,a) ),其中 Q ( s , a ) Q(s, a) 是若干个经过target-net正向传播的结果。
训练的数据是从记忆库中随机提取的,记忆库记录着每一个状态下的行动,奖励,和下一个状态的结果(s, a, r, s’)。记忆库的大小有限,当记录的数据满了之后,下一个数据会覆盖记忆库中的第一个数据,记忆库就是这样覆盖更新的。
Q-target的网络target-net也会定期更新一下参数,由于target-net和eval-net的结构是一样的。更新q-target网络的参数就是直接将q-eval 的参数复制过来就行了。
DQN基本结构:
在这里插入图片描述
随机抽取记忆库中的数据进行学习,打乱了经历之间的相关性,使得神经网络更新更有效率,Fixed Q-targets 使target_net能够延迟更新参数从而也打乱了相关性。

Deep Mind 就是靠CNN, 记忆库和Fixed Q-target这三把利剑让机器学会了如何玩游戏,甚至在电子游戏中还能打败人类玩家。

DQN系列算法介绍

在这里插入图片描述

  1. 深度学习开山之作DQN

DeepMind《Playing Atari with Deep Reinforcement Learning》提出了DQN,DQN使用了卷积神经网络作为价值函数来拟合Q-Learning中的动作价值,这是第一个直接从原始像素中成功学习到控制策略的深度强化学习算法。DQN模型的核心就是卷积神经网络,使用Q-Learning算法来进行训练,其输入为原始像素,输出为价值函数。在不改变模型的架构和参数的条件下,DQN在七个Atari2600游戏上,击败了之前所有的算法,并在其中三个游戏上,击败了人类最佳水平。

将深度学习应用到强化学习上,面临诸多挑战。
第一个挑战,大多数成功的(有监督)深度学习算法都需要巨大的数据量,而强化学习算法通常只能提供稀疏的,有噪声的,以及延迟的奖励;同时强化学习的回报与相对应产生回报的动作之间可能有数千步的间隔,对比监督学习直截了当的输入输出映射,训练要难得多。
第二个挑战。深度学习通常假设数据样本独立同分布。而对于强化学习来说,作为训练样本的状态是一个序列,而且通常状态之间高度相关。就是,随着训练的进程,神经网络对于动作价值的估计不断得到优化。而随着神经网络参数的不断更新,其Q值输出也会跟着改变。这与深度学习要求的训练用的数据分布不变不符合。

DQN最关键的技术就是采用了经验回放。通过在经验回放中随机均匀采样,打破了训练样本之间的相关性。同时,采用过去多个样本做平均,也平滑了训练样本分布,减缓了样本分布变化的问题。

在经验回报中,将多个episode中,agent每一步使用 ε g r e e d y \varepsilon-greedy 来选择动作,产生的经验 e t = ( s t , a t , r t , s t + 1 ) e_{t} =(s_{t}, a_{t}, r_{t}, s_{t+1}) ,存入一个经验记忆池D中,在算法的参数更新循环里,对记忆池里的样本进行随机采样或批量随机采样,通过Q-Learning对模型参数进行更新。由于处理变长数据对神经网络来说有些困难,所以DQN使用固定长度的历史数据来表征状态,具体来说,就是利用过去三帧或四帧图像的融合。

这种方法(经验回放)对于传统的在线Q-Learning来说,有很多个优势。
第一个优势是,每一步的数据都可以被多次采样,极大的提高了数据效率。
第二个优势是,直接从连续的数据里学习效率低下,因为前后样本之间高度相关。而随机采样打破了这些相关性,因而降低了参数更新的方差。
第三个优势是,在线的Q-Learning下当前的参数决定了下一个参数更新所用到的数据样本。比如,当前的参数决定了最大动作是向左,那么接下来的样本多数也会是来自于左半边的样本,然后这些来自左半边的样本再用于训练。显然这样训练过程可能会陷入一个不好的循环,参数可能会收敛到局部极值,甚至发散。通过经验回放,数据分布会在过去多个状态下被平均,从而平滑了训练过程,避免了训练发散。由于使用了经验回放,算法必然是off-policy的,因为产生数据样本(动作选择)的网络参数与当前被训练的网络参数是不同的,也就是生成动作的policy与算法学习的policy是不同的。

实际操作中,经验回放仅存储最近的N个样本点,当参数更新时均匀的从这些样本点中采样。这种方法也有其缺点,经验池不能区分哪些样本点更重要;同时,经验池的样本也会不断的被最近的数据所覆盖掉。均匀采样也赋予了每个样本同样的重要性,更聪明的采样策略应该是对那些能够学到更多的样本点赋予更多的权重,类似于Prioritized Sweeping。

另外注意的是,DQN在每次参数更新之前,会固定上一次参数更新的网络参数,来产生本次更新的目标。注意这儿训练目标是随着训练过程变化的,这一点与监督学习在训练前就确定训练目标也是不一样的。

关于Q的处理,一种做法是将状态和(已经出现过的)动作值一起输入网络,然后输出对应的Q值。然而这样做的缺点是每一个动作值都需要重新前向计算一次。所以DQN采取的做法是,只将状态输入,然后每一个可能的动作对应一个Q值的输出,这样最主要的好处是只需要一次前向即可。最终的结构是,输入图像为84x84x4像素,第一个卷积层包含16个8x8 卷积核,以步长为4进行卷积,随后是整流非线性层;第二个卷积层为32个4x4卷积核,以步长为2卷积,再跟一个整流非线性层;接下来是全链接层和256个非线性单元;输出层则是一个全链接层产生动作个数个输出。在论文中,输出动作个数依据游戏不同为4-18个。

DeepMind共在7个游戏上测试了DQN的性能。所有游戏使用了相同的超参,但是Rreward进行了裁剪。将所有的正的Reward归为1,将所有的负Rreward归为0,0值Reward保持不变。这样做控制了反向传播的误差的范围,同时保证了多个游戏间可以使用相同的学习率。与此同时,这样做可能降低算法的性能,因为限制了奖励的大小所带来的额外信息。训练DQN使用了RMSProp算法,批大小为32,ξ-greedy,ξ从1下降到0.1,一百万帧后固定到0.1。算法总共训练了1000万帧;为了减小计算量,训练过程使用了跳帧,每4帧选择一次动作,中间的3帧延续前一帧的动作。

  1. DQN改进

Reference:
https://blog.csdn.net/qq_16234613/article/details/80268564
https://www.jianshu.com/p/b92dac7a4225

猜你喜欢

转载自blog.csdn.net/weixin_42018112/article/details/88564858