深度强化学习基础-DQN算法

148 阅读1分钟

DQN (基本概念)

关键词

  • 深度Q网络(deep Q-network,DQN):基于深度学习的Q学习算法,其结合了价值函数近似(value function approximation)与神经网络技术,并采用目标网络和经验回放等方法进行网络的训练。

  • 状态-价值函数(state-value function):其输入为演员某一时刻的状态,输出为一个标量,即当演员在对应的状态时,预期的到过程结束时间段内所能获得的价值。

  • 状态-价值函数贝尔曼方程(state-value function Bellman equation):基于状态-价值函数的贝尔曼方程,它表示在状态 sts_t 下对累积奖励 GtG_t 的期望。

  • Q函数(Q-function): 其也被称为动作价值函数(action-value function)。其输入是一个状态-动作对,即在某一具体的状态采取对应的动作,假设我们都使用某个策略 π\pi ,得到的累积奖励的期望值有多大。

  • 目标网络(target network):其可解决在基于时序差分的网络中,优化目标 Qπ(st,at)=rt+Qπ(st+1,π(st+1))Q_{\pi}\left(s_{t}, a_{t}\right) = r_{t}+Q_{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right) 左右两侧会同时变化使得训练过程不稳定,从而增大回归的难度的问题。目标网络选择将右边部分,即 rt+Qπ(st+1,π(st+1))r_{t}+Q_{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right) 固定,通过改变左边部分,即 Qπ(st,at)Q_{\pi}\left(s_{t}, a_{t}\right) 中的参数进行回归,这也是深度Q网络应用中比较重要的技巧。

  • 探索(exploration):我们在使用Q函数的时候,我们的策略完全取决于Q函数,这有可能导致出现对应的动作是固定的某几个数值的情况,而不像策略梯度中的输出是随机的,我们再从随机分布中采样选择动作。这会导致我们继续训练的输入值一样,从而“加重”输出的固定性,导致整个模型的表达能力急剧下降,这就是探索-利用窘境(exploration-exploitation dilemma)问题。我们可以使用 ε\varepsilon-贪心和玻尔兹曼探索(Boltzmann exploration)等探索方法进行优化。

  • 经验回放(experience replay):其会构建一个回放缓冲区(replay buffer)来保存许多经验,每一个经验的形式如下:在某一个状态 sts_t,采取某一个动作 ata_t,得到奖励 rtr_t,然后进入状态 st+1s_{t+1}。我们使用 π\pi 与环境交互多次,把收集到的经验都存储在回放缓冲区中。当我们的缓冲区“装满”后,就会自动删去最早进入缓冲区的经验。在训练时,对于每一轮迭代都有相对应的批量(batch)(与我们训练普通的网络一样,都是通过采样得到的),然后用这个批量中的经验去更新我们的Q函数。综上,Q函数在采样和训练的时候,会用到过去的经验,所以这里称这个方法为经验回放,其也是深度Q网络应用中比较重要的技巧。 传统的强化学习算法会使用表格的形式存储状态价值函数 V(s)V(s) 或动作价值函数 Q(s,a)Q(s,a),但是这样的方法存在很大的局限性。例如,现实中的强化学习任务所面临的状态空间往往是连续的,存在无穷多个状态,在这种情况下,就不能再使用表格对价值函数进行存储。价值函数近似利用函数直接拟合状态价值函数或动作价值函数,降低了对存储空间的要求,有效地解决了这个问题。

为了在连续的状态和动作空间中计算值函数 Qπ(s,a)Q_{\pi}(s,a),我们可以用一个函数 Qϕ(s,a)Q_{\phi}(\boldsymbol{s},\boldsymbol{a}) 来表示近似计算,称为价值函数近似(value function approximation)

Qϕ(s,a)Qπ(s,a) Q_{\phi}(\boldsymbol{s}, \boldsymbol{a}) \approx Q_{\pi}(\boldsymbol{s}, \boldsymbol{a})

其中,s\boldsymbol{s}a\boldsymbol{a} 分别是状态 ss 和动作 aa 的向量表示,函数 Qϕ(s,a)Q_{\phi}(\boldsymbol{s}, \boldsymbol{a}) 通常是一个参数为 ϕ\phi 的函数,比如神经网络,其输出为一个实数,称为 Q 网络(Q-network)

深度Q网络(deep Q-network,DQN)是指基于深度学习的Q学习算法,主要结合了价值函数近似与神经网络技术,并采用目标网络和经历回放的方法进行网络的训练。在 Q学习 中,我们使用表格来存储每个状态 ss 下采取动作 aa 获得的奖励,即状态-动作值函数 Q(s,a)Q(s,a)。然而,这种方法在状态量巨大甚至是连续的任务中,会遇到维度灾难问题,往往是不可行的。因此,深度Q网络 采用了价值函数近似的表示方法。

深度Q网络 算法是这样的,我们初始化两个网络------QQQ^\hat{Q}Q^\hat{Q} 就等于 QQ。一开始目标网络Q^\hat{Q}与原来的 Q 网络是一样的。在每一个回合中,我们用演员与环境交互,在每一次交互的过程中,都会得到一个状态 sts_t,会采取某一个动作 ata_t。 怎么知道采取哪一个动作 ata_t 呢?我们就根据现在的Q函数,但是要有探索的机制。比如我们用玻尔兹曼探索或是ε\varepsilon-贪心探索,接下来得到奖励 rtr_t,进入状态 st+1s_{t+1}。所以现在收集到一笔数据(st(s_tata_trtr_tst+1)s_{t+1}),我们将其放到回放缓冲区里面。如果回放缓冲区满了, 我们就把一些旧的数据丢掉。接下来我们就从回放缓冲区里面去采样数据,采样到的是 (si(s_{i}aia_{i}rir_{i}si+1)s_{i+1})。这笔数据与刚放进去的不一定是同一笔,我们可能抽到旧的。要注意的是,我们采样出来不是一笔数据,采样出来的是一个批量的数据,采样一些经验出来。 接下来就是计算目标。假设我们采样出一笔数据,根据这笔数据去计算目标。目标要用目标网络 Q^\hat{Q} 来计算。目标是:

y=ri+maxaQ^(si+1,a) y=r_{i}+\max _{a} \hat{Q}\left(s_{i+1}, a\right)

其中,aa 是让 Q^\hat{Q} 值最大的动作。因为我们在状态 si+1s_{i+1}会采取的动作 aa 就是可以让 Q^\hat{Q}值最大的那一个动作。接下来我们要更新 Q 值,就把它当作一个回归问题。我们希望 Q(si,ai)Q(s_i,a_i) 与目标越接近越好。假设已经更新了一定的次数,比如 CC 次,设 C=100C = 100, 那我们就把 Q^\hat{Q} 设成 QQ,这就是 深度Q网络 算法。

image.png

习题

1 为什么在深度Q网络中采用价值函数近似的表示方法?

首先深度Q网络为基于深度学习的Q学习算法,而在Q学习中,我们使用表格来存储每一个状态下动作的奖励,即我们在正文中介绍的动作价值函数 Q(s,a)Q(s,a) 。但是在我们的实际任务中,状态量通常数量巨大,并且在连续任务中会遇到维度灾难等问题,使用真正的价值函数通常是不切实际的,所以使用了与价值函数近似的表示方法。

2 评论员的输出通常与哪几个值直接相关?

与状态和演员直接相关。我们在讨论输出时通常是针对一个演员衡量一个状态的好坏,也就是状态、价值从本质上来说是依赖于演员的。不同的演员在相同的状态下也会有不同的输出。

3 我们通常怎么衡量状态价值函数 Vπ(s)V_{\pi}(s) ?其优势和劣势分别有哪些?

(1)基于蒙特卡洛的方法:本质上就是让演员与环境交互。评论员根据统计结果,将演员和状态对应起来,即如果演员看到某一状态 sas_a ,将预测接下来的累积奖励有多大,如果看到另一个状态 sbs_b,将预测接下来的累积奖励有多大。但是其普适性不好,其需要匹配到所有的状态。如果我们面对的是一个简单的例如贪吃蛇游戏等状态有限的问题还可以应对,但是如果我们面对的是一个图片型的任务,我们几乎不可能将所有的状态(对应每一帧的图像)的都“记录”下来。总之,其不能对未出现过的输入状态进行对应价值的输出。

(2)基于蒙特卡洛的网络方法:为了弥补上面描述的基于蒙特卡洛的方法的不足,我们将其中的状态价值函数 Vπ(s)V_{\pi}(s) 定义为一个网络,其可以对于从未出现过的输入状态,根据网络的泛化和拟合能力,“估测”出一个价值输出。

(3)基于时序差分的网络方法,即基于时序差分的网络:与我们在前4章介绍的蒙特卡洛方法与时序差分方法的区别一样,基于时序差分的网络方法和基于蒙特卡洛的网络方法的区别也相同。在基于蒙特卡洛的方法中,每次我们都要计算累积奖励,也就是从某一个状态 sas_a 一直到游戏结束的时候,得到的所有奖励的总和。所以要应用基于蒙特卡洛的方法时,我们必须至少把游戏玩到结束。但有些游戏要玩到游戏结束才能够更新网络花费的时间太长了,因此我们会采用基于时序差分的网络方法。基于时序差分的网络方法不需要把游戏玩到结束,只要在游戏某一个状态 sts_t 的时候,采取动作 ata_t 得到奖励 rtr_t ,进入状态 st+1s_{t+1},就可以应用基于时序差分的网络方法。其公式与之前介绍的时序差分方法类似,即 Vπ(st)=Vπ(st+1)+rtV_{\pi}\left(s_{t}\right)=V_{\pi}\left(s_{t+1}\right)+r_{t}

(4)基于蒙特卡洛方法和基于时序差分方法的区别在于: 蒙特卡洛方法本身具有很大的随机性,我们可以将其 GaG_a 视为一个随机变量,所以其最终的偏差很大。而对于时序差分,其具有随机的变量 rr 。因为在状态 sts_t 采取同一个动作,所得的奖励也不一定是一样的,所以对于时序差分方法来说,rr 是一个随机变量。但是相对于蒙特卡洛方法的 GaG_a 来说,rr 的随机性非常小,这是因为 GaG_a 本身就是由很多的 rr 组合而成的。从另一个角度来说,在时序差分方法中,我们的前提是 rt=Vπ(st+1)Vπ(st)r_t=V_{\pi}\left(s_{t+1}\right)-V_{\pi}\left(s_{t}\right) ,但是我们通常无法保证 Vπ(st+1)V_{\pi}\left(s_{t+1}\right)Vπ(st)V_{\pi}\left(s_{t}\right) 计算的误差为0。所以当 Vπ(st+1)V_{\pi}\left(s_{t+1}\right)Vπ(st)V_{\pi}\left(s_{t}\right) 计算得不准确,得到的结果也会是不准确的。总之,两者各有优劣。

(5)目前,基于时序差分的方法是比较常用的,基于蒙特卡洛的方法其实是比较少用的。

4 基于本章正文介绍的基于蒙特卡洛的网络方法,我们怎么训练模型呢?或者我们应该将其看作机器学习中什么类型的问题呢?

理想状态下,我们期望对于一个输入状态,输出其无误差的奖励价值。对于价值函数,如果输入状态是 sas_a,正确的输出价值应该是 GaG_a。如果输入状态是 sbs_b,正确的输出价值应该是 GbG_b。所以在训练的时候,其就是一个典型的机器学习中的回归问题。我们实际中需要输出的仅仅是一个非精确值,即我们希望在输入状态 sas_a 的时候,输出价值与 GaG_a 越近越好;输入 sbs_b 的时候,输出价值与 GbG_b 越近越好。其训练方法与我们在训练卷积神经网络等深度神经网络时的方法类似。

5 基于本章正文中介绍的基于时序差分的网络方法,具体地,我们应该怎么训练模型呢?

基于时序差分网络的核心函数为 Vπ(st)=Vπ(st+1)+rtV_{\pi}\left(s_{t}\right)=V_{\pi}\left(s_{t+1}\right)+r_{t}。我们将状态 sts_t 输入网络,因为将 sts_t 输入网络会得到输出 Vπ(st)V_{\pi}(s_t),同样将 st+1s_{t+1} 输入网络会得到Vπ(st+1)V_{\pi}(s_{t+1})。同时核心函数 Vπ(st)=Vπ(st+1)+rtV_{\pi}\left(s_{t}\right)=V_{\pi}\left(s_{t+1}\right)+r_{t} 告诉我们, Vπ(st)V_{\pi}(s_t)Vπ(st+1)V_{\pi}(s_{t+1}) 的值应该是 rtr_t。我们希望它们两个相减的损失值与 rtr_t 尽可能地接近。这也是网络的优化目标,我们称之为损失函数。

6 动作价值函数和状态价值函数的有什么区别和联系?

(1)状态价值函数的输入是一个状态,它根据状态计算出当前这个状态以后的累积奖励的期望值是多少。

(2)动作价值函数的输入是状态-动作对,即在某一个状态采取某一个动作,同时假设我们都使用策略 π\pi ,得到的累积奖励的期望值是多少。

7 请介绍Q函数的两种表示方法。

(1)使用状态-动作对表示时,即当Q函数的输入是状态-动作对时,输出就是一个标量。

(2)仅使用状态表示时,即当Q函数的输入仅是一个状态时,输出就是多个价值。

8 当得到了Q函数后,我们应当如何找到更好的策略 π\pi' 呢?或者说 π\pi' 的本质是什么?

首先, π\pi'π(s)=argmaxaQπ(s,a)\pi^{\prime}(s)=\underset{a}{\arg \max} Q_{\pi}(s, a) 计算而得,其表示假设我们已经学习出 π\pi 的Q函数,对于某一个状态 ss ,把所有可能的动作 aa 一一代入这个Q函数,看看哪一个动作 aa 可以让Q函数的价值最大,那么该动作就是 π\pi' 将会执行的动作。所以根据以上方法决定动作的策略 π\pi' 一定比原来的策略 π\pi 要好,即 Vπ(s)Vπ(s)V_{\pi^{\prime}}(s) \geqslant V_{\pi}(s)

9 解决探索-利用窘境问题的探索的方法有哪些?

(1) ε\varepsilon-贪心: 我们有 1ε1-\varepsilon 的概率(通常 ε\varepsilon 很小)完全按照Q函数决定动作,但是有 ε\varepsilon 的概率使得动作是随机的。通常在实现上, ε\varepsilon的值会随着时间递减。也就是在最开始的时候,因为还不知道哪个动作是比较好的,所以我们会花比较大的力气做探索。接下来随着训练的次数越来越多,我们已经比较确定哪一种策略是比较好的,就会减少探索,从而把 ε\varepsilon 的值变小,主要根据Q函数来决定未来的动作,随机性就会变小。

(2) 玻尔兹曼探索:这个方法比较像策略梯度。在策略梯度里面,网络的输出是一个期望动作空间上的一个概率分布,我们根据概率分布去采样。所以也可以根据Q值确定一个概率分布,假设某一个动作的Q值越大,代表它越好,我们采取这个动作的概率就越高。

10 我们使用经验回放有什么好处?

(1)首先,在强化学习的整个过程中,最花时间的过程是与环境交互,使用GPU乃至TPU来训练网络相对来说是比较快的。而用回放缓冲区可以减少与环境交互的次数。因为在训练的时候,我们的经验不需要通通来自于某一个策略(或者当前时刻的策略)。一些由过去的策略所得到的经验可以放在回放缓冲区中被使用多次,被反复地再利用,这样采样到的经验才能被高效地利用。

(2)另外,在训练网络的时候,我们其实希望一个批量里面的数据越多样越好。如果一个批量里面的数据都是同性质的,我们训练出的模型的拟合能力可能不会很乐观。如果一个批量里面都是一样的数据,在训练的时候,拟合效果会比较差。如果回放缓冲区里面的经验通通来自于不同的策略,那么采样到的一个批量里面的数据会是比较多样的。这样可以保证我们的模型的性能至少不会很差。

11 在经验回放中我们观察 π\pi 的价值,发现里面混杂了一些不是 π\pi 的经验,这会有影响吗?

没影响。这并不是因为过去的 π\pi 与现在的 π\pi' 很相似,就算过去的π\pi 不是很相似,其实也是没有关系的。主要的原因是我们并不是去采样一条轨迹,我们只能采样一个经验,所以与是不是异策略是没有关系的。就算是异策略,就算是这些经验不是来自 π\pi,我们还是可以使用这些经验来估测 Qπ(s,a)Q_{\pi}(s,a)

引用参考

[1] datawhalechina.github.io/joyrl-book/…

[2] datawhalechina.github.io/easy-rl/#/

[3] speech.ee.ntu.edu.tw/~tlkagk/cou…