【EasyRL学习笔记】第六章 DQN 深度Q网络(基本概念)

文章目录

  • 一、深度Q网络的引入
    • 1.1 传统表格型方法的缺点
    • 1.2 引入深度Q网络
  • 二、状态价值函数
    • 2.1 基于蒙特卡洛的方法
    • 2.2 基于时序差分的方法
    • 2.3 两方法对比
    • 2.4 举例说明
  • 三、动作价值函数
  • 四、目标网络
  • 五、探索
    • 5.1 εvarepsilonε-贪心探索
    • 5.2 玻尔兹曼探索
  • 六、经验回放
  • 七、深度Q网络
  • 八、关键词总结
  • 九、习题
  • 十、面试题
  • 十一、Python代码实战

一、深度Q网络的引入

1.1 传统表格型方法的缺点

传统的强化学习算法会使用表格的形式存储状态价值函数 V(s)V(s)V(s) 或动作价值函数 Q(s,a)Q(s, a)Q(s,a) ,但是这样的方法存在很大的局 限性。

例如,现实中的强化学习任务所面临的状态空间往往是连续的,存在无穷多个状态,在这种情况下,就不能再使用 表格对价值函数进行存储。

1.2 引入深度Q网络

价值函数近似利用函数直接拟合状态价值函数或动作价值函数,降低了对存储空间的要求,有 效地解决了这个问题。

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

Qϕ(s,a)≈Qπ(s,a)Q_phi(boldsymbol{s}, boldsymbol{a}) approx Q_pi(boldsymbol{s}, boldsymbol{a}) Qϕ(s,a)Qπ(s,a)
其中, s、aboldsymbol{s} 、 boldsymbol{a}sa 分别是状态 sss 和动作 aaa 的向量表示,函数 Qϕ(s,a)Q_phi(boldsymbol{s}, boldsymbol{a})Qϕ(s,a) 通常是一个参数为 ϕphiϕ 的函数,比如神经网络,其输出为 一个实数,称为 Qmathrm{Q}Q 网络 (Q-network)。

深度Q网络(deep Q-network,DQN) 是指基于深度学习的Q学习算法,主要结合了价值函数近似与神经网络技术,并采用目标网络和经历回放的方法进行网络的训练。

在 Q学习中,我们使用表格来存储每个状态 sss 下采取动作 aaa 获得的奖励,即 状态-动作值函数 Q(s,a)Q(s, a)Q(s,a) 。然而,这种方法在状态量巨大甚至是连续的任务中,会遇到维度灾难问题,往往是不可行的。 因此,深度Q网络采用了价值函数近似的表示方法。


二、状态价值函数

深度Q网络 是基于价值的算法,在基于价值的算法里面,我们学习的不是策略,而是评论员(critic)

评论员就是评价演员的策略 πpiπ 好还是不好,即策略评估。

例如,有一种评论员称为状态价值函数 VπV_piVπ 。例如在玩雅达利游戏,状态 sss 是某一个画面, πpiπ 看到某一个画面,接下来一直 到游戏结束,期望的累积奖励有多大。如图下图a所示, VπV_piVπ 是一个函数,输入一个状态,它会输出一个标量。这个标量代 表演员的策略 πpiπ 看到状态 sss 的时候,预期到游戏结束的时候,它可以获得多大的奖励。例如,假设我们在玩太空侵略者, 图下图b 所示的状态 sss ,这个游戏画面, Vπ(s)V_pi(s)Vπ(s) 也许会很大,因为这时还有很多的怪物可以击杀,所以我们会得到很高的分 数。一直到游戏结束的时候,我们仍然有很多的分数可以获得。如下图c 所示的情况我们得到的 Vπ(s)V_pi(s)Vπ(s) 可能就很小,因为剩 下的怪物也不多,并且红色的防护罩已经消失了,所以我们可能很快就会“死掉”。因此接下来得到预期的奖励,就不会太大。
在这里插入图片描述

这里要强调一下,评论员的输出是与演员有关的,状态的价值其实取决于演员,当演员改变的时候,状态价值函数的输出其实也是会跟着改变的。
评论员其实都要绑定一个演员,它是在衡量某一个演员的好坏,而不是衡量一个状态的好坏。

衡量状态价值函数Vπ(s)V_{pi}(s)Vπ(s)有两种方法:基于蒙特卡洛的方法和基于时序差分的方法。

2.1 基于蒙特卡洛的方法

基于蒙特卡洛的方法 就是让演员与环境交互,我们要看演员好不好,就让演员与环境交互,让评论员评价。评论员就统计,演员如果看到状态 sas_asa ,接下来的累积奖励有多大; 如果它看到状态 sbs_bsb ,接下来的累积奖励有多大。

但是实际上,我们不可能看到所有的状 态。如果我们在玩雅达利游戏,状态是图像,那么无法看到所有的状态。所以实际上 Vπ(s)V_pi(s)Vπ(s) 是一个网络。对一个网络来 说,就算输入状态是从来都没有看过的,它也可以相办法估测一个值。怎么训练这个网络呢?

如下图所示,如果在状态 sas_asa ,接下来的累积奖励就是 GaG_aGa 。也就是对这个价值函数,如果输入是状态 sas_asa ,正确的输出应该是 GaG_aGa ;如果输入状态是 sbs_bsb ,正确的输出应该是 GbG_bGb 。所以在训练的时候,它就是一个回归问题 (regression problem)网络的输出就是一个值, 我们希望在输入 sas_asa 的时候,输出的值与 GaG_aGa 越接近越好;输入 sbs_bsb 的时候,输出的值与 GbG_bGb 越接近越好。接下来继续训练 网络,这是基于蒙特卡洛的方法。

在这里插入图片描述

2.2 基于时序差分的方法

在基于蒙特卡洛的方法中,每次我们都要计算累积奖励,也就是一直到游戏结束得到的所有奖励总和。所以我们必须玩到游戏结束。但是有些游戏时间很长,玩到游戏结束才能更新网络,这花的时间太多了所以我们在游戏时间长的环境中,一般选择采用基于时序差分的方法。

基于时序差分的方法不需要玩到游戏结束才能更新网络,只需要在游戏的某一个状态 sts_tst 的时候,采取动作 ata_tat 得到奖励 rtr_trt ,接下来进入状态 st+1s_{t+1}st+1 ,就可以使用时序差分的方法。我们可以通过下式来使用时序差分的方法。

Vπ(st)=Vπ(st+1)+rtV_pileft(s_tright)=V_pileft(s_{t+1}right)+r_t Vπ(st)=Vπ(st+1)+rt
假设我们现在用的是某一个策略 πpiπ ,在状态 sts_tst 时,它会采取动作 ata_tat ,得到奖励 rtr_trt ,接下来进入 st+1s_{t+1}st+1 。状态 st+1s_{t+1}st+1 的值与 状态 sts_tst 的值,它们的中间差了一项 rtr_trt ,这是因为我们把 st+1s_{t+1}st+1 的值加上得到的奖励 rtr_trt 就可以得到 sts_tst 的值。有了上式 , 在训练的时候,我们并不是直接估测 VπV_piVπ ,而是希望得到的结果 VπV_piVπ 可以满足上式 。我们是这样训练的,如下图所示, 我们把 sts_tst 输入网络,因为把 sts_tst 输入网络会得到 Vπ(st)V_pileft(s_tright)Vπ(st) ,把 st+1s_{t+1}st+1 输入网络会得到 Vπ(st+1),Vπ(st)V_pileft(s_{t+1}right) , V_pileft(s_tright)Vπ(st+1)Vπ(st)Vπ(st+1)V_pileft(s_{t+1}right)Vπ(st+1) 的值应 该是 rtr_trt 。我们希望它们相减的损失与 rtr_trt 接近,训练下去,更新 VπV_piVπ 的参数,我们就可以把 VπV_piVπ 函数学习出来。

在这里插入图片描述

2.3 两方法对比

蒙特卡洛方法与时序差分方法有什么差别呢?

如下图所示,蒙特卡洛方法最大的问题就是方差很大。因为我们在玩游戏 的时候,游戏本身是有随机性的,所以我们可以把 GaG_aGa 看成一个随机变量。因为我们每次到 sas_asa 的时候,最后得到的 GaG_aGa 其 实是不一样的。我们看到同样的状态 sas_{a}sa, 最后到游戏结束的时候,因为游戏本身是有随机性的,玩游戏的模型可能也有随机性,所以我们每次得到的 GaG_aGa 是不一样的,每一次得到的 GaG_aGa 的差别其实会很大。为什么会很大呢? 因为 GaG_aGa 是很多个奖励的和。(每个步骤的奖励都可以看为一个随机变量,这么多随机变量求和,不确定性大,方差固然就大)
在这里插入图片描述

通过下式,我们知道 GaG_aGa 的方差相较于某一个状态的奖励,它是比较大的。

Var⁡[kX]=k2Var⁡[X]operatorname{Var}[k X]=k^2 operatorname{Var}[X] Var[kX]=k2Var[X]

其中, Var 是指方差 (variance)。

如果用时序差分的方法,我们要去最小化

Vπ(st)⟷r+Vπ(st+1)V_pileft(s_tright) longleftrightarrow r+V_pileft(s_{t+1}right) Vπ(st)r+Vπ(st+1)
其中, rrr 具有随机性。因为即使我们在 sts_tst 采取同一个动作,得到的奖励也不一定是一样的,所以 rrr 是一个随机变量。rrr 的方差比 GaG_aGa 要小,因为 GaG_aGa 是很多 rrr 的加和,时序差分只是某一个 rrr 而已。 GaG_aGa 的方差会比较大, rrr 的方差会比较小。

但是这里我们会遇到的一个问题是 VπV_piVπ 的估计不一定准确。假设 VπV_piVπ 的估计不准确,我们使用上式学习出来的结果也会是 不准确的。

所以蒙特卡洛方法与时序差分方法各有优劣。其实时序差分方法是比较常用的,蒙特卡洛方法其实是比较少用 的。

2.4 举例说明

下图所示为时序差分方法与蒙特卡洛方法的差别。假设有某一个评论员,它去观察某一个策略 πpiπ 与环境交互 8 个回合的 结果。有一个策略 πpiπ 与环境交互了8 次,得到了 8 次玩游戏的结果。接下来这个评论员去估测状态的值。

在这里插入图片描述

我们先计算 sbs_bsb 的值。状态 sbs_bsb 在 8 场游戏里都存在,其中有 6 场得到奖励 1 ,有 2 场得到奖励 0 。所以如果我们要计算期 望值,只算智能体看到状态 sbs_bsb 以以后得到的奖励。智能体一直玩到游戏结束的时候得到的累积奖励期望值是 3/43 / 43/4 ,计算过程 为

6×1+2×08=68=34frac{6 times 1+2 times 0}{8}=frac{6}{8}=frac{3}{4} 86×1+2×0=86=43
sas_asa 期望的奖励到底应该是多少呢? 这里其实有两个可能的答案: 0 和 3/43 / 43/4 。为什么有两个可能的答案呢? 这取决于我们 用蒙特卡洛方法还是时序差分方法。用 蒙特卡洛方法与用 时序差分方法 算出来的结果是不一样的。

假如我们用蒙特卡洛方法, sas_asa 就出现一次,看到状态 sas_asa ,接下来累积奖励就是 0 ,所以 sas_asa 期望奖励就是 0 。但时序差分 方法在计算的时候,需要更新

Vπ(sa)=Vπ(sb)+rV_pileft(s_aright)=V_pileft(s_bright)+r Vπ(sa)=Vπ(sb)+r

因为我们在状态 sas_asa 得到奖励 r=0r=0r=0 以后,进入状态 sbs_bsb ,所以状态 sas_asa 的奖励等于状态 sbs_bsb 的奖励加上从状态 sas_asa 进入状态

用蒙特卡洛方法与时序差分方法估出来的结果很有可能是不一样的。就算评论员观察到一样的训练数据,它最后估出来的 结果也不一定是一样的。为什么会这样呢? 哪一个结果比较对呢? 其实都对。因为在第一个轨迹中, sas_asa 得到奖励 0 以人后, 再进入 sbs_bsb 也得到奖励 0 。这里有两个可能。

(1) sas_asa 是一个标志性的状态,只要看到 sas_asa 以后, sbs_bsb 就不会获得奖励, sas_asa 可能影响了 sbs_bsb 。如果是使用蒙特卡洛方法,它 会把 sas_asa 影响 sbs_bsb 这件事考虑进去。所以看到 sas_asa 以后,接下来 sbs_bsb 就得不到奖励, sbs_bsb 期望的奖励是 0 。

(2) 看到 sas_asa 以后, sbs_bsb 的奖励是 0 这件事只是巧合,并不是 sas_asa 造成的,而是因为 sbs_bsb 有时候就是会得到奖励 0 ,这只是单 纯“运气”的问题。其实平常 sbs_bsb 会得到的奖励期望值是 3/43 / 43/4,与sas_asa 是完全没有关系的。所以假设 sas_asa 之后会进入 sbs_bsb ,得到的 奖励按照时序差分方法来算应该是 3/43 / 43/4

不同的方法考虑了不同的假设,所以运算结果不同。


三、动作价值函数

还有另外一种评论员称为Q函数,它又被称为动作价值函数

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

动作价值函数的输入是一个状态-动作对,其指在某一个状态采取某一个动作,假设我们都使用策略 πpiπ ,得到的累积奖励的期望值有多大。

Q函数有两种写法:

(1)如下图a 所示,输入是状态与动作,输出就是一个标量。这种Q函数既适用于连续动作 (动作是无法穷举的),又适 用于离散动作。
(2)如下图b 所示,输入是一个状态,输出就是多个值。这种 QQQ 函数只适用于离散动作。假设动作是离散的,比如动作就 只有 3 个可能: 往左、往右或是开火。Q函数输出的 3 个值就分别代表 aaa 是往左的时候的 Qmathrm{Q}Q 值, aaa 是往右的时候的 Qmathrm{Q}Q 值, 还有 aaa 是开火的时候的 Q 值。
在这里插入图片描述
如果我们去估计Q函数,看到的结果可能如下图所示。假设我们有 3 个动作: 原地不动、向上、向下。假设在第一个状 态,不管采取哪个动作,最后到游戏结束的时候,得到的期望奖励都差不多。因为乒乓球在这个地方时,就算我们向下, 接下来我们应该还可以接到乒乓球,所以不管采取哪个动作,都相差不了太多。假设在第二个状态,乒乓球已经反弹到很 接近边缘的地方,这个时候我们采取向上的动作,才能接到乒乓球,才能得到正的奖励。如果我们站在原地不动或向下, 接下来都会错过这个乒乓球,得到的奖励就会是负的。假设在第三个状态,乒乓球离我们的球拍很近了,所以就要采取向 上的动作。假设在第四个状态,乒乓球被反弹回去,这时候采取哪个动作都差不多。这是动作价值函数的例子。
在这里插入图片描述

虽然我们学习的 Qmathrm{Q}Q 函数只能用来评估某一个策略 πpiπ 的好坏,但只要有了 Qmathrm{Q}Q 函数,我们就可以进行强化学习,就可以决定要 采取哪一个动作,就可以进行策略改进。

如下图所示,假设我们有一个初始的演员,也许一开始很差,随机的也没有关 系。初始的演员称为 π,πpi , piππ 与环境交互,会收集数据。接下来我们学习策略 πpiπQmathrm{Q}Q 值,去衡量一下 πpiπ 在某一个状态强制采 取某一个动作,接下来会得到的期望奖励,用时序差分方法或蒙特卡洛方法都是可以的。我们学习出一个Q函数以后,就 可以找到一个新的策略 π′pi^{prime}π ,策略 π′pi^{prime}π 会比原来的策略 πpiπ 要好 (稍后会定义什么是好) 。

所以假设我们有一个Q函数和某一 个策略 πpiπ ,根据策略 πpiπ 学习出策略 πpiπQmathrm{Q}Q 函数,接下来可以找到一个新的策略 π′pi^{prime}π ,它会比 πpiπ 要好。我们用 π′pi^{prime}π 取代 πpiπ ,再 去学习它的 Q函数,得到新的Q函数以后,再去寻找一个更好的策略。这样一直循环下去,策略就会越来越好。

在这里插入图片描述
首先要定义的是什么是好。 π′pi^{prime}π 一定会比 πpiπ 要好,什么是好呢? 这里的好是指,对所有可能的状态 sss 而言, Vπ′(s)⩾V_{pi^{prime}}(s) geqslantVπ(s) Vπ(s)V_pi(s)Vπ(s) 。也就是我们到同一个状态 sss 的时候,如果用 πpiπ 继续与环境交互,我们得到的奖励一定会小于等于用 π′pi^{prime}π 与环境交 互得到的奖励。所以不管在哪一个状态,我们用 π′pi^{prime}π 与环境交互,得到的期望奖励一定会比较大。所以 π′pi^{prime}π 是比 πpiπ 要好的策 略。

有了Q函数以后,我们把根据下式决定动作的策略称为 π′pi^{prime}π

π′(s)=arg⁡max⁡aQπ(s,a)pi^{prime}(s)=underset{a}{arg max } Q_pi(s, a) π(s)=aargmaxQπ(s,a)

π′pi^{prime}π 一定比 πpiπ 好。假设我们已经学习出 πpiπQmathrm{Q}Q 函数,在某一个状态 sss ,把所有可能的动作 aaa 一代入 Qmathrm{Q}Q 函数,看看哪一个 aaa 可以让Q函数的值最大,这个动作就是 π′pi^{prime}π 会采取的动作。

但是在这里要解决一个 arg⁡max⁡arg maxargmax 操作的问题,如果 aaa 是离散的,如 aaa 只有 3 个选项,将 每个动作都代入Q函数,看哪个动作的 Qmathrm{Q}Q 值最大,这没有问题。但如果 aaa 是连续的,我们要解决 arg⁡max⁡arg maxargmax 操作问题,就不 可行。

接下来讲一下为什么用 Qπ(s,a)Q_pi(s, a)Qπ(s,a) 决定的 π′pi^{prime}π 一定会比 πpiπ 好。假设有一个策略 π′pi^{prime}π ,它是由 QπQ_piQπ 决定的。我们要证明对所有 的状态 sss ,有 Vπ′(s)⩾Vπ(s)V_{pi^{prime}}(s) geqslant V_pi(s)Vπ(s)Vπ(s)
怎么证明呢? Vπ(s)V_pi(s)Vπ(s) 可写为

Vπ(s)=Qπ(s,π(s))V_pi(s)=Q_pi(s, pi(s)) Vπ(s)=Qπ(s,π(s))

假设在状态 sss 下按照策略 πpiπ ,会采取的动作就是 π(s)pi(s)π(s) ,我们算出来的 Qπ(s,π(s))Q_pi(s, pi(s))Qπ(s,π(s)) 会等于 Vπ(s)V_pi(s)Vπ(s) 。一般而言, Qπ(s,π(s))Q_pi(s, pi(s))Qπ(s,π(s)) 不一定等于 Vπ(s)V_pi(s)Vπ(s) ,因为动作不一定是 π(s)pi(s)π(s) 。但如果这个动作是 π(s),Qπ(s,π(s))pi(s) , Q_pi(s, pi(s))π(s)Qπ(s,π(s)) 是等于 Vπ(s)V_pi(s)Vπ(s) 的。
Qπ(s,π(s))Q_pi(s, pi(s))Qπ(s,π(s)) 还满足如下的关系:

Qπ(s,π(s))⩽max⁡aQπ(s,a)Q_pi(s, pi(s)) leqslant max _a Q_pi(s, a) Qπ(s,π(s))amaxQπ(s,a)

因为 aaa 是所有动作里面可以让 QQQ 函数取最大值的那个动作,所以 Qπ(s,a)Q_pi(s, a)Qπ(s,a) 一定大于等于 Qπ(s,π(s))∘Qπ(s,a)Q_pi(s, pi(s))_{circ} Q_pi(s, a)Qπ(s,π(s))Qπ(s,a) 中的 aaa 就是 π′(s)pi^{prime}(s)π(s) ,因为 π′(s)pi^{prime}(s)π(s) 输出的 aaa 可以让 Qπ(s,a)Q_pi(s, a)Qπ(s,a) 最大,所以我们可得

max⁡aQπ(s,a)=Qπ(s,π′(s))max _a Q_pi(s, a)=Q_pileft(s, pi^{prime}(s)right) amaxQπ(s,a)=Qπ(s,π(s))

于是

Vπ(s)⩽Qπ(s,π′(s))V_pi(s) leqslant Q_pileft(s, pi^{prime}(s)right) Vπ(s)Qπ(s,π(s))
也就是在某一个状态,如果我们按照策略 πpiπ 一直执行下去,得到的奖励一定会小于等于在状态 sss 故意不按照 πpiπ 所指示的方 向,而是按照 π′pi^{prime}π 的方向走一步得到的奖励。但只有第一步是按照 π′pi^{prime}π 的方向走,只有在状态 sss ,才按照 π′pi^{prime}π 的指示走,接下 来我们就按照 πpiπ 的指示走。虽然只有一步之差,但我们得到的奖励一定会比完全按照 πpiπ 得到的奖励要大。

接下来要证

Qπ(s,π′(s))⩽Vπ′(s)Q_pileft(s, pi^{prime}(s)right) leqslant V_{pi^{prime}}(s) Qπ(s,π(s))Vπ(s)

也就是,只有一步之差,我们会得到比较大的奖励。但假设每步都是不一样的,每步都按照 π′pi^{prime}π 而不是 πpiπ ,得到的奖励一定 会更大,即 Qπ(s,π′(s))Q_pileft(s, pi^{prime}(s)right)Qπ(s,π(s)) 是指我们在状态 sts_tst 采取动作 ata_tat ,得到奖励 rtr_trt ,进入状态 st+1s_{t+1}st+1 ,即

Qπ(s,π′(s))=E[rt+Vπ(st+1)∣st=s,at=π′(st)]Q_pileft(s, pi^{prime}(s)right)=mathbb{E}left[r_t+V_pileft(s_{t+1}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] Qπ(s,π(s))=E[rt+Vπ(st+1)st=s,at=π(st)]

在状态 sss 按照 π′pi^{prime}π 采取某一个动作 ata_tat ,得到奖励 rtr_trt ,进入状态 st+1,Vπ(st+1)s_{t+1} , V_pileft(s_{t+1}right)st+1Vπ(st+1) 是状态 st+1s_{t+1}st+1 根据策略 πpiπ 所估出来的值。因为在同样的状态采取同样的动 作,我们得到的奖励和会进入的状态不一定一样,所以需要取期望值。

因为 Vπ(s)⩽Qπ(s,π′(s))V_pi(s) leqslant Q_pileft(s, pi^{prime}(s)right)Vπ(s)Qπ(s,π(s)) ,也就是 Vπ(st+1)⩽Qπ(st+1,π′(st+1))V_pileft(s_{t+1}right) leqslant Q_pileft(s_{t+1}, pi^{prime}left(s_{t+1}right)right)Vπ(st+1)Qπ(st+1,π(st+1)) ,所以我们可得

E[rt+Vπ(st+1)∣st=s,at=π′(st)]⩽E[rt+Qπ(st+1,π′(st+1))∣st=s,at=π′(st)]begin{aligned} &mathbb{E}left[r_t+V_pileft(s_{t+1}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ &leqslant mathbb{E}left[r_t+Q_pileft(s_{t+1}, pi^{prime}left(s_{t+1}right)right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] end{aligned} E[rt+Vπ(st+1)st=s,at=π(st)]E[rt+Qπ(st+1,π(st+1))st=s,at=π(st)]

因为 Qπ(st+1,π′(st+1))=rt+1+Vπ(st+2)Q_pileft(s_{t+1}, pi^{prime}left(s_{t+1}right)right)=r_{t+1}+V_pileft(s_{t+2}right)Qπ(st+1,π(st+1))=rt+1+Vπ(st+2) ,所以我们可得

E[rt+Qπ(st+1,π′(st+1))∣st=s,at=π′(st)]=E[rt+rt+1+Vπ(st+2)∣st=s,at=π′(st)]begin{aligned} &mathbb{E}left[r_t+Q_pileft(s_{t+1}, pi^{prime}left(s_{t+1}right)right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ &=mathbb{E}left[r_t+r_{t+1}+V_pileft(s_{t+2}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] end{aligned} E[rt+Qπ(st+1,π(st+1))st=s,at=π(st)]=E[rt+rt+1+Vπ(st+2)st=s,at=π(st)]

我们再把上式代入 Vπ(s)⩽Qπ(s,π′(s))V_pi(s) leqslant Q_pileft(s, pi^{prime}(s)right)Vπ(s)Qπ(s,π(s)) ,一直算到回合结束,即

Vπ(s)≤Qπ(s,π′(s))=E[rt+Vπ(st+1)∣st=s,at=π′(st)]≤E[rt+Qπ(st+1,π′(st+1))∣st=s,at=π′(st)]=E[rt+rt+1+Vπ(st+2)∣st=s,at=π′(st)]≤E[rt+rt+1+Qπ(st+2,π′(st+2)∣st=s,at=π′(st)]=E[rt+rt+1+rt+2+Vπ(st+3)∣st=s,at=π′(st)]≤⋯≤E[rt+rt+1+rt+2+⋯∣st=s,at=π′(st)]=Vπ′(s)begin{aligned} V^pi(s) & leq Q^pileft(s, pi^{prime}(s)right) \ &=Eleft[r_t+V^pileft(s_{t+1}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ & leq Eleft[r_t+Q^pileft(s_{t+1}, pi^{prime}left(s_{t+1}right)right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ &=Eleft[r_t+r_{t+1}+V^pileft(s_{t+2}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ & leq Eleft[r_t+r_{t+1}+Q^pileft(s_{t+2}, pi^{prime}left(s_{t+2}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right]right.\ &=Eleft[r_t+r_{t+1}+r_{t+2}+V^pileft(s_{t+3}right) mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ & leq cdots \ & leq Eleft[r_t+r_{t+1}+r_{t+2}+cdots mid s_t=s, a_t=pi^{prime}left(s_tright)right] \ &=V^{pi^{prime}}(s) end{aligned} Vπ(s)Qπ(s,π(s))=E[rt+Vπ(st+1)st=s,at=π(st)]E[rt+Qπ(st+1,π(st+1))st=s,at=π(st)]=E[rt+rt+1+Vπ(st+2)st=s,at=π(st)]E[rt+rt+1+Qπ(st+2,π(st+2)st=s,at=π(st)]=E[rt+rt+1+rt+2+Vπ(st+3)st=s,at=π(st)]E[rt+rt+1+rt+2+st=s,at=π(st)]=Vπ(s)

因此

Vπ(s)⩽Vπ′(s)V_pi(s) leqslant V_{pi^{prime}}(s) Vπ(s)Vπ(s)

我们可以估计某一个策略的Q函数,接下来就可以找到另外一个策略 π′pi^{prime}π 比原来的策略 πpiπ 还要更好。


四、目标网络

接下来讲一些在深度 Qmathrm{Q}Q 网络里一定会用到的技巧。第一个技巧是目标网络(target network)。我们在学习 Qmathrm{Q}Q 函数的时候, 也会用到时序差分方法的概念。

我们现在收集到一个数据,比如在状态 sts_tst 采取动作 ata_tat 以后,得到奖励 rtr_trt ,进入状态 st+1s_{t+1}st+1。 根据Q函数,我们可知

Qπ(st,at)=rt+Qπ(st+1,π(st+1))Q_pileft(s_t, a_tright)=r_t+Q_pileft(s_{t+1}, pileft(s_{t+1}right)right) Qπ(st,at)=rt+Qπ(st+1,π(st+1))
所以我们在学习的时候, Qmathrm{Q}Q 函数输入 st、ats_t 、 a_tstat 得到的值,与输入 st+1、π(st+1)s_{t+1} 、 pileft(s_{t+1}right)st+1π(st+1) 得到的值之间,我们希望它们相差 rtr_trt ,这 与时序差分方法的概念是一样的。

但是实际上这样的输入并不好学习,假设这是一个回归问题,如下图 所示:

在这里插入图片描述

Qπ(st,at)Q_pileft(s_t, a_tright)Qπ(st,at) 是网络的输出, rt+Qπ(st+1,π(st+1))r_t+Q_pileft(s_{t+1}, pileft(s_{t+1}right)right)rt+Qπ(st+1,π(st+1)) 是目标,目标是会变动的。当然如果我们要实现这样的训练,其实 也没有问题,就是在做反向传播的时候, QπQ_piQπ 的参数会被更新,我们会把两个更新的结果加在一起 (因为它们是同一个模 型 QπQ_piQπ ,所以两个更新的结果会加在一起)。但这样会导致训练变得不太稳定,因为假设我们把 Qπ(st,at)Q_pileft(s_t, a_tright)Qπ(st,at) 当作模型的 输出,把 rt+Qπ(st+1,π(st+1))r_t+Q_pileft(s_{t+1}, pileft(s_{t+1}right)right)rt+Qπ(st+1,π(st+1)) 当作目标,我们要去拟合的目标是一直在变动的,这是不太好训练的。

所以我们会把其中一个 Qmathrm{Q}Q 网络,通常是把右边的 Qmathrm{Q}Q 网络固定住。在训练的时候,我们只更新左边的 Qmathrm{Q}Q 网络的参数, 而右边的 Qmathrm{Q}Q 网络的参数会被固定。因为右边的 Qmathrm{Q}Q 网络负责产生目标,所以被称为目标网络。因为目标网络是固定的,所以 现在得到的目标 rt+Qπ(st+1,π(st+1))r_t+Q_pileft(s_{t+1}, pileft(s_{t+1}right)right)rt+Qπ(st+1,π(st+1)) 的值也是固定的。我们只调整左边 Qmathrm{Q}Q 网络的参数,它就变成一个回归问题。我们希望模型输出的值与目标越接近越好,这样会最小化它的均方误差 (mean square error)。

在实现的时候,我们会把左边的 QQQ 网络更新多次,再用更新过的 QQQ 网络替换目标网络。但这两个网络不要一起更新,一起更新,结果会很容易不好。一开始这两个网络是一样的,在训练的时候,我们会把右边的 Qmathrm{Q}Q 网络固定住,在做梯度下降的 时候,只调整左边 QQQ 网络的参数。我们可能更新 100 次以后才把参数复制到右边的网络中,把右边网络的参数覆盖,目标值就变了。

就好像我们本来在做一个回归问题,训练后把这个回归问题的损失降下去以后,接下来我们把左边网络的参数 复制到右边网络,目标值就变了,接下来就要重新训练

如下图所示,我们可以通过猫追老鼠的例子来直观地理解固定目标网络的目的。猫是 Qmathrm{Q}Q 估计,老鼠是 Qmathrm{Q}Q 目标。一开 始,猫离老鼠很远,所以我们想让猫追上老鼠。如下图b 所示,因为 Q 目标也是与模型参数相关的,所以每次优化后, Qmathrm{Q}Q 目标也会动。这就导致一个问题,猫和老鼠都在动。如下图c 所示,猫和老鼠会在优化空间里面到处乱动,这会产生非 常奇怪的优化轨迹,使得训练过程十分不稳定。所以我们可以固定 QQQ 网络,让老鼠动得不那么频慗,可能让它每 5 步动一 次,猫则是每一步都在动。如果老鼠每 5 次动一步,猫就有足够的时间来接近老鼠,它们之间的距离会随着优化过程越来 越小,最后它们就可以拟合,拟合后就可以得到一个最好的 QQQ 网络。
在这里插入图片描述


五、探索

第二个技巧是探索。当我们使用 Qmathrm{Q}Q 函数的时候,策略完全取决于 Qmathrm{Q}Q 函数。给定某一个状态,我们就穷举所有的动作,采取 让Q值最大的动作,即
a=arg⁡max⁡aQ(s,a)a=underset{a}{arg max } Q(s, a) a=aargmaxQ(s,a)
使用 Qmathrm{Q}Q 函数来决定动作与使用策略梯度不一样,策略梯度的输出是随机的,它会输出一个动作的分布,我们根据这个动作 的分布去采样,所以在策略梯度里面,我们每次采取的动作是不一样的,是有随机性的。像 Qmathrm{Q}Q 函数中,如果我们采取的动 作总是固定的,会遇到的问题就是这不是一个好的收集数据的方式。

假设我们要估测某一个状态,可以采取动作 a1、a2a_1 、 a_2a1a2a3a_3a3 。我们要估测在某一个状态采取某一个动作会得到的 Qmathrm{Q}Q 值,一定要在那一个状态采取过那一个动作,才能估测出它的 值。如果没有在那个状态采取过那个动作,我们其实是估测不出它的值的。如果Q函数是一个网络,这个问题可能没有那 么严重。但是一般而言,假设 Qmathrm{Q}Q 函数是一个表格,对于没有见过的状态动作对,它是估不出值的。如果 Qmathrm{Q}Q 函数是网络,也 会有类似的问题,只是没有那么严重。所以假设我们在某一个状态,动作 a1、a2、a3a_1 、 a_2 、 a_3a1a2a3 都没有采取过,估出来的 Q(s,a1)Qleft(s, a_1right)Q(s,a1) Q(s,a2)、Q(s,a3)Qleft(s, a_2right) 、 Qleft(s, a_3right)Q(s,a2)Q(s,a3) 的值可能都是一样的,都是一个初始值,比如 0 ,即
Q(s,a1)=0Q(s,a2)=0Q(s,a3)=0begin{aligned} &Qleft(s, a_1right)=0 \ &Qleft(s, a_2right)=0 \ &Qleft(s, a_3right)=0 end{aligned} Q(s,a1)=0Q(s,a2)=0Q(s,a3)=0

但是如下图所示,假设我们在状态 sss 采取动作 a2a_2a2 ,它得到的值是正的奖励, Q(s,a2)Qleft(s, a_2right)Q(s,a2) 就会比其他动作的 Qmathrm{Q}Q 值要大。在 采取动作的时候,谁的 Qmathrm{Q}Q 值最大就采取谁,所以之后永远都只会采取 a2a_2a2 ,其他的动作就再也不会被采取了,这就会有问 题。

比如我们去一个餐厅吃饭。假设我们点了某一样菜,比如辣子鸡,我们觉得还可以。接下来我们每次去就都会点辣子鸡,再也不点别的菜了,那我们就不知道别的菜是不是会比辣子鸡好吃,这是一样的问题。

在这里插入图片描述

这个问题就是探索-利用窘境(exploration-exploitation dilemma) 问题
有两个方法可以解决这个问题: εvarepsilonε-贪心探索和玻尔兹曼探索 (Boltzmann exploration)。

5.1 εvarepsilonε-贪心探索

εvarepsilonε-贪心是指我们有 1−ε1-varepsilon1ε 的概率会按照 Qmathrm{Q}Q 函数来决定动作,可写为
a={arg⁡max⁡Q(s,a),有 1−ε的概率 a,否则 随机 a=left{begin{array}{cc} arg max Q(s, a) & , text { 有 } 1-varepsilon text { 的概率 } \ a, & text { 否则 } \ text { 随机 } & end{array}right. a=argmaxQ(s,a)a, 随机 ,  1ε 的概率  否则 
通常将 εvarepsilonε 设为一个很小的值, 1−ε1-varepsilon1ε 可能是 0.90.90.9 ,也就是 0.90.90.9 的概率会按照 Qmathrm{Q}Q 函数来决定动作,但是我们有 0.10.10.1 的概率是随 机的。通常在实现上 εvarepsilonε 会随看时间递减。在最开始的时候,因为不知道哪个动作是比较好的,所以我们会花比较大的力气 探索。接下来,随着训练的次数越来越多,我们已经比较确定哪个动作是比较好的。我们就会减少探索,会把 εvarepsilonε 的值变 小,主要根据Q函数来决定动作,比较少随机决定动作,这就是 εvarepsilonε-念心。

5.2 玻尔兹曼探索

在玻尔兹曼探索中,我们假设对于任意的 s、a,Q(s,a)⩾0s 、 a , Q(s, a) geqslant 0saQ(s,a)0 ,因此 aaa 被选中的概率与 eQ(s,a)/Te^{Q(s, a) / T}eQ(s,a)/T 呈正比,即

π(a∣s)=eQ(s,a)/T∑a′∈AeQ(s,a′)/Tpi(a mid s)=frac{mathrm{e}^{Q(s, a) / T}}{sum_{a^{prime} in A} mathrm{e}^{Qleft(s, a^{prime}right) / T}} π(as)=aAeQ(s,a)/TeQ(s,a)/T
其中, T>0T>0T>0 称为温度系数。如果 TTT 很大,所有动作几乎以等概率选择 (探索) ; 如果 TTT 很小,Q值大的动作更容易被 选中 (利用); 如果 TTT 趋于 0 ,我们就只选择最优动作类似模拟退火过程)。


六、经验回放

第三个技巧是经验回放 (experience replay)。如下图所示,经验回放会构建一个回放缓冲区 (replay buffer),回放缓冲区又被称为回放内存 (replay memory)

在这里插入图片描述

回放缓冲区是指现在有某一个策略 πpiπ 与环境交互,它会去收集数据,我们把所 有的数据放到一个数据缓冲区 (buffer) 里面,数据缓冲区里面存储了很多数据。比如数据缓冲区可以存储 5 万条数据,每 一笔数据就是记得说,我们之前在某一个状态 sts_tst ,采取某一个动作 ata_tat ,得到了奖励 rtr_trt ,进入状态 st+1s_{t+1}st+1 。我们用 πpiπ 去与环 境交互多次,把收集到的数据放到回放缓冲区里面。回放缓冲区里面的经验可能来自不同的策略,我们每次用 πpiπ 与环境交互的时候,可能只交互 10000 次,接下来我们就更新 πpiπ 了。但是回放缓区里面可以放 5 万笔数据,所以 5 万笔数据可能 来自不同的策略。回放缓冲区只有在它装满的时候,才会把旧的数据丟掉。所以回放缓冲区里面其实装了很多不同的策略的经验

如下图所示,有了回放缓冲区以后,我们怎么训练 Qmathrm{Q}Q 模型、怎么估 Qmathrm{Q}Q 函数呢? 我们会迭代地训练 Qmathrm{Q}Q 函数,在每次迭代 里面,从回放缓冲区中随机挑一个批量 (batch) 出来,即与一般的网络训练一样,从训练集里面挑一个批量出来。我们采样该批量出来,里面有一些经验,我们根据这些经验去更新Q函数。这与时序差分学习要有一个目标网络是一样的。我们采样一个批量的数据,得到一些经验,再去更新 QQQ 函数

在这里插入图片描述

如果某个算法使用了经验回放这个技巧,该算法就变成了一个异策略的算法

因为本来 Qmathrm{Q}Q 是要观察 πpiπ 的经验的,但实际上 存储在回放缓冲区里面的这些经验不是通通来自于 πpiπ ,有些是过去其他的策略所留下来的经验。因为我们不会用某一个 πpiπ 就把整个回放缓冲区装满,拿去测 QQQ 函数, πpiπ 只是采样一些数据放到回放缓冲区里面,接下来就让 QQQ 去训练。所以 QQQ 在采 样的时候,它会采样到过去的一些数据。

这么做有两个好处。

  • 第一个好处是,在进行强化学习的时候,往往最花时间的步骤是与环境交互,训练网络反而是比较快的。因为我们用 GPU 训练其实很快,真正花时间的往往是与环境交互。用回放缓冲区可以减少与环境交互的次数,因为在做训练的时候,经验不需要通通来自于某一个策略。一些过去的策略所得到的经验可以放在回放缓冲区里面被使用很多次,被反复的再利用,这样可以比较高效地采样经验
  • 第二个好处是,在训练网络的时候,其实我们希望一个批量里面的 数据越多样 (diverse) 越好。如果批量里面的数据都是同样性质的,我们训练下去,训练结果是容易不好的。如果批量里 面都是一样的数据,训练的时候,性能会比较差。我们希望批量里的数据越多样越好。如果回放缓冲区里面的经验通通来 自于不同的策略,我们采样到的一个批量里面的数据会是比较多样的

Q:我们观察 πpiπ 的值,发现里面混杂了一些不是 πpiπ 的经验,这有没有关系?
A: 没关系。这并不是因为过去的策略与现在的策略很像,就算过去的策略与现在的策略不是很像,也是没有关系的。主 要的原因是我们并不是去采样一个轨迹,我们只采样了一笔经验,所以与是不是异策略这件事是没有关系的。就算是异策 略,就算是这些经验不是来自于 πpiπ ,我们还是可以用这些经验来估测 Qπ(s,a)Q_pi(s, a)Qπ(s,a)


七、深度Q网络

在这里插入图片描述

上图所示为一般的深度 Qmathrm{Q}Q 网络算法。

深度 Qmathrm{Q}Q 网络算法是这样的,我们初始化两个网络 :估计网络 QQQ 和 目标网络 Q^,Q^hat{Q} , hat{Q}Q^Q^ 就等于 QQQ一开始 目标网络 Q^hat{Q}Q^ 与原来的 QQQ 网络是一样的

在每一个回合中,我们用演员与环境交互,在每一次交互的过程中,都会得到一个 状态 sts_tst ,会采取某一个动作 at。a_{t 。}at 怎么知道采取哪一个动作 ata_tat 呢? 我们就根据现在的 Q函数,但是要有探索的机制。比如 我们用玻尔兹曼探索或是 εvarepsilonε-贪心探索,接下来得到奖励 rtr_trt ,进入状态 st+1s_{t+1}st+1

所以现在收集到一笔数据 (st、at、rt、st+1)left(s_t 、 a_t 、 r_t 、 s_{t+1}right)(statrtst+1) ,我们将其放到回放缓冲区里面。如果回放缓冲区满了,我们就把一些旧的数据丢掉。

接下来我们就从回放缓冲区里面去采样数据,采样到的是 (si、ai、ri、si+1)left(s_i 、 a_i 、 r_i 、 s_{i+1}right)(siairisi+1) 。这笔数据与刚放进去的不一定是同一笔,我们可能抽到旧的。要注意的是, 我们采样出来不是一笔数据,采样出来的是一个批量的数据,采样一些经验出来。

接下来就是计算目标。假设我们采样出 一笔数据,根据这笔数据去计算目标。目标要用目标网络 Q^hat{Q}Q^ 来计算。目标是:
y=ri+max⁡aQ^(si+1,a)y=r_i+max _a hat{Q}left(s_{i+1}, aright) y=ri+amaxQ^(si+1,a)
其中, aaa 是让 Q^hat{Q}Q^ 值最大的动作。因为我们在状态 si+1s_{i+1}si+1 会采取的动作 aaa 就是可以让 Q^hat{Q}Q^ 值最大的那一个动作。接下来我们要 更新 Qmathrm{Q}Q 值,就把它当作一个回归问题。我们希望 Q(si,ai)Qleft(s_i, a_iright)Q(si,ai) 与目标越接近越好。

假设已经更新了一定的次数,比如 CCC 次, 设 C=100C=100C=100 ,那我们就把 Q^hat{Q}Q^ 设成 QQQ ,这就是深度Q网络算法。

Qmathrm{Q}Q :深度 Qmathrm{Q}Q 网络和 Qmathrm{Q}Q 学习有什么不同?
A: 整体来说,深度 QQQ 网络与 QQQ 学习的目标价值以及价值的更新方式都非常相似。主要的不同点在于:深度 QQQ 网络将 QQQ 学习与 深度学习结合,用深度网络来近似动作价值函数,而 QQQ 学习则是采用表格存储;深度 QQQ 网络采用了经验回放的训练方法, 从历史数据中随机采样,而 Qmathrm{Q}Q 学习直接采用下一个状态的数据进行学习。


八、关键词总结

  • 深度 Qmathrm{Q}Q 网络 (deep Q-network, DQN):基于深度学习的 Qmathrm{Q}Q 学习算法, 其结合了价值函数近似 (value function approximation) 与神经网络技术,并采用目标网络和经验回放等方法进行网络的训练。
  • 状态-价值函数 (state-value function): 其输人为演员某一时刻的状态, 输出为一个标量, 即当演员在 对应的状态时,预期的到过程结束时间段内所能获得的价值。
  • 状态-价值函数贝尔曼方程 (state-value function Bellman equation):基于状态-价值函数的贝尔曼方 程, 它表示在状态 sts_tst 下对累积奖励 GtG_tGt 的期望。
  • Qmathrm{Q}Q 函数 (Q-function) : 其也被称为动作价值函数 (action-value function)。其输人是一个状态-动作对, 即在某一具体的状态采取对应的动作, 假设我们都使用某个策略 πpiπ, 得到的累积奖励的期望值有多大。
  • 目标网络(target network):其可解决在基于时序差分的网络中, 优化目标 Qπ(st,at)=rt+Q_pileft(s_t, a_tright)=r_t+Qπ(st,at)=rt+ Qπ(st+1,π(st+1))Q_pileft(s_{t+1}, pileft(s_{t+1}right)right)Qπ(st+1,π(st+1)) 左右两侧会同时变化使得训练过程不稳定, 从而增大回归的难度的问题。目标网络选择 将右边部分, 即 rt+Qπ(st+1,π(st+1))r_t+Q_pileft(s_{t+1}, pileft(s_{t+1}right)right)rt+Qπ(st+1,π(st+1)) 固定, 通过改变左边部分, 即 Qπ(st,at)Q_pileft(s_t, a_tright)Qπ(st,at) 中的参数进行回归, 这也 是深度 Qmathrm{Q}Q 网络应用中比较重要的技巧。
  • 探索 (exploration):我们在使用 Qmathrm{Q}Q 函数的时候, 我们的策略完全取决于 Qmathrm{Q}Q 函数, 这有可能导致出现 对应的动作是固定的某几个数值的情况, 而不像策略梯度中的输出是随机的, 我们再从随机分布中采样选 择动作。这会导致我们继续训练的输人值一样, 从而 “加重” 输出的固定性, 导致整个模型的表达能力急 剧下降, 这就是探索-利用窘境 (exploration-exploitation dilemma) 问题。我们可以使用 εvarepsilonε-贪心和玻尔兹曼探索 (Boltzmann exploration) 等探索方法进行优化。
  • 经验回放 (experience replay):其会构建一个回放缓冲区 (replay buffer) 来保存许多经验, 每一个经 验的形式如下: 在某一个状态 sts_tst, 采取某一个动作 ata_tat, 得到奖励 rtr_trt, 然后进人状态 st+1s_{t+1}st+1 。我们使用 πpiπ 与 环境交互多次, 把收集到的经验都存储在回放缓冲区中。当我们的缓冲区 “装满” 后, 就会自动删去最早 进人缓冲区的经验。在训练时, 对于每一轮迭代都有相对应的批量 (batch) (与我们训练普通的网络一样, 都是通过采样得到的), 然后用这个批量中的经验去更新我们的 Qmathrm{Q}Q 函数。综上, Qmathrm{Q}Q 函数在采样和训练的时 候, 会用到过去的经验, 所以这里称这个方法为经验回放, 其也是深度 Qmathrm{Q}Q 网络应用中比较重要的技巧。

九、习题

6-1 为什么在深度 QQQ 网络中采用价值函数近似的表示方法?
6-2 评论员的输出通常与哪几个值直接相关?
6-3 我们通常怎么衡量状态价值函数 Vπ(s)V_pi(s)Vπ(s) ? 其优势和劣势分别有哪些?
6-4 基于本章正文介绍的基于蒙特卡洛的网络方法, 我们怎么训练模型呢? 或者我们应该将其看作机 器学习中什么类型的问题呢?
6-5 基于本章正文中介绍的基于时序差分的网络方法,具体地,我们应该怎么训练模型呢?
6-6 动作价值函数和状态价值函数的有什么区别和联系?
6-7 请介绍 QQQ 函数的两种表示方法。
6-8 当得到了 QQQ 函数后, 我们应当如何找到更好的策略 π′pi^{prime}π 呢? 或者说 π′pi^{prime}π 的本质是什么?
6-9 解决探索-利用窘境问题的探索的方法有哪些?
6-10 我们使用经验回放有什么好处?
6-11 在经验回放中我们观察 πpiπ 的价值, 发现里面混杂了一些不是 πpiπ 的经验, 这会有影响吗?


十、面试题

6-1 友善的面试官:请问深度 Qmathrm{Q}Q 网络是什么? 其两个关键性的技巧分别是什么?
6-2 友善的面试官:那我们继续分析! 你刚才提到的深度 QQQ 网络中的两个技巧
目标网络和经 验回放, 其具体作用是什么呢?
6-3 友善的面试官:深度 Qmathrm{Q}Q 网络和 Qmathrm{Q}Q 学习有什么异同点?
6-4 友善的面试官:请问, 随机性策略和确定性策略有什么区别吗?
6-5 友善的面试官:请问不打破数据相关性, 神经网络的训练效果为什么就不好?


十一、Python代码实战

【强化学习】深度Q网络(DQN)求解倒立摆问题 + Python代码实战

Published by

风君子

独自遨游何稽首 揭天掀地慰生平