fix ch4 typos
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
|
||||
* 策略一般写成 $\pi$。假设你是用深度学习的技术来做强化学习的话,**策略就是一个网络**。网络里面就有一堆参数, 我们用 $\theta$ 来代表 $\pi$ 的参数。
|
||||
|
||||
* **网络的输入就是现在机器看到的东西**,如果让机器打电玩的话,机器看到的东西就是游戏的画面。机器看到什么东西,会影响你现在训练到底好不好训练。举例来说,在玩游戏的时候, 也许你觉得游戏的画面,前后是相关的,也许你觉得说,你应该让你的策略,看从游戏初始到现在这个时间点,所有画面的总和。你可能会觉得你要用到 RNN 来处理它,不过这样子会比较难处理。要让你的机器,你的策略 看到什么样的画面, 这个是你自己决定的。让你知道说给机器看到什么样的游戏画面,可能是比较有效的。
|
||||
* **网络的输入就是现在机器看到的东西**,如果让机器打电玩的话,机器看到的东西就是游戏的画面。机器看到什么东西,会影响你现在训练到底好不好训练。举例来说,在玩游戏的时候, 也许你觉得游戏的画面前后是相关的,也许你觉得你应该让你的策略,看从游戏初始到现在这个时间点,所有画面的总和。你可能会觉得你要用到 RNN 来处理它,不过这样子会比较难处理。要让你的机器,你的策略看到什么样的画面,这个是你自己决定的。让你知道说给机器看到什么样的游戏画面,可能是比较有效的。
|
||||
* **输出的就是机器要采取什么样的行为。**
|
||||
|
||||
* 上图就是具体的例子,
|
||||
@@ -31,7 +31,7 @@
|
||||
* 输入 就是游戏的画面,它通常是由像素(pixels)所组成的;
|
||||
* 输出就是看看说有哪些选项是你可以去执行的,输出层就有几个神经元。
|
||||
* 假设你现在可以做的行为有 3 个,输出层就是有 3 个神经元。每个神经元对应到一个可以采取的行为。
|
||||
* 输入一个东西后,网络就会给每一个可以采取的行为一个分数。你可以把这个分数当作是概率。演员就是看这个概率的分布,根据这个概率的分布来决定它要采取的行为。比如说 70% 会走 left,20% 走 right,10% 开火等等。概率分布不同,演员采取的行为就会不一样。
|
||||
* 输入一个东西后,网络就会给每一个可以采取的行为一个分数。你可以把这个分数当作是概率。演员就是看这个概率的分布,根据这个概率的分布来决定它要采取的行为。比如说 70% 会向左走,20% 向右走,10% 开火等等。概率分布不同,演员采取的行为就会不一样。
|
||||
|
||||

|
||||
**接下来用一个例子来说明演员是怎么样跟环境互动的。**
|
||||
@@ -47,9 +47,9 @@
|
||||
* 演员 要想办法去最大化它可以得到的奖励。
|
||||
|
||||

|
||||
首先,`环境` 是一个`函数`,游戏的主机也可以把它看作是一个函数,虽然它不一定是神经网络,可能是基于规则的(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(轨迹)`,如下式所示。
|
||||
在一场游戏里面,我们把环境输出的 $s$ 跟演员输出的行为 $a$,把这个 $s$ 跟 $a$ 全部串起来, 叫做一个 `Trajectory(轨迹)`,如下式所示。
|
||||
$$
|
||||
\text { Trajectory } \tau=\left\{s_{1}, a_{1}, s_{2}, a_{2}, \cdots, s_{t}, a_{t}\right\}
|
||||
$$
|
||||
@@ -66,19 +66,19 @@ $$
|
||||
|
||||
怎么算呢,如上式所示。在假设演员的参数就是 $\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$ 出现的概率有多大。
|
||||
这件事情可能是概率,也可能不是概率,这个取决于环境,就是主机它内部设定是怎样。看今天这个主机在决定,要输出什么样的游戏画面的时候,有没有概率。因为如果没有概率的话,这个游戏的每次的行为都一样,你只要找到一条路径就可以过关了,这样感觉是蛮无聊的 。所以游戏里面通常还是有一些概率的,你做同样的行为,给同样的前一个画面, 下次产生的画面不见得是一样的。过程就反复继续下去,你就可以计算一个轨迹 $s_1$,$a_1$, $s_2$ , $a_2$ 出现的概率有多大。
|
||||
|
||||
**这个概率取决于两部分**,
|
||||
|
||||
* 一部分是 `环境的行为`, 环境的函数 它内部的参数或内部的规则长什么样子。 $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$, 所以这部分是演员可以自己控制的。随着演员的行为不同,每个同样的轨迹, 它就会有不同的出现的概率。
|
||||
|
||||
|
||||

|
||||
|
||||
在强化学习里面,除了 环境跟演员以外, 还有`奖励函数(reward function)`。
|
||||
在强化学习里面,除了环境跟演员以外, 还有`奖励函数(reward function)`。
|
||||
|
||||
奖励函数根据在某一个状态采取的某一个动作 决定说现在这个行为可以得到多少的分数。 它是一个函数,给它 $s_1$,$a_1$,它告诉你得到 $r_1$。给它 $s_2$ ,$a_2$,它告诉你得到 $r_2$。 把所有的 $r$ 都加起来,我们就得到了 $R(\tau)$ ,代表某一个轨迹 $\tau$ 的奖励。
|
||||
奖励函数根据在某一个状态采取的某一个动作决定说现在这个行为可以得到多少的分数。 它是一个函数,给它 $s_1$,$a_1$,它告诉你得到 $r_1$。给它 $s_2$ ,$a_2$,它告诉你得到 $r_2$。 把所有的 $r$ 都加起来,我们就得到了 $R(\tau)$ ,代表某一个轨迹 $\tau$ 的奖励。
|
||||
|
||||
在某一场游戏里面, 某一个回合里面,我们会得到 R。**我们要做的事情就是调整演员内部的参数 $\theta$, 使得 R 的值越大越好。** 但实际上奖励并不只是一个标量,奖励其实是一个随机变量。R 其实是一个随机变量,因为演员在给定同样的状态会做什么样的行为,这件事情是有随机性的。环境在给定同样的观测要采取什么样的动作,要产生什么样的观测,本身也是有随机性的。所以 R 是一个随机变量,你能够计算的,是它的期望值。你能够计算的是说,在给定某一组参数 $\theta$ 的情况下,我们会得到的 R 的期望值是多少。
|
||||
$$
|
||||
@@ -91,7 +91,7 @@ $$
|
||||
我们还可以写成上式那样,从 $p_{\theta}(\tau)$ 这个分布采样一个轨迹 $\tau$,然后计算 $R(\tau)$ 的期望值,就是你的期望的奖励。 我们要做的事情就是最大化期望奖励。
|
||||
|
||||

|
||||
怎么最大化期望奖励呢?我们用的是 `梯度上升(gradient ascent)`,因为要让它越大越好,所以是梯度上升。梯度上升在更新参数的时候要加。要进行梯度上升,我们先要计算期望的奖励(expected reward) $\bar{R}$ 的梯度。我们对 $\bar{R}$ 取一个梯度,这里面只有 $p_{\theta}(\tau)$ 是跟 $\theta$ 有关,所以梯度就放在 $p_{\theta}(\tau)$ 这个地方。$R(\tau)$ 这个奖励函数 不需要是 differentiable,我们也可以解接下来的问题。举例来说,如果是在 GAN 里面,$R(\tau)$ 其实是一个 discriminator,它就算是没有办法微分,也无所谓,你还是可以做接下来的运算。
|
||||
怎么最大化期望奖励呢?我们用的是 `梯度上升(gradient ascent)`,因为要让它越大越好,所以是梯度上升。梯度上升在更新参数的时候要加。要进行梯度上升,我们先要计算期望的奖励(expected reward) $\bar{R}$ 的梯度。我们对 $\bar{R}$ 取一个梯度,这里面只有 $p_{\theta}(\tau)$ 是跟 $\theta$ 有关,所以梯度就放在 $p_{\theta}(\tau)$ 这个地方。$R(\tau)$ 这个奖励函数不需要是可微分的(differentiable),这个不影响我们解接下来的问题。举例来说,如果是在 GAN 里面,$R(\tau)$ 其实是一个 discriminator,它就算是没有办法微分,也无所谓,你还是可以做接下来的运算。
|
||||
|
||||
取梯度之后,我们背一个公式:
|
||||
$$
|
||||
@@ -104,7 +104,7 @@ $$
|
||||
\frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)}=\log p_{\theta}(\tau)
|
||||
$$
|
||||
|
||||
然后如下式所示, 对 $\tau$ 进行求和,把 $R(\tau)$ 和 $\log p_{\theta}(\tau)$ 这两项使用 $p_{\theta}(\tau)$ 进行加权, 既然使用 $p_{\theta}(\tau)$ 进行加权 ,它们就可以被写成这个期望的形式。也就是你从 $p_{\theta}(\tau)$ 这个分布里面采样 $\tau$ 出来, 去计算 $R(\tau)$ 乘上 $\nabla\log p_{\theta}(\tau)$,然后把它对所有可能的 $\tau$ 进行求和,就是这个期望的值(expected value)。
|
||||
如下式所示,对 $\tau$ 进行求和,把 $R(\tau)$ 和 $\log p_{\theta}(\tau)$ 这两项使用 $p_{\theta}(\tau)$ 进行加权, 既然使用 $p_{\theta}(\tau)$ 进行加权 ,它们就可以被写成期望的形式。也就是你从 $p_{\theta}(\tau)$ 这个分布里面采样 $\tau$ 出来, 去计算 $R(\tau)$ 乘上 $\nabla\log p_{\theta}(\tau)$,然后把它对所有可能的 $\tau$ 进行求和,就是这个期望的值(expected value)。
|
||||
$$
|
||||
\begin{aligned}
|
||||
\nabla \bar{R}_{\theta}&=\sum_{\tau} R(\tau) \nabla p_{\theta}(\tau)\\&=\sum_{\tau} R(\tau) p_{\theta}(\tau) \frac{\nabla p_{\theta}(\tau)}{p_{\theta}(\tau)} \\&=
|
||||
@@ -113,14 +113,14 @@ $$
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
实际上这个期望值没有办法算,所以你是用采样的方式来采样一大堆的 $\tau$。你采样 $N$ 笔 $\tau$, 然后你去计算每一笔的这些值,然后把它全部加起来,就可以得到你的梯度。你就可以去更新你的参数,你就可以去更新你的 agent,如下式所示。
|
||||
实际上这个期望值没有办法算,所以你是用采样的方式来采样一大堆的 $\tau$。你采样 $N$ 笔 $\tau$, 然后你去计算每一笔的这些值,然后把它全部加起来,就可以得到你的梯度。你就可以去更新你的参数,你就可以去更新你的 agent,如下式所示:
|
||||
$$
|
||||
\begin{aligned}
|
||||
E_{\tau \sim p_{\theta}(\tau)}\left[R(\tau) \nabla \log p_{\theta}(\tau)\right] &\approx \frac{1}{N} \sum_{n=1}^{N} R\left(\tau^{n}\right) \nabla \log p_{\theta}\left(\tau^{n}\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)=
|
||||
注意 $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)$。
|
||||
|
||||
你可以非常直观的来理解这个部分,也就是在你采样到的数据里面, 你采样到,在某一个状态 $s_t$ 要执行某一个动作 $a_t$, 这个 $s_t$ 跟 $a_t$ 它是在整个轨迹 $\tau$ 的里面的某一个状态和动作的对。
|
||||
@@ -138,9 +138,9 @@ $$
|
||||
$$
|
||||
\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)
|
||||
$$
|
||||
实际上,要套上面这个公式, 首先你要先收集一大堆的 s 跟 a 的对,你还要知道这些 s 跟 a 在跟环境互动的时候,你会得到多少的奖励。 这些资料怎么收集呢?你要拿你的 agent,它的参数是 $\theta$,去跟环境做互动, 也就是拿你已经训练好的 agent 先去跟环境玩一下,先去跟那个游戏互动一下, 互动完以后,你就会得到一大堆游戏的纪录,你会记录说,今天先玩了第一场,在第一场游戏里面,我们在状态 $s_1$ 采取动作 $a_1$,在状态$s_2$ 采取动作 $a_2$ 。
|
||||
实际上,要套上面这个公式, 首先你要先收集一大堆的 s 跟 a 的对(pair),你还要知道这些 s 跟 a 在跟环境互动的时候,你会得到多少的奖励。 这些资料怎么收集呢?你要拿你的 agent,它的参数是 $\theta$,去跟环境做互动, 也就是拿你已经训练好的 agent 先去跟环境玩一下,先去跟那个游戏互动一下, 互动完以后,你就会得到一大堆游戏的纪录,你会记录说,今天先玩了第一场,在第一场游戏里面,我们在状态 $s_1$ 采取动作 $a_1$,在状态$s_2$ 采取动作 $a_2$ 。
|
||||
|
||||
玩游戏的时候是有随机性的,所以 agent 本身是有随机性的,在同样状态$s_1$,不是每次都会采取 $a_1$,所以你要记录下来。在状态$s_1^1$ 采取 $a_1^1$,在状态$s_2^1$ 采取 $a_2^1$。整场游戏结束以后,得到的分数是 $R(\tau^1)$。你会采样到另外一笔数据,也就是另外一场游戏。在另外一场游戏里面,你在状态$s_1^2$ 采取 $a_1^2$,在状态 $s_2^2$ 采取 $a_2^2$,然后你采样到的就是 $\tau^2$,得到的奖励是 $R(\tau^2)$。
|
||||
玩游戏的时候是有随机性的,所以 agent 本身是有随机性的,在同样状态$s_1$,不是每次都会采取 $a_1$,所以你要记录下来。在状态 $s_1^1$ 采取 $a_1^1$,在状态 $s_2^1$ 采取 $a_2^1$。整场游戏结束以后,得到的分数是 $R(\tau^1)$。你会采样到另外一笔数据,也就是另外一场游戏。在另外一场游戏里面,你在状态 $s_1^2$ 采取 $a_1^2$,在状态 $s_2^2$ 采取 $a_2^2$,然后你采样到的就是 $\tau^2$,得到的奖励是 $R(\tau^2)$。
|
||||
|
||||
你就可以把采样到的东西代到这个梯度的式子里面,把梯度算出来。也就是把这边的每一个 s 跟 a 的对拿进来,算一下它的对数概率(log probability)。你计算一下在某一个状态采取某一个动作的对数概率,然后对它取梯度,然后这个梯度前面会乘一个权重,权重就是这场游戏的奖励。 有了这些以后,你就会去更新你的模型。
|
||||
|
||||
@@ -150,7 +150,7 @@ $$
|
||||
|
||||
**接下来讲一些实现细节。**
|
||||
|
||||
我们可以把它想成一个分类的问题,在分类里面就是输入一个图像,然后输出决定说是 10 个类里面的哪一个。在做分类时,我们要收集一堆训练数据,要有输入跟输出的对(pair)。
|
||||
我们可以把它想成一个分类的问题,在分类里面就是输入一个图像,然后输出决定说是 10 个类里面的哪一个。在做分类时,我们要收集一堆训练数据,要有输入跟输出的对。
|
||||
|
||||
在实现的时候,你就把状态当作是分类器的输入。 你就当在做图像分类的问题,只是现在的类不是说图像里面有什么东西。 现在的类是说,看到这张图像我们要采取什么样的行为,每一个行为就是一个类。比如说第一个类叫做向左,第二个类叫做向右,第三个类叫做开火。
|
||||
|
||||
@@ -164,7 +164,11 @@ $$
|
||||
\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 的时候得到的奖励。 你要把你的每一笔训练数据,都使用这个 R 进行加权。然后你用 TensorFlow 或 PyTorch 去帮你算梯度就结束了,跟一般分类差不多。
|
||||
像这种损失函数,你可在 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)
|
||||
$$
|
||||
你要把你的每一笔训练数据,都使用这个 R 进行加权。然后你用 TensorFlow 或 PyTorch 去帮你算梯度就结束了,跟一般分类差不多。
|
||||
|
||||
## Tips
|
||||
这边有一些在实现的时候,你也许用得上的 tip。
|
||||
@@ -183,11 +187,11 @@ $$
|
||||

|
||||
|
||||
|
||||
这是一个理想上的状况,但是实际上,我们是在做采样就本来这边应该是一个期望(expectation),对所有可能的 s 跟 a 的对进行求和。 但你真正在学的时候,当然不可能是这么做的,你只是采样了少量的 s 跟 a 的对而已。 因为我们做的是采样,有一些动作 可能从来都没有采样到。在某一个状态1,虽然可以执行的动作 有 a/b/c 3 个,但你可能只采样到动作 b,你可能只采样到动作 c,你没有采样到动作 a。但现在所有动作 的奖励都是正的,所以根据这个式子,它的每一项的概率都应该要上升。你会遇到的问题是,因为 a 没有被采样到,其它动作 的概率如果都要上升,a 的概率就下降。 所以 a 不一定是一个不好的动作, 它只是没被采样到。但只是因为它没被采样到, 它的概率就会下降,这个显然是有问题的,要怎么解决这个问题呢?你会希望你的奖励不要总是正的。
|
||||
这是一个理想上的状况,但是实际上,我们是在做采样就本来这边应该是一个期望(expectation),对所有可能的 s 跟 a 的对进行求和。 但你真正在学的时候,当然不可能是这么做的,你只是采样了少量的 s 跟 a 的对而已。 因为我们做的是采样,有一些动作 可能从来都没有采样到。在某一个状态,虽然可以执行的动作 有 a/b/c 3 个,但你可能只采样到动作 b,你可能只采样到动作 c,你没有采样到动作 a。但现在所有动作的奖励都是正的,所以根据这个式子,它的每一项的概率都应该要上升。你会遇到的问题是,因为 a 没有被采样到,其它动作 的概率如果都要上升,a 的概率就下降。 所以 a 不一定是一个不好的动作, 它只是没被采样到。但只是因为它没被采样到, 它的概率就会下降,这个显然是有问题的,要怎么解决这个问题呢?你会希望你的奖励不要总是正的。
|
||||
|
||||

|
||||
|
||||
为了解决奖励总是正的这个问题,你可以把奖励减掉一项叫做 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)]
|
||||
$$
|
||||
@@ -199,43 +203,49 @@ $$
|
||||
|
||||
### Tip 2: Assign Suitable Credit
|
||||
|
||||
**第二个 tip:给每一个动作合适的 credit。**什么意思呢,如果我们看今天下面这个式子的话,
|
||||
**第二个 tip:给每一个动作合适的分数(credit)。**
|
||||
|
||||
如果我们看下面这个式子的话,
|
||||
$$
|
||||
\nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}}\left(R\left(\tau^{n}\right)-b\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right)
|
||||
$$
|
||||
我们原来会做的事情是,在某一个状态,假设你执行了某一个动作 a,它得到的奖励,它前面乘上的这一项 $R(\tau^n)-b$。
|
||||
|
||||
只要在同一个回合里面,在同一场游戏里面, 所有的状态跟动作的对,它都会使用同样的奖励项(term)进行加权,这件事情显然是不公平的,因为在同一场游戏里面 也许有些动作是好的,有些动作是不好的。 假设整场游戏的结果是好的, 并不代表这个游戏里面每一个行为都是对的。若是整场游戏结果不好, 但不代表游戏里面的所有行为都是错的。所以我们希望可以给每一个不同的动作前面都乘上不同的权重。每一个动作的不同权重, 它反映了每一个动作到底是好还是不好。
|
||||
只要在同一个回合里面,在同一场游戏里面, 所有的状态跟动作的对都会使用同样的奖励项(term)进行加权,这件事情显然是不公平的,因为在同一场游戏里面 也许有些动作是好的,有些动作是不好的。 假设整场游戏的结果是好的, 并不代表这个游戏里面每一个行为都是对的。若是整场游戏结果不好, 但不代表游戏里面的所有行为都是错的。所以我们希望可以给每一个不同的动作前面都乘上不同的权重。每一个动作的不同权重, 它反映了每一个动作到底是好还是不好。
|
||||
|
||||

|
||||
|
||||
举个例子, 假设这个游戏都很短,只有 3~4 个互动, 在 $s_a$ 执行 $a_1$ 得到 5 分。在 $s_b$ 执行 $a_2$ 得到 0 分。在 $s_c$ 执行 $a_3$ 得到 -2 分。 整场游戏下来,你得到 +3 分,那你得到 +3 分 代表在状态 $s_b$ 执行动作 $a_2$ 是好的吗?并不见得代表状态 $s_b$ 执行 $a_2$ 是好的。因为这个正的分数,主要来自于在状态$s_a$ 执行了 $a_1$,跟在状态$s_b$ 执行 $a_2$ 是没有关系的,也许在状态 $s_b$ 执行 $a_2$ 反而是不好的, 因为它导致你接下来会进入状态 $s_c$,执行 $a_3$ 被扣分,所以整场游戏得到的结果是好的, 并不代表每一个行为都是对的。
|
||||
举个例子, 假设这个游戏都很短,只有 3~4 个互动, 在 $s_a$ 执行 $a_1$ 得到 5 分。在 $s_b$ 执行 $a_2$ 得到 0 分。在 $s_c$ 执行 $a_3$ 得到 -2 分。 整场游戏下来,你得到 +3 分,那你得到 +3 分 代表在 $s_b$ 执行动作 $a_2$ 是好的吗?并不见得代表 $s_b$ 执行 $a_2$ 是好的。因为这个正的分数,主要来自于在 $s_a$ 执行了 $a_1$,跟在 $s_b$ 执行 $a_2$ 是没有关系的,也许在 $s_b$ 执行 $a_2$ 反而是不好的, 因为它导致你接下来会进入 $s_c$,执行 $a_3$ 被扣分,所以整场游戏得到的结果是好的, 并不代表每一个行为都是对的。
|
||||
|
||||

|
||||
|
||||
如果按照我们刚才的讲法,整场游戏得到的分数是 3 分,那到时候在训练的时候, 每一个状态跟动作的对,都会被乘上 +3。 在理想的状况下,这个问题,如果你采样够多就可以被解决。因为假设你采样够多,在状态 $s_b$ 执行 $a_2$ 的这件事情,被采样到很多。就某一场游戏,在状态$s_b$ 执行 $a_2$,你会得到 +3 分。 但在另外一场游戏,在状态$s_b$ 执行 $a_2$,你却得到了 -7 分,为什么会得到 -7 分呢? 因为在状态 $s_b$ 执行 $a_2$ 之前, 你在状态$s_a$ 执行 $a_2$ 得到 -5 分,-5 分这件事可能也不是在 $s_b$ 执行 $a_2$ 的错,这两件事情,可能是没有关系的,因为它先发生了,这件事才发生,所以它们是没有关系的。
|
||||
如果按照我们刚才的讲法,整场游戏得到的分数是 3 分,那到时候在训练的时候, 每一个状态跟动作的对,都会被乘上 +3。 在理想的状况下,这个问题,如果你采样够多就可以被解决。因为假设你采样够多,在 $s_b$ 执行 $a_2$ 的这件事情,被采样到很多。就某一场游戏,在 $s_b$ 执行 $a_2$,你会得到 +3 分。 但在另外一场游戏,在 $s_b$ 执行 $a_2$,你却得到了 -7 分,为什么会得到 -7 分呢? 因为在 $s_b$ 执行 $a_2$ 之前, 你在 $s_a$ 执行 $a_2$ 得到 -5 分,-5 分这件事可能也不是在 $s_b$ 执行 $a_2$ 的错,这两件事情,可能是没有关系的,因为它先发生了,这件事才发生,所以它们是没有关系的。
|
||||
|
||||
在状态 $s_b$ 执行 $a_2$ 可能造成的问题只有会在接下来 -2 分,而跟前面的 -5 分没有关系的。但是假设我们今天采样到这项的次数够多,把所有发生这件事情的情况的分数通通都集合起来, 那可能不是一个问题。但现在的问题就是,我们采样的次数是不够多的。在采样的次数不够多的情况下,你要给每一个状态跟动作对合理的 credit,你要让大家知道它合理的 contribution。怎么给它一个合理的 contribution 呢? 一个做法是计算这个 pair 的奖励的时候,不把整场游戏得到的奖励全部加起来,**只计算从这一个动作执行以后所得到的奖励**。因为这场游戏在执行这个动作之前发生的事情是跟执行这个动作是没有关系的, 所以在执行这个动作之前得到多少奖励都不能算是这个动作的功劳。跟这个动作有关的东西, 只有在执行这个动作以后发生的所有的奖励把它加起来,才是这个动作真正的 contribution。所以在这个例子里面,在状态 $s_b$ 执行 $a_2$ 这件事情,也许它真正会导致你得到的分数应该是 -2 分而不是 +3 分,因为前面的 +5 分 并不是执行 $a_2$ 的功劳。实际上执行 $a_2$ 以后,到游戏结束前, 你只有被扣 2 分而已,所以它应该是 -2。那一样的道理,今天执行 $a_2$ 实际上不应该是扣 7 分,因为前面扣 5 分,跟在 $s_b$ 这个状态 执行 $a_2$ 是没有关系的。在 $s_b$ 这个状态 执行 $a_2$,只会让你被扣两分而已,所以也许在 $s_b$ 这个状态 执行 $a_2$, 你真正会导致的结果只有扣两分而已。如果要把它写成式子的话是什么样子呢?如下式所示。
|
||||
在 $s_b$ 执行 $a_2$ 可能造成的问题只有会在接下来 -2 分,而跟前面的 -5 分没有关系的。但是假设我们今天采样到这项的次数够多,把所有发生这件事情的情况的分数通通都集合起来, 那可能不是一个问题。但现在的问题就是,我们采样的次数是不够多的。在采样的次数不够多的情况下,你要给每一个状态跟动作对合理的分数,你要让大家知道它合理的贡献。怎么给它一个合理的贡献呢?
|
||||
|
||||
一个做法是计算这个对的奖励的时候,不把整场游戏得到的奖励全部加起来,**只计算从这一个动作执行以后所得到的奖励**。因为这场游戏在执行这个动作之前发生的事情是跟执行这个动作是没有关系的, 所以在执行这个动作之前得到多少奖励都不能算是这个动作的功劳。跟这个动作有关的东西, 只有在执行这个动作以后发生的所有的奖励把它加起来,才是这个动作真正的贡献。所以在这个例子里面,在 $s_b$ 执行 $a_2$ 这件事情,也许它真正会导致你得到的分数应该是 -2 分而不是 +3 分,因为前面的 +5 分 并不是执行 $a_2$ 的功劳。实际上执行 $a_2$ 以后,到游戏结束前, 你只有被扣 2 分而已,所以它应该是 -2。那一样的道理,今天执行 $a_2$ 实际上不应该是扣 7 分,因为前面扣 5 分,跟在 $s_b$ 执行 $a_2$ 是没有关系的。在 $s_b$ 执行 $a_2$,只会让你被扣两分而已,所以也许在 $s_b$ 执行 $a_2$, 你真正会导致的结果只有扣两分而已。如果要把它写成式子的话是什么样子呢?如下式所示:
|
||||
|
||||

|
||||
|
||||
本来的权重是整场游戏的奖励的总和。那现在改成从某个时间 $t$ 开始,假设这个动作是在 t 这个时间点所执行的,从 $t$ 这个时间点,一直到游戏结束所有奖励的总和,才真的代表这个动作是好的还是不好的。
|
||||
本来的权重是整场游戏的奖励的总和。那现在改成从某个时间 $t$ 开始,假设这个动作是在 $t$ 这个时间点所执行的,从 $t$ 这个时间点一直到游戏结束所有奖励的总和,才真的代表这个动作是好的还是不好的。
|
||||
|
||||

|
||||
**接下来再更进一步,我们把未来的奖励做一个 discount**,由此得到的回报被称为 `Discounted Return(折扣回报)`。为什么要把未来的奖励做一个 discount 呢?因为虽然在某一个时间点,执行某一个动作,会影响接下来所有的结果,有可能在某一个时间点执行的动作,接下来得到的奖励都是这个动作的功劳。但在比较真实的情况下, 如果时间拖得越长,影响力就越小。 比如说在第二个时间点执行某一个动作, 那我在第三个时间点得到的奖励可能是在第二个时间点执行某个动作的功劳,但是在 100 个时间点之后,又得到奖励,那可能就不是在第二个时间点执行某一个动作得到的功劳。 所以我们实际上在做的时候,你会在 R 前面乘上一个 `discount factor` $\gamma$, $\gamma \in [0,1] $ ,一般会设个 0.9 或 0.99,
|
||||
**接下来再更进一步,我们把未来的奖励做一个折扣(discount)**,由此得到的回报被称为 `Discounted Return(折扣回报)`。为什么要把未来的奖励做一个折扣呢?因为虽然在某一个时间点,执行某一个动作,会影响接下来所有的结果,有可能在某一个时间点执行的动作,接下来得到的奖励都是这个动作的功劳。但在比较真实的情况下, 如果时间拖得越长,影响力就越小。 比如说在第二个时间点执行某一个动作, 那我在第三个时间点得到的奖励可能是在第二个时间点执行某个动作的功劳,但是在 100 个时间点之后又得到奖励,那可能就不是在第二个时间点执行某一个动作得到的功劳。 所以我们实际上在做的时候,你会在 R 前面乘上一个 `discount factor` $\gamma$, $\gamma \in [0,1] $ ,一般会设个 0.9 或 0.99,
|
||||
|
||||
* $\gamma = 0$ : 只关心即时奖励;
|
||||
* $\gamma = 1$ : 未来奖励等同于即时奖励。
|
||||
|
||||
如果时间点 $t'$ 越大,它前面就乘上越多次的 $\gamma$,就代表说现在在某一个状态$s_t$, 执行某一个动作$a_t$ 的时候,它真正的 credit 是在执行这个动作之后所有奖励的总和,而且你还要乘上 $\gamma$。
|
||||
如果时间点 $t'$ 越大,它前面就乘上越多次的 $\gamma$,就代表说现在在某一个状态$s_t$, 执行某一个动作 $a_t$ 的时候,它真正的分数是在执行这个动作之后所有奖励的总和,而且你还要乘上 $\gamma$。
|
||||
|
||||
举一个例子, 你就想成说,这是游戏的第 1、2、3、4 回合,那你在游戏的第二回合的某一个 $s_t$ 你执行 $a_t$,它真正的 credit 得到的分数应该是,假设你这边得到 +1 分 这边得到 +3 分,这边得到 -5 分,它的真正的 credit,应该是 1 加上一个 discount 的 credit 叫做 $\gamma$ 乘上 3,再加上 $\gamma^2$ 乘上 -5。
|
||||
|
||||
如果大家可以接受这样子的话, 实际上就是这么实现的。这个 b 可以是取决于状态(state-dependent)的,事实上 b 它通常是一个网络估计出来的,它是一个网络的输出。
|
||||
举一个例子, 你就想成说,这是游戏的第 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$ 的分数应该是:
|
||||
$$
|
||||
1+ \gamma \times 3+\gamma^2 \times-5
|
||||
$$
|
||||
实际上就是这么实现的,b 可以是取决于状态(state-dependent)的,事实上 b 它通常是一个网络估计出来的,它是一个网络的输出。
|
||||
|
||||

|
||||
|
||||
把 $R-b$ 这一项合起来,我们统称为` advantage function`, 用 `A` 来代表 advantage function。Advantage function 是 dependent on s and a,我们就是要计算的是在某一个状态s 采取某一个动作 a 的时候,advantage function 有多大。
|
||||
把 $R-b$ 这一项合起来,我们统称为` advantage function`, 用 `A` 来代表 advantage function。Advantage function 取决于 s 和 a,我们就是要计算的是在某一个状态 s 采取某一个动作 a 的时候,advantage function 有多大。
|
||||
|
||||
在算 advantage function 时,你要计算 $\sum_{t^{\prime}=t}^{T_{n}} r_{t^{\prime}}^{n}$ ,你需要有一个互动的结果。你需要有一个模型去跟环境做互动,你才知道接下来得到的奖励会有多少。这个 advantage function 的上标是 $\theta$,$\theta$ 就是代表说是用 $\theta$ 这个模型跟环境去做互动,然后你才计算出这一项。从时间 t 开始到游戏结束为止,所有 r 的加和减掉 b,这个就叫 advantage function。
|
||||
|
||||
@@ -245,7 +255,7 @@ Advantage function 的意义就是,假设我们在某一个状态$s_t$ 执行
|
||||
|
||||

|
||||
|
||||
MC 可以理解为算法完成一个回合之后,再拿这个回合的数据来去 learn 一下,做一次更新。因为我们已经拿到了一整个回合的数据的话,也能够拿到每一个步骤的奖励,我们可以很方便地去计算每个步骤的未来总收益,就是我们的期望,就是我们的回报 $G_t$ 。$G_t$ 是我们的未来总收益,$G_t$ 代表是从这个步骤后面,我能拿到的收益之和是多少。$G_1$是说我从第一步开始,往后能够拿到多少的收益。$G_2$ 是说从第二步开始,往后一共能够拿到多少的收益。
|
||||
MC 可以理解为算法完成一个回合之后,再拿这个回合的数据来去 learn 一下,做一次更新。因为我们已经拿到了一整个回合的数据的话,也能够拿到每一个步骤的奖励,我们可以很方便地去计算每个步骤的未来总收益,就是我们的期望,就是我们的回报 $G_t$ 。$G_t$ 是我们的未来总收益,$G_t$ 代表是从这个步骤后面,我能拿到的收益之和是多少。$G_1 $是说我从第一步开始,往后能够拿到多少的收益。$G_2$ 是说从第二步开始,往后一共能够拿到多少的收益。
|
||||
|
||||
相比 MC 还是一个回合更新一次这样子的方式,TD 就是每个步骤都更新一下。每走一步,我就更新下,这样的更新频率会更高一点。它拿的是 Q-function 来去近似地表示我的未来总收益 $G_t$。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user