fix ch4 typos

This commit is contained in:
qiwang067
2020-12-20 19:50:45 +08:00
parent a875f35760
commit 1711322141

View File

@@ -17,7 +17,7 @@
* 环境就是对手;
* 奖励函数就是按照围棋的规则, 赢就是得一分,输就是负一分等等。
在强化学习里面,环境跟奖励函数不是你可以控制的,环境跟奖励函数是在开始学习之前,就已经事先给定的。你唯一能做的事情是调整 演员里面的策略(policy),使得 演员可以得到最大的奖励。演员里面会有一个策略, 这个策略决定了演员的行为。策略就是给一个外界的输入,然后它会输出演员现在应该要执行的行为。
在强化学习里面,环境跟奖励函数不是你可以控制的,环境跟奖励函数是在开始学习之前,就已经事先给定的。你唯一能做的事情是调整演员里面的策略(policy),使得 演员可以得到最大的奖励。演员里面会有一个策略, 这个策略决定了演员的行为。策略就是给一个外界的输入,然后它会输出演员现在应该要执行的行为。
![](img/4.2.png)
@@ -38,7 +38,7 @@
首先演员会看到一个游戏画面,我们用 $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)
@@ -49,12 +49,12 @@
![](img/4.5.png)
首先,`环境` 是一个`函数`,游戏的主机也可以把它看作是一个函数,虽然它不一定是神经网络,可能是基于规则的(rule-based)规则,但你可以把它看作是一个函数。这个函数,一开始就先吐出一个状态,也就是游戏的画面,接下来你的演员看到这个游戏画面 $s_1$ 以后,它吐出 $a_1$,然后 环境把 $a_1$ 当作它的输入,然后它再吐出 $s_2$,吐出新的游戏画面。演员看到新的游戏画面,再采取新的行为 $a_2$,然后 环境再看到 $a_2$,再吐出 $s_3$。这个过程会一直持续下去,直到环境觉得说应该要停止为止。
在一场游戏里面,我们把环境输出的 $s$ 跟演员输出的行为 $a$,把这个 $s$ 跟 $a$ 全部串起来, 叫做一个 `Trajectory(轨迹)`,如下式所示。
在一场游戏里面,我们把环境输出的 $s$ 跟演员输出的行为 $a$,把 $s$ 跟 $a$ 全部串起来, 叫做一个 `Trajectory(轨迹)`,如下式所示。
$$
\text { Trajectory } \tau=\left\{s_{1}, a_{1}, s_{2}, a_{2}, \cdots, s_{t}, a_{t}\right\}
$$
每一个轨迹,你可以计算它发生的概率。假设现在演员的参数已经被给定了话,就是 $\theta$。根据 $\theta$,你其实可以计算某一个轨迹 发生的概率,你可以计算某一个回合,某一个回合里面, 发生这样子状况的概率。
你可以计算每一个轨迹发生的概率。假设现在演员的参数已经被给定了话,就是 $\theta$。根据 $\theta$,你其实可以计算某一个轨迹发生的概率,你可以计算某一个回合里面发生这样子状况的概率。
$$
\begin{aligned}
@@ -64,14 +64,14 @@ p_{\theta}(\tau)
\end{aligned}
$$
怎么算呢,如上式所示。在假设演员的参数就是 $\theta$ 的情况下,某一个轨迹 $\tau$ 的概率就是这样算的,你先算 环境输出 $s_1$ 的概率,再计算根据 $s_1$ 执行 $a_1$ 的概率,这是由你策略里面的网络参数 $\theta$ 所决定的, 它是一个概率,因为你的策略的网络的输出是一个分布,演员是根据这个分布去做采样,决定现在实际上要采取的动作是哪一个。接下来环境根据 $a_1$ 跟 $s_1$ 产生 $s_2$,因为 $s_2$ 跟$s_1$ 还是有关系的,下一个游戏画面跟前一个游戏画面通常还是有关系的,至少要是连续的, 所以给定前一个游戏画面 $s_1$ 和现在演员采取的行为 $a_1$,就会产生 $s_2$。
怎么算呢,如上式所示。在假设演员的参数就是 $\theta$ 的情况下,某一个轨迹 $\tau$ 的概率就是这样算的,你先算环境输出 $s_1$ 的概率,再计算根据 $s_1$ 执行 $a_1$ 的概率,这是由你策略里面的网络参数 $\theta$ 所决定的, 它是一个概率,因为你的策略的网络的输出是一个分布,演员是根据这个分布去做采样,决定现在实际上要采取的动作是哪一个。接下来环境根据 $a_1$ 跟 $s_1$ 产生 $s_2$,因为 $s_2$ 跟 $s_1$ 还是有关系的,下一个游戏画面跟前一个游戏画面通常还是有关系的,至少要是连续的, 所以给定前一个游戏画面 $s_1$ 和现在演员采取的行为 $a_1$,就会产生 $s_2$。
这件事情可能是概率,也可能不是概率,这个取决于环境,就是主机它内部设定是怎样。看今天这个主机在决定,要输出什么样的游戏画面的时候,有没有概率。因为如果没有概率的话,这个游戏的每次的行为都一样,你只要找到一条路径就可以过关了,这样感觉是蛮无聊的 。所以游戏里面通常还是有一些概率的,你做同样的行为,给同样的前一个画面, 下次产生的画面不见得是一样的。过程就反复继续下去,你就可以计算一个轨迹 $s_1$,$a_1$, $s_2$ , $a_2$ 出现的概率有多大。
**这个概率取决于两部分**
* 一部分是 `环境的行为` 环境的函数内部的参数或内部的规则长什么样子。 $p(s_{t+1}|s_t,a_t)$这一项代表的是环境, 环境这一项通常你是无法控制它的,因为那个是人家写好的,你不能控制它。
* 另一部分是 `agent 的行为`。你能控制的是 $p_\theta(a_t|s_t)$。给定一个 $s_t$,演员要采取什么样的 $a_t$ 会取决于演员的参数 $\theta$ 所以这部分是演员可以自己控制的。随着演员的行为不同,每个同样的轨迹, 它就会有不同的出现的概率。
* 另一部分是 `agent 的行为`。你能控制的是 $p_\theta(a_t|s_t)$。给定一个 $s_t$,演员要采取什么样的 $a_t$ 会取决于演员的参数 $\theta$ 所以这部分是演员可以自己控制的。随着演员的行为不同,每个同样的轨迹, 它就会有不同的出现的概率。
![](img/4.6.png)
@@ -80,11 +80,18 @@ $$
奖励函数根据在某一个状态采取的某一个动作决定说现在这个行为可以得到多少的分数。 它是一个函数,给它 $s_1$$a_1$,它告诉你得到 $r_1$。给它 $s_2$ $a_2$,它告诉你得到 $r_2$。 把所有的 $r$ 都加起来,我们就得到了 $R(\tau)$ ,代表某一个轨迹 $\tau$ 的奖励。
在某一场游戏里面, 某一个回合里面,我们会得到 R。**我们要做的事情就是调整演员内部的参数 $\theta$ 使得 R 的值越大越好。** 但实际上奖励并不只是一个标量奖励其实是一个随机变量。R 其实是一个随机变量,因为演员在给定同样的状态会做什么样的行为,这件事情是有随机性的。环境在给定同样的观测要采取什么样的动作,要产生什么样的观测,本身也是有随机性的所以 R 是一个随机变量你能够计算的,是它的期望值。你能够计算的是说,在给定某一组参数 $\theta$ 的情况下,我们会得到的 R 的期望值是多少。
在某一场游戏里面, 某一个回合里面,我们会得到 R。**我们要做的事情就是调整演员内部的参数 $\theta$ 使得 R 的值越大越好。** 但实际上奖励并不只是一个标量奖励其实是一个随机变量。R 其实是一个随机变量,因为演员在给定同样的状态会做什么样的行为,这件事情是有随机性的。环境在给定同样的观测要采取什么样的动作,要产生什么样的观测,本身也是有随机性的所以 R 是一个随机变量你能够计算的是 R 的期望值。你能够计算的是说,在给定某一组参数 $\theta$ 的情况下,我们会得到的 $R_{\theta}$ 的期望值是多少。
$$
\bar{R}_{\theta}=\sum_{\tau} R(\tau) p_{\theta}(\tau)
$$
这个期望值的算法如上式所示穷举所有可能的轨迹 $\tau$ 每一个轨迹 $\tau$ 都有一个概率。比如 $\theta$ 是一个很强的模型, 那它都不会死。如果有一个回合很快就死掉了, 它的概率就很小;如果有一个回合都一直没有死, 那它的概率就很大。根据你的 $\theta$ 你可以算出某一个轨迹 $\tau$ 出现的概率,接下来你计算这个 $\tau$ 的总奖励是多少。总奖励使用这个 $\tau$ 出现的概率进行加权,对所有的 $\tau$ 进行求和,就是期望值。给定一个参数,你会得到的期望值。
这个期望值的算法如上式所示。我们要穷举所有可能的轨迹 $\tau$ 每一个轨迹 $\tau$ 都有一个概率。
比如 $\theta$ 是一个很强的模型,它都不会死。因为 $\theta$ 很强,所以:
* 如果有一个回合 $\theta$ 很快就死掉了,因为这种情况很少会发生,所以该回合对应的轨迹 $\tau$ 的概率就很小;
* 如果有一个回合 $\theta$ 都一直没有死,因为这种情况很可能发生,所以该回合对应的轨迹 $\tau$ 的概率就很大。
你可以根据 $\theta$ 算出某一个轨迹 $\tau$ 出现的概率,接下来计算这个 $\tau$ 的总奖励是多少。总奖励使用这个 $\tau$ 出现的概率进行加权,对所有的 $\tau$ 进行求和,就是期望值。给定一个参数,你会得到的期望值。
$$
\bar{R}_{\theta}=\sum_{\tau} R(\tau) p_{\theta}(\tau)=E_{\tau \sim p_{\theta}(\tau)}[R(\tau)]
$$
@@ -120,10 +127,21 @@ E_{\tau \sim p_{\theta}(\tau)}\left[R(\tau) \nabla \log p_{\theta}(\tau)\right]
&=\frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}} R\left(\tau^{n}\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right)
\end{aligned}
$$
注意 $p_{\theta}(\tau)$ 里面有两项,$p(s_{t+1}|s_t,a_t)$ 来自于环境,$p_\theta(a_t|s_t)$ 是来自于 agent。 $p(s_{t+1}|s_t,a_t)$ 由环境决定,所以与 $\theta$ 无关,因此 $\nabla \log p(s_{t+1}|s_t,a_t) =0 $。因此 $\nabla p_{\theta}(\tau)=
\nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)$。
下面给出 $\nabla \log p_{\theta}(\tau)$ 的具体计算过程。
$$
\nabla \log p_{\theta}(\tau) = \nabla \left(\log p(s_1)+\sum_{t=1}^{T}\log p_{\theta}(a_t|s_t)+ \sum_{t=1}^{T}\log p(s_{t+1}|s_t,a_t) \right)
$$
你可以非常直观的来理解这个部分,也就是在你采样到的数据里面, 你采样到,在某一个状态 $s_t$ 要执行某一个动作 $a_t$ 这个 $s_t$ $a_t$ 它是在整个轨迹 $\tau$ 的里面的某一个状态和动作的对。
注意 $p(s_1)$ 和 $p(s_{t+1}|s_t,a_t)$ 来自于环境,$p_\theta(a_t|s_t)$ 是来自于 agent。$p(s_1)$ $p(s_{t+1}|s_t,a_t)$ 由环境决定,所以与 $\theta$ 无关,因此 $\nabla \log p(s_1)=0$ $\nabla \sum_{t=1}^{T}\log p(s_{t+1}|s_t,a_t)=0$,所以:
$$
\begin{aligned}
\nabla \log p_{\theta}(\tau) &= \nabla \left(\log p(s_1)+\sum_{t=1}^{T}\log p_{\theta}(a_t|s_t)+ \sum_{t=1}^{T}\log p(s_{t+1}|s_t,a_t) \right) \\
&= \nabla \log p(s_1)+ \nabla \sum_{t=1}^{T}\log p_{\theta}(a_t|s_t)+ \nabla \sum_{t=1}^{T}\log p(s_{t+1}|s_t,a_t) \\
&=\nabla \sum_{t=1}^{T}\log p_{\theta}(a_t|s_t)\\
&=\sum_{t=1}^{T} \nabla\log p_{\theta}(a_t|s_t)
\end{aligned}
$$
你可以非常直观的来理解这个部分,也就是在你采样到的数据里面, 你采样到在某一个状态 $s_t$ 要执行某一个动作 $a_t$ 这个 $s_t$ 跟 $a_t$ 它是在整个轨迹 $\tau$ 的里面的某一个状态和动作的对。
* 假设你在 $s_t$ 执行 $a_t$,最后发现 $\tau$ 的奖励是正的, 那你就要增加这一项的概率,你就要增加在 $s_t$ 执行 $a_t$ 的概率。
* 反之,在 $s_t$ 执行 $a_t$ 会导致 $\tau$ 的奖励变成负的, 你就要减少这一项的概率。
@@ -133,8 +151,7 @@ $$
![](img/4.8.png)
这个怎么实现呢? 你用梯度上升来更新你的参数,你原来有一个参数 $\theta$ ,把你的 $\theta$ 加上你的梯度这一项,那当然前面要有个学习率,学习率也是要调整的,你可用 Adam、RMSProp 等方法对其进行调整。
我们可以套下面这个公式来把梯度计算出来:
我们可以套下面这个公式来把梯度计算出来:
$$
\nabla \bar{R}_{\theta}=\frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}} R\left(\tau^{n}\right) \nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)
$$
@@ -163,7 +180,6 @@ $$
$$
\frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}} \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right)
$$
像这种损失函数,你可在 TensorFlow 里调用现成的函数它就会自动帮你算然后你就可以把梯度计算出来。这是一般的分类问题RL 唯一不同的地方是 loss 前面乘上一个权重:整场游戏得到的总奖励 R它并不是在状态 s 采取动作 a 的时候得到的奖励,如下式所示:
$$
\frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}} R\left(\tau^{n}\right) \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right)
@@ -195,7 +211,6 @@ $$
$$
b \approx E[R(\tau)]
$$
这是其中一种做法, 你可以想想看有没有其它的做法。
所以在实现训练的时候,你会不断地把 $R(\tau)$ 的分数记录下来 然后你会不断地去计算 $R(\tau)$ 的平均值, 你会把这个平均值,当作你的 b 来用。 这样就可以让你在训练的时候, $\nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)$ 乘上前面这一项, 是有正有负的,这个是第一个 tip。