fix ch4 typos

This commit is contained in:
qiwang067
2020-12-21 20:25:41 +08:00
parent 1711322141
commit 79fdd06eca

View File

@@ -21,7 +21,7 @@
![](img/4.2.png)
* 策略一般写成 $\pi$。假设你是用深度学习的技术来做强化学习的话,**策略就是一个网络**。网络里面就有一堆参数, 我们用 $\theta$ 来代表 $\pi$ 的参数。
* 策略一般写成 $\pi$。假设你是用深度学习的技术来做强化学习的话,**策略就是一个网络**。网络里面就有一堆参数,我们用 $\theta$ 来代表 $\pi$ 的参数。
* **网络的输入就是现在机器看到的东西**,如果让机器打电玩的话,机器看到的东西就是游戏的画面。机器看到什么东西,会影响你现在训练到底好不好训练。举例来说,在玩游戏的时候, 也许你觉得游戏的画面前后是相关的,也许你觉得你应该让你的策略,看从游戏初始到现在这个时间点,所有画面的总和。你可能会觉得你要用到 RNN 来处理它,不过这样子会比较难处理。要让你的机器,你的策略看到什么样的画面,这个是你自己决定的。让你知道说给机器看到什么样的游戏画面,可能是比较有效的。
* **输出的就是机器要采取什么样的行为。**
@@ -38,16 +38,16 @@
首先演员会看到一个游戏画面,我们用 $s_1$ 来表示游戏初始的画面。接下来演员看到这个游戏的初始画面以后,根据它内部的网络,根据它内部的策略来决定一个动作。假设它现在决定的动作 是向右,它决定完动作 以后,它就会得到一个奖励,代表它采取这个动作以后得到的分数。
我们把一开始的初始画面记作 $s_1$ 把第一次执行的动作记作 $a_1$,把第一次执行动作完以后得到的奖励记作 $r_1$。不同的书会有不同的定义,有人会觉得说这边应该要叫做 $r_2$,这个都可以,你自己看得懂就好。演员 决定一个行为以后,就会看到一个新的游戏画面,这边是 $s_2$。然后把这个 $s_2$ 输入给演员,这个演员决定要开火,然后它可能杀了一只怪,就得到五分。这个过程就反复地持续下去,直到今天走到某一个时间点执行某一个动作,得到奖励之后, 这个环境决定这个游戏结束了。比如说,如果在这个游戏里面,你是控制绿色的船去杀怪,如果你被杀死的话,游戏就结束,或是你把所有的怪都清空,游戏就结束了。
我们把一开始的初始画面记作 $s_1$ 把第一次执行的动作记作 $a_1$,把第一次执行动作完以后得到的奖励记作 $r_1$。不同的书会有不同的定义,有人会觉得说这边应该要叫做 $r_2$,这个都可以,你自己看得懂就好。演员决定一个行为以后,就会看到一个新的游戏画面,这边是 $s_2$。然后把这个 $s_2$ 输入给演员,这个演员决定要开火,然后它可能杀了一只怪,就得到五分。这个过程就反复地持续下去,直到今天走到某一个时间点执行某一个动作,得到奖励之后,这个环境决定这个游戏结束了。比如说,如果在这个游戏里面,你是控制绿色的船去杀怪,如果你被杀死的话,游戏就结束,或是你把所有的怪都清空,游戏就结束了。
![](img/4.4.png)
* 一场游戏叫做一个 `回合(episode)` 或者 `试验(trial)`
* 把这场游戏里面所有得到的奖励都加起来,就是 `总奖励(total reward)`,我们称其为`回报(return)`,用 R 来表示它。
* 演员 要想办法去最大化它可以得到的奖励。
* 演员要想办法去最大化它可以得到的奖励。
![](img/4.5.png)
首先,`环境` 是一个`函数`,游戏的主机也可以把它看作是一个函数,虽然它不一定是神经网络,可能是基于规则的(rule-based)规则,但你可以把它看作是一个函数。这个函数一开始就先吐出一个状态,也就是游戏的画面,接下来你的演员看到这个游戏画面 $s_1$ 以后,它吐出 $a_1$,然后 环境把 $a_1$ 当作它的输入,然后它再吐出 $s_2$,吐出新的游戏画面。演员看到新的游戏画面,再采取新的行为 $a_2$,然后 环境再看到 $a_2$,再吐出 $s_3$。这个过程会一直持续下去,直到环境觉得说应该要停止为止。
首先,`环境` 是一个`函数`,游戏的主机也可以把它看作是一个函数,虽然它不一定是神经网络,可能是基于规则的(rule-based)规则,但你可以把它看作是一个函数。这个函数一开始就先吐出一个状态,也就是游戏的画面,接下来你的演员看到这个游戏画面 $s_1$ 以后,它吐出 $a_1$,然后环境把 $a_1$ 当作它的输入,然后它再吐出 $s_2$,吐出新的游戏画面。演员看到新的游戏画面,再采取新的行为 $a_2$,然后 环境再看到 $a_2$,再吐出 $s_3$。这个过程会一直持续下去,直到环境觉得说应该要停止为止。
在一场游戏里面,我们把环境输出的 $s$ 跟演员输出的行为 $a$,把 $s$ 跟 $a$ 全部串起来, 叫做一个 `Trajectory(轨迹)`,如下式所示。
$$
@@ -70,7 +70,7 @@ $$
**这个概率取决于两部分**
* 一部分是 `环境的行为` 环境的函数内部的参数或内部的规则长什么样子。 $p(s_{t+1}|s_t,a_t)$这一项代表的是环境, 环境这一项通常你是无法控制它的,因为那个是人家写好的,你不能控制它。
* 一部分是 `环境的行为` 环境的函数内部的参数或内部的规则长什么样子。 $p(s_{t+1}|s_t,a_t)$这一项代表的是环境,环境这一项通常你是无法控制它的,因为那个是人家写好的,你不能控制它。
* 另一部分是 `agent 的行为`。你能控制的是 $p_\theta(a_t|s_t)$。给定一个 $s_t$,演员要采取什么样的 $a_t$ 会取决于演员的参数 $\theta$ 所以这部分是演员可以自己控制的。随着演员的行为不同,每个同样的轨迹, 它就会有不同的出现的概率。
@@ -161,7 +161,7 @@ $$
你就可以把采样到的东西代到这个梯度的式子里面,把梯度算出来。也就是把这边的每一个 s 跟 a 的对拿进来,算一下它的对数概率(log probability)。你计算一下在某一个状态采取某一个动作的对数概率,然后对它取梯度,然后这个梯度前面会乘一个权重,权重就是这场游戏的奖励。 有了这些以后,你就会去更新你的模型。
更新完你的模型以后。你要重新去收集数据,再更新模型。这边要注意一下,一般 `policy gradient(PG) `采样的数据就只会用一次。你把这些数据采样起来,然后拿去更新参数,这些数据就丢掉了。接着再重新采样数据,才能够去更新参数, 等一下我们会解决这个问题。
更新完你的模型以后。你要重新去收集数据,再更新模型。注意,一般 `policy gradient(PG) `采样的数据就只会用一次。你把这些数据采样起来,然后拿去更新参数,这些数据就丢掉了。接着再重新采样数据,才能够去更新参数,等一下我们会解决这个问题。
![](img/4.9.png)
@@ -207,7 +207,7 @@ $$
![1.](img/4.14.png)
为了解决奖励总是正的这个问题,你可以把奖励减掉一项叫做 b这项 b 叫做 baseline。你减掉这项 b 以后,就可以让 $R(\tau^n)-b$ 这一项, 有正有负。 所以如果得到的总奖励 $R(\tau^n)$ 大于 b 的话,就让它的概率上升。如果这个总奖励小于 b就算它是正的正的很小也是不好的你就要让这一项的概率下降。 如果$R(\tau^n)<b$ 你就要让这个状态采取这个动作 的分数下降 。这个 b 怎么设呢?一个最简单的做法就是 你把 $\tau^n$ 的值取期望, 算一下 $\tau^n$的平均值,即:
为了解决奖励总是正的这个问题,你可以把奖励减掉一项叫做 b这项 b 叫做 baseline。你减掉这项 b 以后,就可以让 $R(\tau^n)-b$ 这一项, 有正有负。 所以如果得到的总奖励 $R(\tau^n)$ 大于 b 的话,就让它的概率上升。如果这个总奖励小于 b就算它是正的正的很小也是不好的你就要让这一项的概率下降。 如果$R(\tau^n)<b$ 你就要让这个状态采取这个动作的分数下降 。这个 b 怎么设呢?一个最简单的做法就是你把 $\tau^n$ 的值取期望, 算一下 $\tau^n$ 的平均值,即:
$$
b \approx E[R(\tau)]
$$
@@ -250,7 +250,7 @@ $$
* $\gamma = 0$ : 只关心即时奖励;
* $\gamma = 1$ : 未来奖励等同于即时奖励。
如果时间点 $t'$ 越大,它前面就乘上越多次的 $\gamma$,就代表说现在在某一个状态$s_t$ 执行某一个动作 $a_t$ 的时候,它真正的分数是在执行这个动作之后所有奖励的总和,而且你还要乘上 $\gamma$。
如果时间点 $t'$ 越大,它前面就乘上越多次的 $\gamma$,就代表说现在在某一个状态 $s_t$ 执行某一个动作 $a_t$ 的时候,它真正的分数是在执行这个动作之后所有奖励的总和,而且你还要乘上 $\gamma$。
举一个例子, 你就想成说,这是游戏的第 1、2、3、4 回合,假设你在游戏的第二回合的某一个 $s_t$ 执行 $a_t$ 得到 +1 分,在 $s_{t+1}$ 执行 $a_{t+1}$ 得到 +3 分,在 $s_{t+2}$ 执行 $a_{t+2}$ 得到 -5 分,然后第二回合结束。$a_t$ 的分数应该是:
$$
@@ -260,11 +260,11 @@ $$
![](img/4.19.png)
把 $R-b$ 这一项合起来,我们统称为` advantage function``A` 来代表 advantage function。Advantage function 取决于 s 和 a我们就是要计算的是在某一个状态 s 采取某一个动作 a 的时候,advantage function 有多大。
把 $R-b$ 这一项合起来,我们统称为` 优势函数(advantage function)``A` 来代表优势函数。优势函数取决于 s 和 a我们就是要计算的是在某一个状态 s 采取某一个动作 a 的时候,优势函数有多大。
在算 advantage function 时,你要计算 $\sum_{t^{\prime}=t}^{T_{n}} r_{t^{\prime}}^{n}$ ,你需要有一个互动的结果。你需要有一个模型去跟环境做互动,你才知道接下来得到的奖励会有多少。这个 advantage function 的上标是 $\theta$$\theta$ 就是代表说是用 $\theta$ 这个模型跟环境去做互动,然后你才计算出这一项。从时间 t 开始到游戏结束为止,所有 r 的加和减掉 b这个就叫 advantage function
在算优势函数时,你要计算 $\sum_{t^{\prime}=t}^{T_{n}} r_{t^{\prime}}^{n}$ ,你需要有一个互动的结果。你需要有一个模型去跟环境做互动,你才知道接下来得到的奖励会有多少。优势函数 $A^{\theta}\left(s_{t}, a_{t}\right)$ 的上标是 $\theta$$\theta$ 就是代表说是用 $\theta$ 这个模型跟环境去做互动,然后你才计算出这一项。从时间 t 开始到游戏结束为止,所有 r 的加和减掉 b这个就叫优势函数
Advantage function 的意义就是,假设我们在某一个状态$s_t$ 执行某一个动作 $a_t$,相较于其他可能的动作,它有多好。它在意的不是一个绝对的好,而是相对的好,即`相对优势(relative advantage)`。因为会减掉一个 b减掉一个 baseline 所以这个东西是相对的好,不是绝对的好。 $A^{\theta}\left(s_{t}, a_{t}\right)$ 通常可以是由一个网络估计出来的,这个网络叫做 critic。
优势函数的意义就是,假设我们在某一个状态$s_t$ 执行某一个动作 $a_t$,相较于其他可能的动作,它有多好。它在意的不是一个绝对的好,而是相对的好,即`相对优势(relative advantage)`。因为会减掉一个 b减掉一个 baseline 所以这个东西是相对的好,不是绝对的好。 $A^{\theta}\left(s_{t}, a_{t}\right)$ 通常可以是由一个网络估计出来的,这个网络叫做 critic。
## REINFORCE: Monte Carlo Policy Gradient
@@ -310,6 +310,9 @@ REINFORCE 的伪代码主要看最后四行,先产生一个回合的数据,
![](img/4.26.png)
* 类似地policy gradient 预测每一个状态下面应该要输出的这个行动的概率,就是输入状态 $s_t$,然后输出动作的概率,比如 0.020.080.09。实际上输出给环境的动作是随机选了一个动作,比如说我选了右这个动作,它的 one-hot 向量就是 001。
> 独热编码(one-hot Encoding)通常用于处理类别间不具有大小关系的特征。 例如血型一共有4个取值A型、B型、AB型、O型独热编码会把血型变成一个4维稀疏向量A型血表示为1,0,0,0B型血表示为0,1,0,0AB型会表示为0,0,1,0O型血表示为0,0,0,1
* 我们把神经网络的输出和实际动作带入交叉熵的公式就可以求出输出的概率和实际的动作之间的差距。
* 但这个实际的动作 $a_t$ 只是我们输出的真实的动作,它并不一定是正确的动作,它不能像手写数字识别一样作为一个正确的标签来去指导神经网络朝着正确的方向去更新,所以我们需要乘以一个奖励回报 $G_t$。这个奖励回报相当于是对这个真实动作 的评价。
* 如果 $G_t$ 越大,未来总收益越大,那就说明当前输出的这个真实的动作就越好,这个 loss 就越需要重视。
@@ -322,7 +325,7 @@ REINFORCE 的伪代码主要看最后四行,先产生一个回合的数据,
![](img/4.28.png)
上图是 REINFORCE 的流程图。首先我们需要一个 policy model 来输出动作概率,输出动作概率后,我们 sample() 函数去得到一个具体的动作,然后跟环境交互过后,我们可以得到一整个回合的数据。拿到回合数据之后,我再去执行一下 learn() 函数,在 learn() 函数里面,我就可以拿这些数据去构造损失函数,扔给这个优化器去优化,去更新我的 policy model。
上图是 REINFORCE 的流程图。首先我们需要一个 policy model 来输出动作概率,输出动作概率后,我们 `sample()` 函数去得到一个具体的动作,然后跟环境交互过后,我们可以得到一整个回合的数据。拿到回合数据之后,我再去执行一下 `learn()` 函数,在 `learn()` 函数里面,我就可以拿这些数据去构造损失函数,扔给这个优化器去优化,去更新我的 policy model。
## References