update ch6

This commit is contained in:
qiwang067
2022-08-24 16:10:05 +08:00
parent 8f6da78253
commit ba917cafa0

View File

@@ -1,388 +1,346 @@
# DQN
传统的强化学习算法会使用表格的形式存储状态值函数 $V(s)$ 或状态动作值函数 $Q(s,a)$,但是这样的方法存在很大的局限性。例如现实中的强化学习任务所面临的状态空间往往是连续的,存在无穷多个状态,在这种情况下,就不能再使用表格对值函数进行存储。值函数近似利用函数直接拟合状态值函数或状态动作值函数,减少了对存储空间的要求,有效地解决了这个问题。
# 第6章 深度Q网络
传统的强化学习算法会使用表格的形式存储状态值函数 $V(s)$ 或动作值函数 $Q(s,a)$,但是这样的方法存在很大的局限性。例如现实中的强化学习任务所面临的状态空间往往是连续的,存在无穷多个状态,在这种情况下,就不能再使用表格对值函数进行存储。值函数近似利用函数直接拟合状态值函数或动作值函数,降低了对存储空间的要求,有效地解决了这个问题。
为了在连续的状态空间中计算值函数 $Q^{\pi}(s,a)$,我们可以用一个函数 $Q_{\phi}(\boldsymbol{s},\boldsymbol{a})$ 来表示近似计算,称为`价值函数近似(Value Function Approximation)`
为了在连续的状态和动作空间中计算值函数 $Q_{\pi}(s,a)$,我们可以用一个函数 $Q_{\phi}(\boldsymbol{s},\boldsymbol{a})$ 来表示近似计算,称为**价值函数近似value function approximation**
$$
Q_{\phi}(\boldsymbol{s}, \boldsymbol{a}) \approx Q^{\pi}(s, a)
Q_{\phi}(\boldsymbol{s}, \boldsymbol{a}) \approx Q_{\pi}(\boldsymbol{s}, \boldsymbol{a})
$$
其中,$\boldsymbol{s}$、$\boldsymbol{a}$ 分别是状态 $s$ 和动作 $a$ 的向量表示,函数 $Q_{\phi}(\boldsymbol{s}, \boldsymbol{a})$ 通常是一个参数为 $\phi$ 的函数,比如神经网络,其输出为一个实数,称为 **Q 网络Q-network**
深度Q网络deep Q-networkDQN是指基于深度学习的Q学习算法主要结合了价值函数近似与神经网络技术并采用目标网络和经历回放的方法进行网络的训练。在 Q学习 中,我们使用表格来存储每个状态 $s$ 下采取动作 $a$ 获得的奖励,即状态-动作值函数 $Q(s,a)$。然而这种方法在状态量巨大甚至是连续的任务中会遇到维度灾难问题往往是不可行的。因此深度Q网络 采用了价值函数近似的表示方法。
## 6.1 状态价值函数
深度Q网络 是基于价值的算法,在基于价值的算法里面,我们学习的不是策略,而是**评论员critic**。评论员的任务是评价现在的动作有多好或有多不好。假设有一个演员,其要学习一个策略来得到尽量高的回报。评论员就是评价演员的策略 $\pi$ 好还是不好,即策略评估。例如,有一种评论员称为**状态价值函数**$V_{\pi}$。状态价值函数是指,假设演员的策略是 $\pi$,用 $\pi$ 与环境交互,假设 $\pi$ 看到了某一个状态 $s$,例如在玩雅达利游戏,状态 $s$ 是某一个画面,$\pi$ 看到某一个画面,接下来一直到游戏结束,期望的累积奖励有多大。如图 6.1a 所示,$V_{\pi}$ 是一个函数,输入一个状态,它会输出一个标量。这个标量代表演员的策略$\pi$ 看到状态 $s$ 的时候,预期到游戏结束的时候,它可以获得多大的奖励。例如,假设我们在玩太空侵略者,图 6.1b 所示的状态 $s$,这个游戏画面,$V_{\pi}(s)$ 也许会很大,因为这时还有很多的怪兽可以击杀, 所以我们会得到很高的分数。一直到游戏结束的时候,我们仍然有很多的分数可以获得。图 6.1c 所示的情况我们得到的 $V_{\pi}(s)$ 可能就很小,因为剩下的怪兽也不多,并且红色的防护罩已经消失了,所以我们可能很快就会“死掉”。因此接下来得到预期的奖励,就不会太大。
<div align=center>
<img width="550" src="../img/ch6/6.1.png"/>
</div>
<div align=center>图 6.1 玩太空侵略者</div>
这里需要强调,评论员无法凭空评价一个状态的好坏,它所评价的是在给定某一个状态的时候,如果接下来交互的演员的策略是 $\pi$,我们会得到多少奖励,这个奖励就是我们评价得出的值。因为就算是同样的状态,接下来的 $\pi$ 不一样,得到的奖励也是不一样的。例如,在左边的情况下,假设是一个正常的 $\pi$,它可以击杀很多怪兽;假设它是一个很弱的 $\pi$,它就站在原地不动,马上就被射死了,我们得到的 $V_\pi(s)$ 还是很小。所以评论员的输出值取决于状态和演员。评论员其实都要绑定一个演员,它是在衡量某一个演员的好坏,而不是衡量一个状态的好坏。这里要强调一下,评论员的输出是与演员有关的,状态的价值其实取决于演员,当演员改变的时候,状态价值函数的输出其实也是会跟着改变的。
怎么衡量状态价值函数 $V_{\pi}(s)$ 呢?有两种不同的方法:基于蒙特卡洛的方法和基于时序差分的方法。基于蒙特卡洛的方法就是让演员与环境交互,我们要看演员好不好,就让演员与环境交互,让评论员评价。评论员就统计,演员如果看到状态 $s_a$,接下来的累积奖励有多大;如果它看到状态 $s_b$,接下来的累积奖励有多大。但是实际上,我们不可能看到所有的状态。如果我们在玩雅达利游戏,状态是图像,那么无法看到所有的状态。所以实际上 $V_{\pi}(s)$ 是一个网络。对一个网络来说,就算输入状态是从来都没有看过的,它也可以想办法估测一个值。怎么训练这个网络呢?如图 6.2 所示,如果在状态 $s_a$,接下来的累积奖励就是 $G_a$。也就是对这个价值函数,如果输入是状态 $s_a$,正确的输出应该是 $G_a$;如果输入状态是 $s_b$,正确的输出应该是 $G_b$。所以在训练的时候, 它就是一个回归问题regression problem。网络的输出就是一个值我们希望在输入 $s_a$ 的时候,输出的值与 $G_a$ 越接近越好;输入 $s_b$ 的时候,输出的值与 $G_b$ 越接近越好。接下来继续训练网络,这是基于蒙特卡洛的方法。
<div align=center>
<img width="550" src="../img/ch6/6.2.png"/>
</div>
<div align=center>图 6.2 基于蒙特卡洛的方法</div>
第二个方法是**时序差分**的方法,即基于时序差分的方法。在基于蒙特卡洛的方法中,每次我们都要计算累积奖励,也就是从某一个状态 $s_a$ 一直到游戏结束的时候,得到的所有奖励的总和。如果我们要使用基于蒙特卡洛的方法,我们必须至少玩到游戏结束。但有些游戏时间非常长,我们要玩到游戏结束才能够更新网络,这花的时间太多了,因此我们会采用基于时序差分的方法。基于时序差分的方法不需要玩到游戏结束,只需要在游戏的某一个状态 $s_t$ 的时候,采取动作 $a_t$ 得到奖励$r_t$ ,接下来进入状态 $s_{t+1}$,就可以使用时序差分的方法。我们可以通过式(6.1)来使用时序差分的方法。
$$
V_{\pi}\left(s_{t}\right)=V_{\pi}\left(s_{t+1}\right)+r_{t} \tag{6.1}
$$
其中
* $\boldsymbol{s},\boldsymbol{a}$ 分别是状态 $s$ 和动作 $a$ 的向量表示,
* 函数 $Q_{\phi}(\boldsymbol{s}, \boldsymbol{a})$ 通常是一个参数为 $\phi$ 的函数,比如`神经网络`,输出为一个实数,称为`Q 网络(Q-network)`
假设我们现在用的是某一个策略$\pi$,在状态 $s_t$时,它会采取动作 $a_t$,得到奖励 $r_t$ ,接下来进入 $s_{t+1}$ 。状态 $s_{t+1}$ 的值与状态 $s_t$ 的值,它们的中间差了一项 $r_t$,这是因为我们把 $s_{t+1}$ 的值加上得到的奖励 $r_t$ 就可以 得到$s_t$ 的值。有了式(6.1),在训练的时候,我们并不是直接估测 $V_{\pi}$,而是希望得到的结果 $V_{\pi}$ 可以满足式(6.1)。我们是这样训练的,如图 6.3 所示,我们把 $s_t$ 输入网络,因为把 $s_t$ 输入网络会得到 $V_{\pi}(s_t)$,把 $s_{t+1}$ 输入网络会得到 $V_{\pi}(s_{t+1})$$V_{\pi}(s_t)$ 减 $V_{\pi}(s_{t+1})$ 的值应该是 $r_t$。我们希望它们相减的损失与 $r_t$ 接近,训练下去,更新 $V_{\pi}$ 的参数,我们就可以把 $V_{\pi}$ 函数学习出来。
深度Q网络Deep Q-NetworkDQN算法的核心是维护 Q 函数并使用其进行决策。$Q^{\pi}(s,a)$ 为在该策略 $\pi$ 下的动作价值函数,每次到达一个状态 $s_t$ 之后,遍历整个动作空间,使用让 $Q^{\pi}(s,a)$ 最大的动作作为策略:
<div align=center>
<img width="550" src="../img/ch6/6.3.png"/>
</div>
<div align=center>图 6.3 基于时序差分的方法</div>
蒙特卡洛方法与时序差分方法有什么差别呢?如图 6.4 所示,蒙特卡洛方法最大的问题就是方差很大。因为我们在玩游戏的时候,游戏本身是有随机性的,所以我们可以把 $G_a$ 看成一个随机变量。因为我们每次到 $s_a$ 的时候,最后得到的 $G_a$ 其实是不一样的。我们看到同样的状态 $s_a$,最后到游戏结束的时候,因为游戏本身是有随机性的,玩游戏的模型可能也有随机性,所以我们每次得到的 $G_a$ 是不一样的,每一次得到的 $G_a$ 的差别其实会很大。为什么会很大呢?因为 $G_a$ 是很多个不同的步骤的奖励的和。假设我们每一个步骤都会得到一个奖励,$G_a$ 是从状态 $s_a$ 开始一直到游戏结束,每一个步骤的奖励的和。
<div align=center>
<img width="550" src="../img/ch6/6.4.png"/>
</div>
<div align=center>图 6.4 蒙特卡洛方法的问题</div>
通过式(6.2),我们知道 $G_a$ 的方差相较于某一个状态的奖励,它是比较大的。
$$
a_{t}=\underset{a}{\arg \max } ~Q^{\pi}\left(s_{t}, a\right)
\operatorname{Var}[k X]=k^{2} \operatorname{Var}[X] \tag{6.2}
$$
DQN采用贝尔曼方程来迭代更新 $Q^{\pi}(s,a)$
其中Var 是指方差variance
如果用时序差分的方法,我们要去最小化
$$
Q^{\pi}\left(s_{t}, a_{t}\right) \leftarrow Q^{\pi}\left(s_{t}, a_{t}\right)+\alpha\left(r_{t}+\gamma \max _{a} Q^{\pi}\left(s_{t+1}, a\right)-Q^{\pi}\left(s_{t}, a_{t}\right)\right)
$$
通常在简单任务上使用全连接神经网络fully connected neural network来拟合 $Q^{\pi}$但是在较为复杂的任务上如玩雅达利游戏会使用卷积神经网络来拟合从图像到价值函数的映射。由于DQN的这种表达形式只能处理有限个动作值因此其通常用于处理离散动作空间的任务。
## State Value Function
**Q-learning 是 `value-based` 的方法。在 value-based 的方法里面,我们学习的不是策略,我们要学习的是一个 `critic(评论家)`。**评论家要做的事情是评价现在的行为有多好或是有多不好。假设有一个演员(actor) $\pi$ ,评论家就是来评价这个演员的策略 $\pi$ 好还是不好,即 `Policy Evaluation(策略评估)`
> 注:「李宏毅深度强化学习」课程提到的 Q-learning其实是 DQN。
>
> DQN 是指基于深度学习的 Q-learning 算法,主要结合了`价值函数近似(Value Function Approximation)`与神经网络技术,并采用了目标网络和经历回放的方法进行网络的训练。
>
> 在 Q-learning 中,我们使用表格来存储每个状态 s 下采取动作 a 获得的奖励,即状态-动作值函数 $Q(s,a)$。然而这种方法在状态量巨大甚至是连续的任务中会遇到维度灾难问题往往是不可行的。因此DQN 采用了价值函数近似的表示方法。
举例来说,有一种评论家叫做 `state value function(状态价值函数)`。状态价值函数的意思就是说,假设演员叫做 $\pi$,拿 $\pi$ 跟环境去做互动。假设 $\pi$ 看到了某一个状态 s如果在玩 Atari 游戏的话,状态 s 是某一个画面,看到某一个画面的时候,接下来一直玩到游戏结束,期望的累积奖励有多大。所以 $V^{\pi}$ 是一个函数,这个函数输入一个状态,然后它会输出一个标量( scalar)。这个标量代表说,$\pi$ 这个演员看到状态 s 的时候,接下来预期到游戏结束的时候,它可以得到多大的值。
![](img/6.1.png ':size=550')
举个例子,假设你是玩 space invader 的话,
* 左边这个状态 s这个游戏画面$V^{\pi}(s)$ 也许会很大,因为还有很多的怪可以杀, 所以你会得到很大的分数。一直到游戏结束的时候,你仍然有很多的分数可以吃。
* 右边这种情况得到的 $V^{\pi}(s)$ 可能就很小,因为剩下的怪也不多了,并且红色的防护罩已经消失了,所以可能很快就会死掉。所以接下来得到预期的奖励,就不会太大。
这边需要强调的一个点是说,评论家都是绑一个演员的,评论家没有办法去凭空去评价一个状态的好坏,它所评价的东西是在给定某一个状态的时候, 假设接下来互动的演员是 $\pi$,那我会得到多少奖励。因为就算是给同样的状态,你接下来的 $\pi$ 不一样,你得到的奖励也是不一样的。
举例来说,在左边的情况,假设是一个正常的 $\pi$,它可以杀很多怪,那假设它是一个很弱的 $\pi$,它就站在原地不动,然后马上就被射死了,那你得到的 $V^\pi(s)$ 还是很小。所以评论家的输出值取决于状态和演员。所以评论家其实都要绑一个演员,它是在衡量某一个演员的好坏,而不是衡量一个状态的好坏。这边要强调一下,评论家的输出是跟演员有关的,状态的价值其实取决于你的演员,当演员变的时候,状态价值函数的输出其实也是会跟着改变的。
### State Value Function Estimation
**怎么衡量这个状态价值函数 $V^{\pi}(s)$ 呢?**有两种不同的做法MC-based 的方法和 TD-based 的方法。
` Monte-Carlo(MC)-based`的方法就是让演员去跟环境做互动,要看演员好不好,我们就让演员去跟环境做互动,给评论家看。然后,评论家就统计说,
* 演员如果看到状态 $s_a$,接下来的累积奖励会有多大。
* 如果它看到状态 $s_b$,接下来的累积奖励会有多大。
但是实际上,我们不可能把所有的状态通通都扫过。如果是玩 Atari 游戏的话,状态是图像,你没有办法把所有的状态通通扫过。所以实际上 $V^{\pi}(s)$ 是一个网络。对一个网络来说,就算输入状态是从来都没有看过的,它也可以想办法估测一个值。
![](img/6.2.png ':size=350')
怎么训练这个网络呢?因为如果在状态 $s_a$,接下来的累积奖励就是 $G_a$。也就是说,对这个价值函数来说,如果输入是状态 $s_a$,正确的输出应该是 $G_a$。如果输入状态 $s_b$,正确的输出应该是值 $G_b$。**所以在训练的时候, 它就是一个 `回归问题(regression problem)`。**网络的输出就是一个值,你希望在输入 $s_a$ 的时候,输出的值跟 $G_a$ 越近越好,输入 $s_b$ 的时候,输出的值跟 $G_b$ 越近越好。接下来把网络训练下去,就结束了。这是 MC-based 的方法。
![](img/6.3.png ':size=550')
**第二个方法是`Temporal-difference(时序差分)` 的方法, `即 TD-based ` 的方法。**
在 MC-based 的方法中,每次我们都要算累积奖励,也就是从某一个状态 $s_a$ 一直玩到游戏结束的时候,得到的所有奖励的总和。所以你要使用 MC-based 的方法,你必须至少把这个游戏玩到结束。但有些游戏非常长,你要玩到游戏结束才能够更新网络,花的时间太长了,因此我们会采用 TD-based 的方法。
TD-based 的方法不需要把游戏玩到底,只要在游戏的某一个情况,某一个状态 $s_t$ 的时候,采取动作 $a_t$ 得到奖励$r_t$ ,跳到状态 $s_{t+1}$,就可以使用 TD 的方法。
怎么使用 TD 的方法呢?这边是基于以下这个式子:
$$
V^{\pi}\left(s_{t}\right)=V^{\pi}\left(s_{t+1}\right)+r_{t}
V_{\pi}\left(s_{t}\right) \longleftrightarrow r+V_{\pi}\left(s_{t+1}\right) \tag{6.3}
$$
假设我们现在用的是某一个策略 $\pi$,在状态 $s_t$,它会采取动作 $a_t$,给我们奖励 $r_t$ ,接下来进入 $s_{t+1}$ 。状态 $s_{t+1}$ 的值跟状态 $s_t$ 的值,它们的中间差了一项 $r_t$。因为你把 $s_{t+1}$ 得到的值加上得到的奖励 $r_t$ 就会等于 $s_t$ 得到的值。有了这个式子以后,你在训练的时候,你并不是直接去估测 V而是希望你得到的结果 V 可以满足这个式子
其中,$r$具有随机性。因为即使我们在 $s_t$ 采取同一个动作,得到的奖励也不一定是一样的,所以 $r$ 是一个随机变量。但 $r$ 的方差比 $G_a$ 要小,因为 $G_a$ 是很多 $r$ 的加和,时序差分只是某一个 $r$ 而已。$G_a$ 的方差会比较大,$r$ 的方差会比较小。但是这里我们会遇到的一个问题是 $V_{\pi}$ 的估计不一定准确。假设 $V_{\pi}$ 的估计不准确,我们使用式(6.3)学习出来的结果也会是不准确的。所以蒙特卡洛方法与时序差分方法各有优劣。其实时序差分方法是比较常用的,蒙特卡洛方法其实是比较少用的
也就是说我们会是这样训练的,我们把 $s_t$ 丢到网络里面,因为 $s_t$ 丢到网络里面会得到 $V^{\pi}(s_t)$,把 $s_{t+1}$ 丢到你的值网络里面会得到 $V^{\pi}(s_{t+1})$,这个式子告诉我们,$V^{\pi}(s_t)$ 减 $V^{\pi}(s_{t+1})$ 的值应该是 $r_t$。然后希望它们两个相减的 loss 跟 $r_t$ 越接近,训练下去,更新 V 的参数,你就可以把 V 函数学习出来
图 6.5 所示为时序差分方法与蒙特卡洛方法的差别。假设有某一个评论员,它去观察某一个策略 $\pi$ 与环境交互 8 个回合的结果。有一个策略 $\pi$ 与环境交互了8 次,得到了 8 次玩游戏的结果。接下来这个评论员去估测状态的值
![](img/6.4.png ':size=500')
**MC 跟 TD 有什么样的差别呢?**
**MC 最大的问题就是方差很大。**因为我们在玩游戏的时候,它本身是有随机性的。所以你可以把 $G_a$ 看成一个随机变量。因为你每次同样走到 $s_a$ 的时候,最后你得到的 $G_a$ 其实是不一样的。你看到同样的状态 $s_a$,最后玩到游戏结束的时候,因为游戏本身是有随机性的,玩游戏的模型搞不好也有随机性,所以你每次得到的 $G_a$ 是不一样的,每一次得到 $G_a$ 的差别其实会很大。为什么它会很大呢?因为 $G_a$ 其实是很多个不同的步骤的奖励的和。假设你每一个步骤都会得到一个奖励,$G_a$ 是从状态 $s_a$ 开始,一直玩到游戏结束,每一个步骤的奖励的和。
我们先计算 $s_b$ 的值。 状态 $s_b$ 在 8 场游戏里都存在,其中有 6 场得到奖励 1有 2 场得到奖励 0。所以如果我们要计算期望值只算智能体看到状态 $s_b$ 以后得到的奖励。智能体一直玩到游戏结束的时候得到的累积奖励期望值是 3/4计算过程为
$$
\operatorname{Var}[k X]=k^{2} \operatorname{Var}[X]
$$
> Var 是指 variance。
为了方便说明问题,我们简化一下,假设从状态 $s_a$ 开始,一直玩到游戏结束,各个步骤的奖励相同,均为 $r_a$ $G_a=kr_a$。根据上式,则可得
$$
\operatorname{Var}[G_a]=\operatorname{Var}[kr_a]=k^{2} \operatorname{Var}[r_a]
\frac{6 \times 1 + 2 \times 0}{8}=\frac{6}{8}=\frac{3}{4}
$$
因此 $G_a$ 的方差相较于某一个状态的奖励是比较大的。
$s_a$ 期望的奖励到底应该是多少呢这里其实有两个可能的答案0 和 3/4。为什么有两个可能的答案呢这取决于我们用蒙特卡洛方法还是时序差分方法。用 蒙特卡洛方法与用 时序差分方法 算出来的结果是不一样的。
如果用 TD 的话,你是要去最小化这样的一个式子:
![](img/6.5.png ':size=550')
在这中间会有随机性的是 r。因为计算你在 $s_t$ 采取同一个动作,你得到的奖励也不一定是一样的,所以 r 是一个随机变量。但这个随机变量的方差会比 $G_a$ 还要小,因为 $G_a$ 是很多 r 合起来,这边只是某一个 r 而已。$G_a$ 的方差会比较大r 的方差会比较小。但是这边你会遇到的**一个问题是你这个 V 不一定估得准**。假设你的这个 V 估得是不准的,那你使用这个式子学习出来的结果,其实也会是不准的。所以 MC 跟 TD 各有优劣。**今天其实 TD 的方法是比较常见的MC 的方法其实是比较少用的。**
![](img/6.6.png ':size=550')
**上图是讲 TD 跟 MC 的差异。**假设有某一个评论家,它去观察某一个策略 $\pi$ 跟环境互动的 8 个 episode 的结果。有一个演员 $\pi$ 跟环境互动了8 次得到了8 次玩游戏的结果。接下来这个评论家去估测状态的值。
**我们先计算 $s_b$ 的值。** 状态 $s_b$ 在 8 场游戏里面都有经历过,其中有 6 场得到奖励 1有 2 场得到奖励 0。所以如果你是要算期望值的话就算看到状态 $s_b$ 以后得到的奖励,一直到游戏结束的时候得到的累积奖励期望值是 3/4计算过程如下式所示
假如我们用蒙特卡洛方法,$s_a$ 就出现一次,看到状态 $s_a$ ,接下来累积奖励就是 0所以 $s_a$ 期望奖励就是 0。但时序差分方法在计算的时候需要更新
$$
\frac{6 \times 1 + 2 \times 0}{8}=\frac{6}{8}=\frac{3}{4}
V_{\pi}\left(s_{a}\right)=V_{\pi}\left(s_{b}\right)+r
$$
**但 $s_a$ 期望的奖励到底应该是多少呢?**这边其实有两个可能的答案:一个是 0一个是 3/4。为什么有两个可能的答案呢这取决于你用 MC 还是TD。用 MC 跟用 TD 算出来的结果是不一样的
因为我们在状态 $s_a$ 得到奖励 $r=0$ 以后,进入状态 $s_b$,所以状态 $s_a$ 的奖励等于状态 $s_b$ 的奖励加上从状态 $s_a$ 进入状态 $s_b$ 的时候可能得到的奖励 $r$。而得到的奖励 $r$ 的值是 0$s_b$ 期望奖励是 3/4那么 $s_a$ 的奖励应该是 3/4
假如用 MC 的话,你会发现这个 $s_a$ 就出现一次,看到 $s_a$ 这个状态,接下来累积奖励就是 0所以 $s_a$ 期望奖励就是 0
用蒙特卡洛方法与时序差分方法估出来的结果很有可能是不一样的。就算评论员观察到一样的训练数据,它最后估出来的结果也不一定是一样的。为什么会这样呢?哪一个结果比较对呢?其实都对。因为在第一个轨迹中, $s_a$ 得到奖励 0 以后,再进入 $s_b$ 也得到奖励 0。这里有两个可能
但 TD 在计算的时候,它要更新下面这个式子:
1$s_a$ 是一个标志性的状态,只要看到 $s_a$ 以后,$s_b$ 就不会获得奖励,$s_a$ 可能影响了 $s_b$。如果是使用蒙特卡洛方法,它会把 $s_a$ 影响 $s_b$ 这件事考虑进去。所以看到 $s_a$ 以后,接下来 $s_b$ 就得不到奖励,$s_b$ 期望的奖励是 0。
2看到 $s_a$ 以后,$s_b$ 的奖励是 0 这件事只是巧合,并不是 $s_a$ 造成的,而是因为 $s_b$ 有时候就是会得到奖励 0这只是单纯“运气”的问题。其实平常 $s_b$ 会得到的奖励期望值是 3/4与 $s_a$ 是完全没有关系的。所以假设 $s_a$ 之后会进入 $s_b$,得到的奖励按照时序差分方法来算应该是 3/4。
不同的方法考虑了不同的假设,所以运算结果不同。
<div align=center>
<img width="550" src="../img/ch6/6.6.png"/>
</div>
<div align=center>图 6.5 时序差分方法与蒙特卡洛方法的差别</div>
## 6.2 动作价值函数
还有另外一种评论员称为**Q函数**它又被称为动作价值函数。状态价值函数的输入是一个状态它根据状态计算出这个状态以后的期望的累积奖励expected accumulated reward是多少。动作价值函数的输入是一个状态-动作对,其指在某一个状态采取某一个动作,假设我们都使用策略 $\pi$ ,得到的累积奖励的期望值有多大。
Q函数有一个需要注意的问题是策略 $\pi$在看到状态 $s$ 的时候,它采取的动作不一定是 $a$。Q函数假设在状态 $s$ 强制采取动作 $a$,而不管我们现在考虑的策略 $\pi$会不会采取动作 $a$,这并不重要。在状态 $s$ 强制采取动作 $a$。接下来都用策略 $\pi$ 继续玩下去,就只有在状态 $s$,我们才强制一定要采取动作 $a$,接下来就进入自动模式,让策略 $\pi$ 继续玩下去,得到的期望奖励才是 $Q_{\pi}(s,a)$ 。
Q函数有两种写法
1如图 6.7a 所示输入是状态与动作输出就是一个标量。这种Q函数既适用于连续动作动作是无法穷举的又适用于离散动作。
2如图 6.7b 所示输入是一个状态输出就是多个值。这种Q函数只适用于离散动作。假设动作是离散的比如动作就只有 3 个可能往左、往右或是开火。Q函数输出的 3 个值就分别代表 $a$ 是往左的时候的 Q 值,$a$ 是往右的时候的 Q 值,还有 $a$ 是开火的时候的 Q 值。
<div align=center>
<img width="550" src="../img/ch6/6.7.png"/>
</div>
<div align=center>图 6.6 Q函数</div>
如果我们去估计Q函数看到的结果可能如图 6.7 所示。假设我们有 3 个动作:原地不动、向上、向下。假设在第一个状态,不管采取哪个动作,最后到游戏结束的时候,得到的期望奖励都差不多。因为乒乓球在这个地方时,就算我们向下,接下来我们应该还可以接到乒乓球,所以不管采取哪个动作,都相差不了太多。假设在第二个状态,乒乓球已经反弹到很接近边缘的地方,这个时候我们采取向上的动作,才能接到乒乓球,才能得到正的奖励。如果我们站在原地不动或向下,接下来都会错过这个乒乓球,得到的奖励就会是负的。假设在第三个状态,乒乓球离我们的球拍很近了,所以就要采取向上的动作。假设在第四个状态,乒乓球被反弹回去,这时候采取哪个动作都差不多。这是动作价值函数的例子。
<div align=center>
<img width="550" src="../img/ch6/6.8.png"/>
</div>
<div align=center>图 6.7 乒乓球例子</div>
虽然我们学习的Q函数只能用来评估某一个策略 $\pi$ 的好坏,但只要有了 Q函数我们就可以进行强化学习就可以决定要采取哪一个动作就可以进行策略改进。如图 6.8 所示,假设我们有一个初始的演员,也许一开始很差,随机的也没有关系。初始的演员称为 $\pi$$\pi$ 与环境交互,会收集数据。接下来我们学习策略 $\pi$的 Q 值,去衡量一下 $\pi$ 在某一个状态强制采取某一个动作接下来会得到的期望奖励用时序差分方法或蒙特卡洛方法都是可以的。我们学习出一个Q函数以后就可以找到一个新的策略 $\pi'$ ,策略$\pi'$ 会比原来的策略 $\pi$ 要好稍后会定义什么是好。所以假设我们有一个Q函数和某一个策略 $\pi$,根据策略 $\pi$ 学习出策略 $\pi$ 的Q函数接下来可以找到一个新的策略 $\pi'$,它会比 $\pi$ 要好。我们用 $\pi'$ 取代 $\pi$,再去学习它的 Q 函数得到新的Q函数以后再去寻找一个更好的策略。这样一直循环下去策略就会越来越好。
首先要定义的是什么是好。$\pi'$ 一定会比 $\pi$ 要好,什么是好呢?这里的好是指,对所有可能的状态 $s$ 而言,$V_{\pi^{\prime}}(s) \geqslant V_{\pi}(s)$。也就是我们到同一个状态 $s$ 的时候,如果用 $\pi$ 继续与环境交互,我们得到的奖励一定会小于等于用 $\pi'$ 与环境交互得到的奖励。所以不管在哪一个状态,我们用 $\pi'$ 与环境交互,得到的期望奖励一定会比较大。所以 $\pi'$ 是比 $\pi$ 要好的策略。
有了Q函数以后我们把根据式(6.4)决定动作的策略称为 $\pi'$
$$
V^{\pi}\left(s_{a}\right)=V^{\pi}\left(s_{b}\right)+r
\pi^{\prime}(s)=\underset{a}{\arg \max} Q_{\pi}(s, a) \tag{6.4}
$$
$\pi'$ 一定比 $\pi$ 好。假设我们已经学习出 $\pi$ 的Q函数在某一个状态 $s$,把所有可能的动作 $a$ 一一代入 Q 函数,看看哪一个 $a$ 可以让Q函数的值最大这个动作就是 $\pi'$ 会采取的动作。
<div align=center>
<img width="550" src="../img/ch6/6.9.png"/>
</div>
<div align=center>图 6.8 使用Q函数进行策略改进</div>
这里要注意,给定状态 $s$ 和策略 $\pi$ 并不一定会采取动作 $a$。给定某一个状态 $s$ 强制采取动作 $a$,用 $\pi$ 继续交互得到的期望奖励这才是Q函数的定义。所以在状态 $s$ 下不一定会采取动作 $a$。用 $\pi'$ 在状态 $s$ 采取动作 $a$ 与用 $\pi$ 采取的动作不一定是一样的,$\pi'$ 所采取的动作会让它得到比较大的奖励。所以 $\pi'$ 是用Q函数推出来的没有另外一个网络决定 $\pi'$ 怎么与环境交互有Q函数 就可以找出 $\pi'$。但是在这里要解决一个 arg max 操作的问题,如果 $a$ 是离散的,如$a$ 只有 3 个选项将每个动作都代入Q函数看哪个动作的 Q 值最大,这没有问题。但如果 $a$ 是连续的,我们要解决 arg max 操作问题,就不可行。
接下来讲一下为什么用 $Q_{\pi}(s,a)$ 决定的 $\pi'$ 一定会比 $\pi$ 好。假设有一个策略 $\pi'$,它是由 $Q_{\pi}$ 决定的。我们要证明对所有的状态 $s$ ,有$V_{\pi^{\prime}}(s) \geqslant V_{\pi}(s)$。
怎么证明呢?$V_{\pi}(s)$ 可写为
$$
V_{\pi}(s)=Q_{\pi}(s, \pi(s))
$$
因为我们在状态 $s_a$ 得到奖励 r=0 以后,跳到状态 $s_b$。所以状态 $s_b$ 的奖励会等于状态 $s_b$ 的奖励加上在状态 $s_a$ 跳到状态 $s_b$ 的时候可能得到的奖励 r。而这个得到的奖励 r 的值是 0$s_b$ 期望奖励是 3/4那 $s_a$ 的奖励应该是 3/4
假设在状态 $s$ 下按照策略 $\pi$,会采取的动作就是 $\pi(s)$,我们算出来的 $Q_{\pi}(s, \pi(s))$ 会等于 $V_{\pi}(s)$。一般而言,$Q_{\pi}(s, \pi(s))$ 不一定等于 $V_{\pi}(s)$ ,因为动作不一定是 $\pi(s)$。但如果这个动作是 $\pi(s)$ $Q_{\pi}(s, \pi(s))$ 是等于 $V_{\pi}(s)$ 的
用 MC 跟 TD 估出来的结果很有可能是不一样的。就算评论家观察到一样的训练数据,它最后估出来的结果也不一定是一样的。为什么会这样呢?你可能问说,哪一个结果比较对呢?其实就都对。
因为在第一个轨迹, $s_a$ 得到奖励 0 以后,再跳到 $s_b$ 也得到奖励 0。这边有两个可能。
* 一个可能是: $s_a$ 是一个标志性的状态,只要看到 $s_a$ 以后,$s_b$ 就会拿不到奖励,$s_a$ 可能影响了 $s_b$。如果是用 MC 的算法的话,它会把 $s_a$ 影响 $s_b$ 这件事考虑进去。所以看到 $s_a$ 以后,接下来 $s_b$ 就得不到奖励,$s_b$ 期望的奖励是 0。
* 另一个可能是:看到 $s_a$ 以后,$s_b$ 的奖励是 0 这件事只是一个巧合,并不是 $s_a$ 所造成,而是因为说 $s_b$ 有时候就是会得到奖励 0这只是单纯运气的问题。其实平常 $s_b$ 会得到奖励期望值是 3/4跟 $s_a$ 是完全没有关系的。所以假设 $s_a$ 之后会跳到 $s_b$,那其实得到的奖励按照 TD 来算应该是 3/4。
**所以不同的方法考虑了不同的假设,运算结果不同。**
## State-action Value Function(Q-function)
还有另外一种评论家叫做 `Q-function`。它又叫做`state-action value function(状态-动作价值函数)`
* 状态价值函数的输入是一个状态,它是根据状态去计算出,看到这个状态以后的期望的累积奖励( expected accumulated reward)是多少。
* 状态-动作价值函数的输入是一个状态、动作对,它的意思是说,在某一个状态采取某一个动作,假设我们都使用演员 $\pi$ ,得到的累积奖励的期望值有多大。
Q-function 有一个需要注意的问题是,这个演员 $\pi$,在看到状态 s 的时候,它采取的动作不一定是 a。Q-function 假设在状态 s 强制采取动作 a。不管你现在考虑的这个演员 $\pi$ 它会不会采取动作 a这不重要。在状态 s 强制采取动作 a。接下来都用演员 $\pi$ 继续玩下去,就只有在状态 s我们才强制一定要采取动作 a接下来就进入自动模式让演员 $\pi$ 继续玩下去,得到的期望奖励才是 $Q^{\pi}(s,a)$ 。
![](img/6.7.png ':size=550')
Q-function 有两种写法:
* 输入是状态跟动作,输出就是一个标量;
* 输入是一个状态,输出就是好几个值。
假设动作是离散的,动作就只有 3 个可能:往左往右或是开火。那这个 Q-function 输出的 3 个值就分别代表 a 是向左的时候的 Q 值a 是向右的时候的 Q 值,还有 a 是开火的时候的 Q 值。
要注意的事情是,上图右边的函数只有离散动作才能够使用。如果动作是无法穷举的,你只能够用上图左边这个式子,不能够用右边这个式子。
![](img/6.8.png ':size=550')
上图是文献上的结果,你去估计 Q-function 的话,看到的结果可能如上图所示。假设我们有 3 个动作:原地不动、向上、向下。
* 假设是在第一个状态,不管是采取哪个动作,最后到游戏结束的时候,得到的期望奖励其实都差不多。因为球在这个地方,就算是你向下,接下来你应该还可以急救。所以不管采取哪个动作,都差不了太多。
* 假设在第二个状态,这个乒乓球它已经反弹到很接近边缘的地方,这个时候你采取向上,你才能得到正的奖励,才接的到球。如果你是站在原地不动或向下的话,接下来你都会错过这个球。你得到的奖励就会是负的。
* 假设在第三个状态,球很近了,所以就要向上。
* 假设在第四个状态,球被反弹回去,这时候采取哪个动作就都没有差了。
这是状态-动作价值的一个例子。
![](img/6.9.png ':size=550')
虽然表面上我们学习一个 Q-function它只能拿来评估某一个演员$\pi$ 的好坏,但只要有了这个 Q-function我们就可以做强化学习。有了这个 Q-function我们就可以决定要采取哪一个动作我们就可以进行`策略改进(Policy Improvement)`
它的大原则是这样,假设你有一个初始的演员,也许一开始很烂,随机的也没有关系。初始的演员叫做 $\pi$,这个 $\pi$ 跟环境互动,会收集数据。接下来你学习一个 $\pi$ 这个演员的 Q 值,你去衡量一下 $\pi$ 在某一个状态强制采取某一个动作,接下来用 $\pi$ 这个策略 会得到的期望奖励,用 TD 或 MC 都是可以的。你学习出一个 Q-function 以后,就保证你可以找到一个新的策略 $\pi'$ policy $\pi'$ 一定会比原来的策略 $\pi$ 还要好。那等一下会定义说,什么叫做好。所以假设你有一个 Q-function 和某一个策略 $\pi$,你根据策略 $\pi$ 学习出策略 $\pi$ 的 Q-function接下来保证你可以找到一个新的策略 $\pi'$ ,它一定会比 $\pi$ 还要好,然后你用 $\pi'$ 取代 $\pi$,再去找它的 Q-function得到新的以后再去找一个更好的策略。**这样一直循环下去policy 就会越来越好。**
首先要定义的是什么叫做比较好?我们说 $\pi'$ 一定会比 $\pi$ 还要好,这边好是说,对所有可能的状态 s 而言,$V^{\pi^{\prime}}(s) \geq V^{\pi}(s)$。也就是说我们走到同一个状态 s 的时候,如果拿 $\pi$ 继续跟环境互动下去,我们得到的奖励一定会小于等于用 $\pi'$ 跟环境互动下去得到的奖励。所以不管在哪一个状态,你用 $\pi'$ 去做交互,得到的期望奖励一定会比较大。所以 $\pi'$ 是比 $\pi$ 还要好的一个策略。
有了 Q-function 以后,怎么找这个 $\pi'$ 呢?如果你根据以下的这个式子去决定你的动作,
$Q_{\pi}(s, \pi(s))$ 还满足如下的关系:
$$
\pi^{\prime}(s)=\arg \max _{a} Q^{\pi}(s, a)
Q_{\pi}(s, \pi(s)) \leqslant \max _{a} Q_{\pi}(s, a)
$$
根据上式去决定你的动作的步骤叫做 $\pi'$ 的话,那 $\pi'$ 一定会比 $\pi$ 还要好。假设你已经学习出 $\pi$ 的 Q-function今天在某一个状态 s你把所有可能的动作 a 都一一带入这个 Q-function看看哪一个 a 可以让 Q-function 的值最大,那这个动作就是 $\pi'$ 会采取的动作。
这边要注意一下,给定这个状态 s你的策略 $\pi$ 并不一定会采取动作a我们是给定某一个状态 s 强制采取动作 a用 $\pi$ 继续互动下去得到的期望奖励,这个才是 Q-function 的定义。所以在状态 s 里面不一定会采取动作 a。用 $\pi'$ 在状态 s 采取动作 a 跟 $\pi$ 采取的动作是不一定会一样的,$\pi'$ 所采取的动作会让它得到比较大的奖励。
* 所以这个 $\pi'$ 是用 Q-function 推出来的,没有另外一个网络决定 $\pi'$ 怎么交互,有 Q-function 就可以找出 $\pi'$。
* 但是这边有另外一个问题就是,在这边要解一个 arg max 的问题,所以 a 如果是连续的就会有问题。如果是离散的a 只有 3 个选项,一个一个带进去, 看谁的 Q 最大,没有问题。但如果 a 是连续的,要解 arg max 问题,你就会有问题。
**接下来讲一下为什么用 $Q^{\pi}(s,a)$ 决定出来的 $\pi'$ 一定会比 $\pi$ 好。**
假设有一个策略叫做 $\pi'$,它是由 $Q^{\pi}$ 决定的。我们要证对所有的状态 s 而言,$V^{\pi^{\prime}}(s) \geq V^{\pi}(s)$。
怎么证呢?我们先把 $V^{\pi}(s)$ 写出来:
因为 $a$ 是所有动作里面可以让 Q 函数取最大值的那个动作,所以$Q_{\pi}(s, a)$一定大于等于 $Q_{\pi}(s, \pi(s))$。$Q_{\pi}(s, a)$ $a$ 就是 $\pi'(s)$,因为 $\pi'(s)$ 输出的 $a$ 可以让 $Q_\pi(s,a)$ 最大,所以我们可得
$$
V^{\pi}(s)=Q^{\pi}(s, \pi(s))
\max _{a} Q_{\pi}(s, a)=Q_{\pi}\left(s, \pi^{\prime}(s)\right)
$$
假设在状态 s follow $\pi$ 这个演员,它会采取的动作就是 $\pi(s)$,那你算出来的 $Q^{\pi}(s, \pi(s))$ 会等于 $V^{\pi}(s)$。一般而言,$Q^{\pi}(s, \pi(s))$ 不一定等于 $V^{\pi}(s)$ ,因为动作不一定是 $\pi(s)$。但如果这个动作是 $\pi(s)$ 的话,$Q^{\pi}(s, \pi(s))$ 是等于 $V^{\pi}(s)$ 的。
$Q^{\pi}(s, \pi(s))$ 还满足如下的关系:
于是
$$
Q^{\pi}(s, \pi(s)) \le \max _{a} Q^{\pi}(s, a)
V_{\pi}(s) \leqslant Q_{\pi}\left(s, \pi^{\prime}(s)\right)
$$
也就是在某一个状态,如果我们按照策略 $\pi$ 一直执行下去,得到的奖励一定会小于等于在状态 $s$ 故意不按照 $\pi$ 所指示的方向,而是按照 $\pi'$ 的方向走一步得到的奖励。但只有第一步是按照 $\pi'$ 的方向走,只有在状态 $s$,才按照 $\pi'$ 的指示走,接下来我们就按照 $\pi$ 的指示走。虽然只有一步之差,但我们得到的奖励一定会比完全按照$\pi$ 得到的奖励要大。
接下来要证
$$
Q_{\pi}\left(s, \pi^{\prime}(s) \right) \leqslant V_{\pi'}(s)
$$
因为 a 是所有动作里面可以让 Q 最大的那个动作,所以今天这一项一定会比它大。这一项就是 $Q^{\pi}(s, a)$$a$ 就是 $\pi'(s)$。因为 $\pi'(s)$ 输出的 $a$ 就是可以让 $Q^\pi(s,a)$ 最大的那一个,所以我们得到了下面的式子:
$$
\max _{a} Q^{\pi}(s, a)=Q^{\pi}\left(s, \pi^{\prime}(s)\right)
$$
于是:
$$
V^{\pi}(s) \leq Q^{\pi}\left(s, \pi^{\prime}(s)\right)
$$
也就是说某一个状态,如果按照策略 $\pi$ 一直做下去,你得到的奖励一定会小于等于,在这个状态 s 你故意不按照 $\pi$ 所给你指示的方向,而是按照 $\pi'$ 的方向走一步,但只有第一步是按照 $\pi'$ 的方向走,只有在状态 s 这个地方,你才按照 $\pi'$ 的指示走,接下来你就按照 $\pi$ 的指示走。虽然只有一步之差, 但是从上面这个式子可知,虽然只有一步之差,但你得到的奖励一定会比完全 follow $\pi$ 得到的奖励还要大。
接下来要证下面的式子:
$$
Q^{\pi}\left(s, \pi^{\prime}(s) \right) \le V^{\pi'}(s)
$$
也就是说,只有一步之差,你会得到比较大的奖励。**但假设每步都是不一样的,每步都是 follow $\pi'$ 而不是 $\pi$ 的话,那你得到的奖励一定会更大。**如果你要用数学式把它写出来的话,你可以写成 $Q^{\pi}\left(s, \pi^{\prime}(s)\right)$ ,它的意思就是说,我们在状态 $s_t$ 采取动作 $a_t$,得到奖励 $r_{t}$,然后跳到状态 $s_{t+1}$,即如下式所示:
也就是,只有一步之差,我们会得到比较大的奖励。但假设每步都是不一样的,每步都按照 $\pi'$ 而不是 $\pi$,得到的奖励一定会更大,即 $Q_{\pi}\left(s, \pi^{\prime}(s)\right)$是指我们在状态 $s_t$ 采取动作 $a_t$,得到奖励 $r_{t}$,进入状态 $s_{t+1}$,即
$$
Q^{\pi}\left(s, \pi^{\prime}(s)\right)=E\left[r_t+V^{\pi}\left(s_{t+1}\right) \mid s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
$$
> 在文献上有时也会说:在状态 $s_t$ 采取动作 $a_t$ 得到奖励 $r_{t+1}$ 有人会写成 $r_t$,但意思其实都是一样的。
在状态 $s$ 按照 $\pi'$ 采取某一个动作 $a_t$ ,得到奖励 $r_{t}$,然后跳到状态 $s_{t+1}$$V^{\pi}\left(s_{t+1}\right)$ 是状态 $s_{t+1}$ 根据 $\pi$ 这个演员所估出来的值。因为在同样的状态采取同样的动作,你得到的奖励和会跳到的状态不一定一样, 所以这边需要取一个期望值。
因为 $V^{\pi}(s) \leq Q^{\pi}\left(s, \pi^{\prime}(s)\right)$,也就是 $V^{\pi}(s_{t+1}) \leq Q^{\pi}\left(s_{t+1}, \pi^{\prime}(s_{t+1})\right)$,所以我们得到下式:
$$
\begin{array}{l}
E\left[r_{t}+V^{\pi}\left(s_{t+1}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
\leq E\left[r_{t}+Q^{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
\end{array}
Q_{\pi}\left(s, \pi^{\prime}(s)\right)=\mathbb{E}\left[r_t+V_{\pi}\left(s_{t+1}\right) \mid s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
$$
因为 $Q^{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) = r_{t+1}+V^{\pi}\left(s_{t+2}\right)$,所以我们得到下式:
有的文献上也会说:在状态 $s_t$ 采取动作 $a_t$,得到奖励 $r_{t+1}$。但意思其实都是一样的。在状态 $s$ 按照 $\pi'$ 采取某一个动作 $a_t$ ,得到奖励 $r_{t}$,进入状态 $s_{t+1}$$V_{\pi}\left(s_{t+1}\right)$ 是状态 $s_{t+1}$ 根据策略 $\pi$ 所估出来的值。因为在同样的状态采取同样的动作,我们得到的奖励和会进入的状态不一定一样, 所以需要取期望值。
因为 $V_{\pi}(s) \leqslant Q_{\pi}\left(s, \pi^{\prime}(s)\right)$,也就是 $V_{\pi}(s_{t+1}) \leqslant Q_{\pi}\left(s_{t+1}, \pi^{\prime}(s_{t+1})\right)$,所以我们可得
$$
\begin{array}{l}
E\left[r_{t}+Q^{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
=E\left[r_{t}+r_{t+1}+V^{\pi}\left(s_{t+2}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
\end{array}
\begin{array}{l}
\mathbb{E}\left[r_{t}+V_{\pi}\left(s_{t+1}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
\leqslant \mathbb{E}\left[r_{t}+Q_{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
\end{array}
$$
然后你再代入 $V^{\pi}(s) \leq Q^{\pi}\left(s, \pi^{\prime}(s)\right)$,一直算到回合结束,即:
因为 $Q_{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) = r_{t+1}+V_{\pi}\left(s_{t+2}\right)$,所以我们可得
$$
\begin{aligned}
V^{\pi}(s) &\le Q^{\pi}(s,\pi'(s)) \\
&=E\left[r_{t}+V^{\pi}\left(s_{t+1}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]\\
&\le E\left[r_{t}+Q^{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
&=E\left[r_{t}+r_{t+1}+V^{\pi}\left(s_{t+2}\right) |s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& \le E\left[r_{t}+r_{t+1}+Q^{\pi}\left(s_{t+2},\pi'(s_{t+2}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& = E\left[r_{t}+r_{t+1}+r_{t+2}+V^{\pi}\left(s_{t+3}\right) |s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& \le \cdots\\
& \le E\left[r_{t}+r_{t+1}+r_{t+2}+\cdots | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& = V^{\pi'}(s)
\end{aligned}
\begin{array}{l}
\mathbb{E}\left[r_{t}+Q_{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
=\mathbb{E}\left[r_{t}+r_{t+1}+V_{\pi}\left(s_{t+2}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
\end{array} \tag{6.5}
$$
因此:
我们再把式(6.5)代入 $V_{\pi}(s) \leqslant Q_{\pi}\left(s, \pi^{\prime}(s)\right)$,一直算到回合结束,即
$$
V^{\pi}(s)\le V^{\pi'}(s)
\begin{aligned}
V^{\pi}(s) &\le Q^{\pi}(s,\pi'(s)) \\
&=E\left[r_{t}+V^{\pi}\left(s_{t+1}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]\\
&\le E\left[r_{t}+Q^{\pi}\left(s_{t+1}, \pi^{\prime}\left(s_{t+1}\right)\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
&=E\left[r_{t}+r_{t+1}+V^{\pi}\left(s_{t+2}\right) |s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& \le E\left[r_{t}+r_{t+1}+Q^{\pi}\left(s_{t+2},\pi'(s_{t+2}\right) | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& = E\left[r_{t}+r_{t+1}+r_{t+2}+V^{\pi}\left(s_{t+3}\right) |s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& \le \cdots\\
& \le E\left[r_{t}+r_{t+1}+r_{t+2}+\cdots | s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right] \\
& = V^{\pi'}(s)
\end{aligned}
$$
**从这边我们可以知道,你可以估计某一个策略的 Q-function接下来你就可以找到另外一个策略 $\pi'$ 比原来的策略还要更好。**
## Target Network
![](img/6.12.png ':size=550')
接下来讲一下在 DQN 里一定会用到的 tip。第一个是 `目标网络(target network)`,什么意思呢?我们在学习 Q-function 的时候,也会用到 TD 的概念。那怎么用 TD你现在收集到一个数据 是说在状态 $s_t$,你采取动作 $a_t$ 以后,你得到奖励 $r_t$ ,然后跳到状态 $s_{t+1}$。然后根据这个 Q-function你会知道说
因此
$$
\mathrm{Q}^{\pi}\left(s_{t}, a_{t}\right)
=r_{t}+\mathrm{Q}^{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)
V_{\pi}(s)\leqslant V_{\pi'}(s)
$$
所以在学习的时候,你会说我们有 Q-function输入 $s_t$, $a_t$ 得到的值,跟输入 $s_{t+1}$, $\pi (s_{t+1})$ 得到的值中间,我们希望它差了一个 $r_t$ 这跟刚才讲的 TD 的概念是一样的
我们可以估计某一个策略的Q函数接下来就可以找到另外一个策略 $\pi'$ 比原来的策略$\pi$还要更好
但是实际上这样的一个输入并不好学习,因为假设这是一个回归问题,$\mathrm{Q}^{\pi}\left(s_{t}, a_{t}\right) $ 是网络的输出,$r_{t}+\mathrm{Q}^{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)$ 是目标,你会发现目标是会动的。当然你要实现这样的训练,其实也没有问题,就是你在做反向传播的时候, $Q^{\pi}$ 的参数会被更新,你会把两个更新的结果加在一起。因为它们是同一个模型 $Q^{\pi}$ 所以两个更新的结果会加在一起。但这样会导致训练变得不太稳定,因为假设你把 $\mathrm{Q}^{\pi}\left(s_{t}, a_{t}\right) $ 当作你模型的输出,$r_{t}+\mathrm{Q}^{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)$ 当作目标的话,你要去拟合的目标是一直在变的,这种一直在变的目标的训练是不太好训练的。
## 6.3 目标网络
所以你会把其中一个 Q 网络,通常是你会把右边这个 Q 网络固定住。也就是说你在训练的时候,你只更新左边的 Q 网络的参数,而右边的 Q 网络的参数会被固定住。因为右边的 Q 网络负责产生目标,所以叫 `目标网络`。因为目标网络是固定的,所以你现在得到的目标 $r_{t}+\mathrm{Q}^{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)$ 的值也是固定的。因为目标网络是固定的,我们只调左边网络的参数,它就变成是一个回归问题。我们希望模型的输出的值跟目标越接近越好,你会最小化它的均方误差(mean square error)。
在实现的时候,你会把左边的 Q 网络更新好几次以后,再去用更新过的 Q 网络替换这个目标网络。但它们两个不要一起动,它们两个一起动的话,结果会很容易坏掉。
一开始这两个网络是一样的,然后在训练的时候,你会把右边的 Q 网络固定住。你在做梯度下降的时候,只调左边这个网络的参数,那你可能更新 100 次以后才把这个参数复制到右边的网络去,把它盖过去。把它盖过去以后,你这个目标值就变了。就好像说你本来在做一个回归问题,那你训练 后把这个回归问题的 loss 压下去以后,接下来你把这边的参数把它复制过去以后,你的目标就变掉了,接下来就要重新再训练。
### Intuition
![](img/6.13.png ':size=550')
我们可以通过猫追老鼠的例子来直观地理解为什么要 fix target network。猫是 `Q estimation`,老鼠是 `Q target`。一开始的话,猫离老鼠很远,所以我们想让这个猫追上老鼠。
![](img/6.14.png ':size=550')
因为 Q target 也是跟模型参数相关的所以每次优化后Q target 也会动。这就导致一个问题,猫和老鼠都在动。
![](img/6.15.png ':size=550')
然后它们就会在优化空间里面到处乱动,就会产生非常奇怪的优化轨迹,这就使得训练过程十分不稳定。所以我们可以固定 Q target让老鼠动得不是那么频繁可能让它每 5 步动一次,猫则是每一步都在动。如果老鼠每 5 次动一步的话猫就有足够的时间来接近老鼠。然后它们之间的距离会随着优化过程越来越小最后它们就可以拟合拟合过后就可以得到一个最好的Q 网络。
## Exploration
![](img/6.16.png ':size=550')
**第二个 tip 是`探索(Exploration)`。**当我们使用 Q-function 的时候policy 完全取决于 Q-function。给定某一个状态你就穷举所有的 a 看哪个 a 可以让 Q 值最大,它就是采取的动作。这个跟策略梯度不一样,在做策略梯度的时候,输出其实是随机的。我们输出一个动作的分布,根据这个动作的分布去做采样, 所以在策略梯度里面,你每次采取的动作是不一样的,是有随机性的。
像这种 Q-function 如果你采取的动作总是固定的,会有什么问题呢?你会遇到的问题就是这不是一个好的收集数据的方式。因为假设我们今天真的要估某一个状态,你可以采取动作 $a_{1}$, $a_{2}$, $a_{3}$。你要估测在某一个状态采取某一个动作会得到的 Q 值,你一定要在那一个状态采取过那一个动作,才估得出它的值。如果你没有在那个状态采取过那个动作,你其实估不出那个值的。如果是用深的网络,就你的 Q-function 是一个网络,这种情形可能会没有那么严重。但是一般而言,假设 Q-function 是一个表格,没有看过的 state-action pair它就是估不出值来。网络也是会有一样的问题只是没有那么严重。所以今天假设你在某一个状态动作 $a_{1}$, $a_{2}$, $a_{3}$ 你都没有采取过,那你估出来的 $Q(s,a_{1})$, $Q(s,a_{2})$, $Q(s,a_{3})$ 的值可能都是一样的,就都是一个初始值,比如说 0
接下来讲一些在 深度Q网络 里一定会用到的技巧。第一个技巧是**目标网络target network**。我们在学习Q函数的时候也会用到时序差分方法的概念。我们现在收集到一个数据比如在状态 $s_t$ 采取动作 $a_t$ 以后,得到奖励 $r_t$ ,进入状态 $s_{t+1}$。根据Q函数我们可知
$$
\begin{array}{l}
Q(s, a_1)=0 \\
Q(s, a_2)=0 \\
Q(s, a_3)=0
\end{array}
Q_{\pi}\left(s_{t}, a_{t}\right)
=r_{t}+Q_{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)
$$
所以我们在学习的时候Q 函数输入 $s_t$、$a_t$ 得到的值,与输入 $s_{t+1}$、$\pi (s_{t+1})$ 得到的值之间,我们希望它们相差 $r_t$ 这与时序差分方法的概念是一样的。但是实际上这样的输入并不好学习,假设这是一个回归问题,如图 6.9 所示,$Q_{\pi}\left(s_{t}, a_{t}\right) $ 是网络的输出,$r_{t}+Q_{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)$ 是目标,目标是会变动的。当然如果我们要实现这样的训练,其实也没有问题,就是在做反向传播的时候, $Q_{\pi}$ 的参数会被更新,我们会把两个更新的结果加在一起(因为它们是同一个模型 $Q_{\pi}$ 所以两个更新的结果会加在一起)。但这样会导致训练变得不太稳定,因为假设我们把 $Q_{\pi}\left(s_{t}, a_{t}\right) $ 当作模型的输出, 把$r_{t}+Q_{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)$ 当作目标,我们要去拟合的目标是一直在变动的,这是不太好训练的。
所以我们会把其中一个 Q 网络,通常是把图 6.9 右边的 Q 网络固定住。在训练的时候,我们只更新左边的 Q 网络的参数,而右边的 Q 网络的参数会被固定。因为右边的 Q 网络负责产生目标,所以被称为目标网络。因为目标网络是固定的,所以现在得到的目标 $r_{t}+Q_{\pi}\left(s_{t+1}, \pi\left(s_{t+1}\right)\right)$ 的值也是固定的。我们只调整左边Q网络的参数它就变成一个回归问题。我们希望模型输出的值与目标越接近越好这样会最小化它的均方误差mean square error
在实现的时候,我们会把左边的 Q 网络更新多次,再用更新过的 Q 网络替换目标网络。但这两个网络不要一起更新,一起更新,结果会很容易不好。一开始这两个网络是一样的,在训练的时候,我们会把右边的 Q 网络固定住在做梯度下降的时候只调整左边Q网络的参数。我们可能更新 100 次以后才把参数复制到右边的网络中,把右边网络的参数覆盖,目标值就变了。就好像我们本来在做一个回归问题,训练后把这个回归问题的损失降下去以后,接下来我们把左边网络的参数复制到右边网络,目标值就变了,接下来就要重新训练。
<div align=center>
<img width="550" src="../img/ch6/6.12.png"/>
</div>
<div align=center>图 6.9 目标网络</div>
如图 6.10a 所示,我们可以通过猫追老鼠的例子来直观地理解固定目标网络的目的。猫是 Q 估计,老鼠是 Q 目标。一开始,猫离老鼠很远,所以我们想让猫追上老鼠。如图 6.10b 所示,因为 Q 目标也是与模型参数相关的所以每次优化后Q 目标也会动。这就导致一个问题,猫和老鼠都在动。如图 6.10c 所示,猫和老鼠会在优化空间里面到处乱动,这会产生非常奇怪的优化轨迹,使得训练过程十分不稳定。所以我们可以固定 Q 网络,让老鼠动得不那么频繁,可能让它每 5 步动一次,猫则是每一步都在动。如果老鼠每 5 次动一步猫就有足够的时间来接近老鼠它们之间的距离会随着优化过程越来越小最后它们就可以拟合拟合后就可以得到一个最好的Q 网络。
<div align=center>
<img width="550" src="../img/ch6/6.10.png"/>
</div>
<div align=center>图 6.10 固定目标网络</div>
## 6.4 探索
第二个技巧是**探索**。当我们使用 Q 函数的时候,策略完全取决于 Q 函数。给定某一个状态我们就穷举所有的动作采取让Q值最大的动作
$$
a=\underset{a}{\arg \max} Q(s, a)
$$
使用Q函数来决定动作与使用策略梯度不一样策略梯度的输出是随机的它会输出一个动作的分布我们根据这个动作的分布去采样所以在策略梯度里面我们每次采取的动作是不一样的是有随机性的。像Q函数中如果我们采取的动作总是固定的会遇到的问题就是这不是一个好的收集数据的方式。假设我们要估测某一个状态可以采取动作 $a_{1}$、$a_{2}$、$a_{3}$。我们要估测在某一个状态采取某一个动作会得到的 Q 值一定要在那一个状态采取过那一个动作才能估测出它的值。如果没有在那个状态采取过那个动作我们其实是估测不出它的值的。如果Q函数是一个网络这个问题可能没有那么严重。但是一般而言假设Q函数是一个表格对于没有见过的状态-动作对,它是估不出值的。如果 Q 函数是网络,也会有类似的问题,只是没有那么严重。所以假设我们在某一个状态,动作 $a_{1}$、$a_{2}$、$a_{3}$ 都没有采取过,估出来的 $Q(s,a_{1})$、$Q(s,a_{2})$、$Q(s,a_{3})$ 的值可能都是一样的,都是一个初始值,比如 0
$$
\begin{array}{l}
Q(s, a_1)=0 \\
Q(s, a_2)=0 \\
Q(s, a_3)=0
\end{array}
$$
但是假设你在状态 s你采样过某一个动作 $a_{2}$ ,它得到的值是正的奖励。那 $Q(s, a_2)$ 就会比其他动作都要好。在采取动作的时候, 就看说谁的 Q 值最大就采取谁,所以之后永远都只会采样到 $a_{2}$,其他的动作就再也不会被做了,所以就会有问题。就好像说你进去一个餐厅吃饭,其实你都很难选。你今天点了某一个东西以后,假说点了某一样东西, 比如椒麻鸡,觉得还可以。接下来每次去就都会点椒麻鸡,再也不点别的东西了,那就不知道别的东西是不是会比椒麻鸡好吃,这是一样的问题。
但是如图 6.11 所示,假设我们在状态 $s$采取动作 $a_{2}$ ,它得到的值是正的奖励$Q(s, a_2)$ 就会比其他动作的Q值要大。在采取动作的时候,谁的 Q 值 最大就采取谁,所以之后永远都只会采 $a_{2}$,其他的动作就再也不会被采取了,这就会有问题。比如我们去一个餐厅吃饭。假设我们点了某一样菜,比如椒麻鸡,我们觉得还可以。接下来我们每次去就都会点椒麻鸡,再也不点别的了,那我们就不知道别的是不是会比椒麻鸡好吃,这是一样的问题。
如果你没有好的探索的话,你在训练的时候就会遇到这种问题。举个例子, 假设你用 DQN 来玩`slither.io`。 你会有一个蛇,它在环境里面就走来走去,吃到星星,它就加分。假设这个游戏一开始,它往上走,然后就吃到那个星星,它就得到分数,它就知道说往上走可以得到奖励。接下来它就再也不会采取往上走以外的动作了,所以接下来就会变成每次游戏一开始,它就往上冲,然后就死掉。所以需要有探索的机制,让机器知道说,虽然根据之前采样的结果,$a_2$ 好像是不错的,但你至少偶尔也试一下 $a_{1}$ 跟 $a_{3}$,说不定它们更好。
这个问题其实就是`探索-利用窘境(Exploration-Exploitation dilemma)`问题。
有两个方法解这个问题,一个是 `Epsilon Greedy`。Epsilon Greedy($\varepsilon\text{-greedy}$) 的意思是说,我们有 $1-\varepsilon$ 的概率会按照 Q-function 来决定 动作,通常 $\varepsilon$ 就设一个很小的值, $1-\varepsilon$ 可能是 90%,也就是 90% 的概率会按照 Q-function 来决定 动作,但是你有 10% 的机率是随机的。通常在实现上 $\varepsilon$ 会随着时间递减。在最开始的时候。因为还不知道那个动作是比较好的,所以你会花比较大的力气在做探索。接下来随着训练的次数越来越多。已经比较确定说哪一个 Q 是比较好的。你就会减少你的探索,你会把 $\varepsilon$ 的值变小,主要根据 Q-function 来决定你的动作,比较少随机决定动作,这是 Epsilon Greedy。
还有一个方法叫做 `Boltzmann Exploration`,这个方法就比较像是策略梯度。在策略梯度里面,网络的输出是一个期望的动作空间上面的一个的概率分布,再根据概率分布去做采样。那其实你也可以根据 Q 值 去定一个概率分布,假设某一个动作的 Q 值越大,代表它越好,我们采取这个动作的机率就越高。但是某一个动作的 Q 值小,不代表我们不能尝试。
Q: 我们有时候也要尝试那些 Q 值比较差的动作,怎么做呢?
A: 因为 Q 值是有正有负的,所以可以它弄成一个概率,你先取指数,再做归一化。然后把 $\exp(Q(s,a))$ 做归一化的这个概率当作是你在决定动作的时候采样的概率。在实现上Q 是一个网络,所以你有点难知道, 在一开始的时候网络的输出到底会长怎么样子。假设你一开始没有任何的训练数据,参数是随机的,那给定某一个状态 s不同的 a 输出的值可能就是差不多的,所以一开始 $Q(s,a)$ 应该会倾向于是均匀的。也就是在一开始的时候,你这个概率分布算出来,它可能是比较均匀的。
## Experience Replay
![](img/6.17.png ':size=550')
**第三个 tip 是 `Experience Replay(经验回放)`。** Experience Replay 会构建一个 `Replay Buffer`Replay Buffer 又被称为 `Replay Memory`。Replay Buffer 是说现在会有某一个策略$\pi$ 去跟环境做互动,然后它会去收集数据。我们会把所有的数据放到一个 buffer 里面buffer 里面就存了很多数据。比如说 buffer 是 5 万,这样它里面可以存 5 万笔资料,每一笔资料就是记得说,我们之前在某一个状态 $s_t$,采取某一个动作 $a_t$,得到了奖励 $r_t$。然后跳到状态 $s_{t+1}$。那你用 $\pi$ 去跟环境互动很多次,把收集到的资料都放到这个 replay buffer 里面。
这边要注意是 replay buffer 里面的经验可能是来自于不同的策略,你每次拿 $\pi$ 去跟环境互动的时候,你可能只互动 10000 次,然后接下来就更新你的 $\pi$ 了。但是这个 buffer 里面可以放 5 万笔资料,所以 5 万笔资料可能是来自于不同的策略。Buffer 只有在它装满的时候,才会把旧的资料丢掉。所以这个 buffer 里面它其实装了很多不同的策略的经验。
![](img/6.18.png ':size=550')
有了 buffer 以后,怎么训练 Q 的模型,怎么估 Q-function你的做法是这样迭代地去训练这个 Q-function在每次迭代里面从这个 buffer 里面随机挑一个 batch 出来,就跟一般的网络训练一样,从那个训练集里面,去挑一个 batch 出来。你去采样一个 batch 出来,里面有一把的经验,根据这把经验去更新你的 Q-function。就跟 TD learning 要有一个目标网络是一样的。你去采样一堆 batch采样一个 batch 的数据,采样一堆经验,然后再去更新你的 Q-function。
当我们这么做的时候, 它变成了一个 `off-policy` 的做法。因为本来我们的 Q 是要观察 $\pi$ 的经验,但实际上 replay buffer 里面的这些经验不是通通来自于 $\pi$,有些是过去其他的 $\pi$ 所遗留下来的经验。因为你不会拿某一个 $\pi$ 就把整个 buffer 装满,然后拿去测 Q-function这个 $\pi$ 只是采样一些数据塞到那个 buffer 里面去,然后接下来就让 Q 去训练。所以 Q 在采样的时候, 它会采样到过去的一些资料。
这么做有两个好处:
* 其实在做强化学习的时候, 往往最花时间的步骤是在跟环境做互动,训练网络反而是比较快的。因为用 GPU 训练其实很快, 真正花时间的往往是在跟环境做互动。用 replay buffer 可以减少跟环境做互动的次数,因为在做训练的时候,你的经验不需要通通来自于某一个策略。一些过去的策略所得到的经验可以放在 buffer 里面被使用很多次,被反复的再利用,这样让采样到经验的利用是比较高效的。
* 在训练网络的时候,其实我们希望一个 batch 里面的数据越多样(diverse)越好。如果 batch 里面的数据都是同样性质的,训练下去是容易坏掉的。如果 batch 里面都是一样的数据训练的时候performance 会比较差。我们希望 batch 的数据越多样越好。那如果 buffer 里面的那些经验通通来自于不同的策略,那采样到的一个 batch 里面的数据会是比较多样的。
Q我们明明是要观察 $\pi$ 的值,里面混杂了一些不是 $\pi$ 的经验,这有没有关系?
A没关系。这并不是因为过去的 $\pi$ 跟现在的 $\pi$ 很像, 就算过去的 $\pi$ 没有很像,其实也是没有关系的。主要的原因是因为, 我们并不是去采样一个轨迹,我们只采样了一笔经验,所以跟是不是 off-policy 这件事是没有关系的。就算是 off-policy就算是这些经验不是来自于 $\pi$,我们其实还是可以拿这些经验来估测 $Q^{\pi}(s,a)$。这件事有点难解释,不过你就记得说 Experience Replay 在理论上也是没有问题的。
## DQN
![](img/dqn.png ':size=550')
DQN 使用深度卷积神经网络近似拟合状态动作值函数 $Q(s,a)$其网络结构如上图所示。DQN 模型的输入是距离当前时刻最近的 4 帧图像,该输入经过 3 个卷积层和 2 个全连接层的非线性变化后,最终在输出层输出每个动作对应的 Q 值。
![](img/6.19.png ':size=550')
<div align=center>
<img width="550" src="../img/ch6/6.16.png"/>
</div>
<div align=center>图 6.11 探索</div>
上图就是一般的 `Deep Q-network(DQN)` 的算法
如果我们没有好的探索,在训练的时候就会遇到这种问题。例如, 假设我们用 深度Q网络 来玩 slither.io 网页游戏。 我们有一条蛇,它在环境里面走来走去,吃到星星,就加分。假设游戏一开始,蛇往上走,然后吃到星星,就可以得到分数,它就知道往上走可以得到奖励。接下来它就再也不会采取往上走以外的动作了,以后就会变成每次游戏一开始,它就往上走,然后游戏结束。所以需要有探索的机制,让智能体知道,虽然根据之前采样的结果,$a_2$ 好像是不错的,但我们至少偶尔也试一下 $a_{1}$ 与 $a_{3}$,说不定它们更好
这个算法是这样的。初始化的时候,你初始化 2 个网络Q 和 $\hat{Q}$,其实 $\hat{Q}$ 就等于 Q。一开始这个目标 Q 网络,跟你原来的 Q 网络是一样的。在每一个 episode你拿你的演员去跟环境做互动在每一次互动的过程中你都会得到一个状态 $s_t$,那你会采取某一个动作 $a_t$。怎么知道采取哪一个动作 $a_t$ 呢?你就根据你现在的 Q-function。但是你要有探索的机制。比如说你用 Boltzmann 探索或是 Epsilon Greedy 的探索。那接下来你得到奖励 $r_t$,然后跳到状态 $s_{t+1}$。所以现在收集到一笔数据,这笔数据是 ($s_t$, $a_t$ ,$r_t$, $s_{t+1}$)。这笔数据就塞到你的 buffer 里面去。如果 buffer 满的话, 你就再把一些旧的资料丢掉。接下来你就从你的 buffer 里面去采样数据,那你采样到的是 $(s_{i}, a_{i}, r_{i}, s_{i+1})$。这笔数据跟你刚放进去的不一定是同一笔,你可能抽到一个旧的。要注意的是,其实你采样出来不是一笔数据,你采样出来的是一个 batch 的数据,你采样一个 batch 出来,采样一把经验出来。接下来就是计算你的目标。假设采样出这么一笔数据。根据这笔数据去算你的目标。你的目标是什么呢?目标记得要用目标网络 $\hat{Q}$ 来算。目标是:
这个问题就是**探索-利用窘境exploration-exploitation dilemma**问题,有两个方法可以解决这个问题:$\pmb{\varepsilon}$**-贪心**和**玻尔兹曼探索Boltzmann exploration**。
$\varepsilon$-贪心是指我们有 $1-\varepsilon$ 的概率会按照Q函数来决定动作可写为
$$
y=r_{i}+\max _{a} \hat{Q}\left(s_{i+1}, a\right)
a=
\begin{cases}
\underset{a}{\arg \max} Q(s, a) & \text {, 有 } 1-\varepsilon \text { 的概率 } \\
\text { 随机} & \text {, 否则 }
\end{cases}
$$
其中 a 就是让 $\hat{Q}$ 的值最大的 a。因为我们在状态 $s_{i+1}$会采取的动作 a其实就是那个可以让 Q 值最大的那一个 a。接下来我们要更新 Q 的值,那就把它当作一个回归问题。希望 $Q(s_i,a_i)$ 跟你的目标越接近越好。然后假设已经更新了某一个数量的次,比如说 C 次,设 C = 100 那你就把 $\hat{Q}$ 设成 Q这就是 DQN。
Q: DQN 和 Q-learning 有什么不同?
通常将 $\varepsilon$ 设为一个很小的值, $1-\varepsilon$ 可能是 0.9,也就是 0.9 的概率会按照Q函数来决定动作但是我们有 0.1 的概率是随机的。通常在实现上 $\varepsilon$ 会随着时间递减。在最开始的时候,因为不知道哪个动作是比较好的,所以我们会花比较大的力气探索。接下来,随着训练的次数越来越多,我们已经比较确定哪个动作是比较好的。我们就会减少探索,会把 $\varepsilon$ 的值变小主要根据Q函数来决定动作比较少随机决定动作这就是$\varepsilon$-贪心。
A: 整体来说DQN 与 Q-learning 的目标价值以及价值的更新方式都非常相似,主要的不同点在于:
还有一个方法称为玻尔兹曼探索。在玻尔兹曼探索中,我们假设对于任意的 $s$、$a$$Q(s,a) \geqslant 0$,因此 $a$ 被选中的概率与 $e^{Q(s, a) / T}$ 呈正比,即
$$
\pi(a \mid s)=\frac{\mathrm{e}^{Q(s, a) / T}}{\sum_{a^{\prime} \in A} \mathrm{e}^{Q\left(s, a^{\prime}\right) / T}}
$$
其中,$T>0$ 称为温度系数。如果 $T$ 很大,所有动作几乎以等概率选择(探索);如果 $T$ 很小Q值大的动作更容易被选中利用如果 $T$ 趋于0我们就只选择最优动作。
* DQN 将 Q-learning 与深度学习结合,用深度网络来近似动作价值函数,而 Q-learning 则是采用表格存储;
* DQN 采用了经验回放的训练方法,从历史数据中随机采样,而 Q-learning 直接采用下一个状态的数据进行学习
## 6.5 经验回放
第三个技巧是**经验回放experience replay**。如图 6.12 所示,经验回放会构建一个**回放缓冲区replay buffer**,回放缓冲区又被称为**回放内存replay memory**。回放缓冲区是指现在有某一个策略$\pi$ 与环境交互它会去收集数据我们把所有的数据放到一个数据缓冲区buffer里面数据缓冲区里面存储了很多数据。比如数据缓冲区可以存储 5 万笔数据,每一笔数据就是记得说,我们之前在某一个状态 $s_t$,采取某一个动作 $a_t$,得到了奖励 $r_t$,进入状态 $s_{t+1}$。我们用 $\pi$ 去与环境交互多次,把收集到的数据放到回放缓冲区里面
回放缓冲区里面的经验可能来自不同的策略,我们每次用 $\pi$ 与环境交互的时候,可能只交互 10000 次,接下来我们就更新 $\pi$ 了。但是回放缓冲区里面可以放 5 万笔数据,所以 5 万笔数据可能来自不同的策略。回放缓冲区只有在它装满的时候,才会把旧的数据丢掉。所以回放缓冲区里面其实装了很多不同的策略的经验。
## 一些技巧
下面我们介绍下 DQN 的基本技巧:
<div align=center>
<img width="550" src="../img/ch6/6.17.png"/>
</div>
<div align=center>图 6.12 经验回放</div>
* 在 Atari 游戏里面,一般 mini-batch 设置为 32。
* Experience replay 用在新问题上一般为 $10^6$。
## References
如图 6.13 所示,有了回放缓冲区以后,我们怎么训练 Q 模型、怎么估 Q 函数呢?我们会迭代地训练 Q 函数在每次迭代里面从回放缓冲区中随机挑一个批量batch出来即与一般的网络训练一样从训练集里面挑一个批量出来。我们采样该批量出来里面有一些经验我们根据这些经验去更新Q函数。这与时序差分学习要有一个目标网络是一样的。我们采样一个批量的数据得到一些经验再去更新 Q 函数。
如果某个算法使用了经验回放这个技巧,该算法就变成了一个异策略的算法。因为本来 Q 是要观察 $\pi$ 的经验的,但实际上存储在回放缓冲区里面的这些经验不是通通来自于 $\pi$,有些是过去其他的策略所留下来的经验。因为我们不会用某一个 $\pi$ 就把整个回放缓冲区装满拿去测Q函数$\pi$ 只是采样一些数据放到回放缓冲区里面,接下来就让 Q 去训练。所以 Q 在采样的时候, 它会采样到过去的一些数据。
<div align=center>
<img width="550" src="../img/ch6/6.18.png"/>
</div>
<div align=center>图 6.13 使用回放缓冲区训练Q函数</div>
这么做有两个好处。第一个好处是,在进行强化学习的时候, 往往最花时间的步骤是与环境交互,训练网络反而是比较快的。因为我们用 GPU 训练其实很快真正花时间的往往是与环境交互。用回放缓冲区可以减少与环境交互的次数因为在做训练的时候经验不需要通通来自于某一个策略。一些过去的策略所得到的经验可以放在回放缓冲区里面被使用很多次被反复的再利用这样可以比较高效地采样经验。第二个好处是在训练网络的时候其实我们希望一个批量里面的数据越多样diverse越好。如果批量里面的数据都是同样性质的我们训练下去训练结果是容易不好的。如果批量里面都是一样的数据训练的时候性能会比较差。我们希望批量里的数据越多样越好。如果回放缓冲区里面的经验通通来自于不同的策略我们采样到的一个批量里面的数据会是比较多样的。
Q我们观察 $\pi$ 的值,发现里面混杂了一些不是 $\pi$ 的经验,这有没有关系?
A没关系。这并不是因为过去的策略与现在的策略很像 就算过去的策略与现在的策略不是很像,也是没有关系的。主要的原因是我们并不是去采样一个轨迹,我们只采样了一笔经验,所以与是不是异策略这件事是没有关系的。就算是异策略,就算是这些经验不是来自于 $\pi$,我们还是可以用这些经验来估测 $Q_{\pi}(s,a)$。
## 6.6 深度Q网络
图 6.14 所示为一般的深度Q网络算法。深度Q网络 算法是这样的,我们初始化两个网络------$Q$ 和 $\hat{Q}$$\hat{Q}$ 就等于 $Q$。一开始目标网络$\hat{Q}$与原来的 Q 网络是一样的。在每一个回合中,我们用演员与环境交互,在每一次交互的过程中,都会得到一个状态 $s_t$,会采取某一个动作 $a_t$。
怎么知道采取哪一个动作 $a_t$ 呢我们就根据现在的Q函数但是要有探索的机制。比如我们用玻尔兹曼探索或是$\varepsilon$-贪心探索,接下来得到奖励 $r_t$,进入状态 $s_{t+1}$。所以现在收集到一笔数据$(s_t$、$a_t$ 、$r_t$、$s_{t+1})$,我们将其放到回放缓冲区里面。如果回放缓冲区满了, 我们就把一些旧的数据丢掉。接下来我们就从回放缓冲区里面去采样数据,采样到的是 $(s_{i}$、$a_{i}$、$r_{i}$、$s_{i+1})$。这笔数据与刚放进去的不一定是同一笔,我们可能抽到旧的。要注意的是,我们采样出来不是一笔数据,采样出来的是一个批量的数据,采样一些经验出来。
接下来就是计算目标。假设我们采样出一笔数据,根据这笔数据去计算目标。目标要用目标网络 $\hat{Q}$ 来计算。目标是:
$$
y=r_{i}+\max _{a} \hat{Q}\left(s_{i+1}, a\right)
$$
其中,$a$ 是让 $\hat{Q}$ 值最大的动作。因为我们在状态 $s_{i+1}$会采取的动作 $a$ 就是可以让 $\hat{Q}$值最大的那一个动作。接下来我们要更新 Q 值,就把它当作一个回归问题。我们希望 $Q(s_i,a_i)$ 与目标越接近越好。假设已经更新了一定的次数,比如 $C$ 次,设 $C = 100$ 那我们就把 $\hat{Q}$ 设成 $Q$,这就是 深度Q网络 算法。
<div align=center>
<img width="550" src="../img/ch6/6.19.png"/>
</div>
<div align=center>图 6.14 深度Q网络算法</div>
Q深度Q网络 和 Q学习 有什么不同?
A整体来说深度Q网络与Q学习的目标价值以及价值的更新方式都非常相似。主要的不同点在于深度Q网络 将Q学习与深度学习结合用深度网络来近似动作价值函数而 Q学习 则是采用表格存储深度Q网络采用了经验回放的训练方法从历史数据中随机采样而Q学习直接采用下一个状态的数据进行学习。
## 参考文献
* [Intro to Reinforcement Learning (强化学习纲要)](https://github.com/zhoubolei/introRL)
* [神经网络与深度学习](https://nndl.github.io/)
* [强化学习基础 David Silver 笔记](https://zhuanlan.zhihu.com/c_135909947)
@@ -393,3 +351,10 @@ A: 整体来说DQN 与 Q-learning 的目标价值以及价值的更新方式