add REINFORCE and
@@ -235,7 +235,66 @@ $$
|
||||
|
||||
Advantage function 的意义就是,假设我们在某一个 state $s_t$ 执行某一个 action $a_t$,相较于其他可能的 action,它有多好。它在意的不是一个绝对的好,而是相对的好,即`相对优势(relative advantage)`。因为会减掉一个 b,减掉一个 baseline, 所以这个东西是相对的好,不是绝对的好。 $A^{\theta}\left(s_{t}, a_{t}\right)$ 通常可以是由一个 network estimate 出来的,这个 network 叫做 critic。
|
||||
|
||||
## REINFORCE
|
||||
|
||||

|
||||
|
||||
给大家区分一下什么是蒙特卡洛跟时序差分。形象去理解的话,蒙特卡洛可以简单的理解为算法完成一个 episode 之后,再拿这一个 episode 的数据来去 learn 一下,做一次更新。因为我们已经拿到了一整条 episode 的数据的话,也能够拿到每一个 step 的那个 reward,那我们也可以很方便的去计算每个 step 的未来总收益,就是我们的期望,就是我们的回报 $G_t$ 。$G_t$是我们的未来总收益,$G_t$代表是从这个 step 后面我能拿到的收益之和是多少。$G_1$是说我从第一步开始,往后能够拿到多少的收益。$G_2$ 的话也是说我从第二步这里开始,我往后能够拿到一共拿到多少的收益。
|
||||
|
||||
相比较蒙特卡洛还是一个 episode 更新一次这样子的方式,时序差分就是每个 step 都更新一下。我每走一步,我就更新下,这样的更新频率会更高一点。它拿的是 Q-function 来去近似地表示我的未来总收益 $G_t$。
|
||||
|
||||
举个例子来解释时序差分强化学习和蒙特卡洛强化学习的区别,
|
||||
|
||||
* 时序差分强化学习是指在不清楚马尔可夫状态转移概率的情况下,以采样的方式得到不完整的状态序列,估计某状态在该状态序列完整后可能得到的收益,并通过不断地采样持续更新价值。
|
||||
* 蒙特卡洛强化学习则需要经历完整的状态序列后,再来更新状态的真实价值。
|
||||
|
||||
例如,你想获得开车去公司的时间,每天上班开车的经历就是一次采样。假设今天在路口 A 遇到了堵车,
|
||||
|
||||
* 时序差分强化学习会在路口 A 就开始更新预计到达路口 B、路口 C $\cdots \cdots$, 以及到达公司的时间;
|
||||
* 而蒙特卡洛强化学习并不会立即更新时间,而是在到达公司后,再修改到达每个路口和公司的时间。
|
||||
|
||||
时序差分强化学习能够在知道结果之前就开始学习,相比蒙特卡洛强化学习,其更快速、灵活。
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
我们介绍下策略梯度最简单的也是最经典的一个算法 `REINFORCE`。REINFORCE 用的是回合更新的方式。它在代码上的处理上是先拿到每个 step 的 reward,然后计算每个 step 的未来总收益 $G_t$ 是多少,然后拿每个 $G_t$ 代入公式,去优化每一个 action 的输出。所以编写代码时会有这样一个函数,输入每个 step 拿到的 reward,然后把这些 reward 转成每一个 step 的未来总收益。因为未来总收益是这样计算的:
|
||||
$$
|
||||
\begin{aligned}
|
||||
G_{t} &=\sum_{k=t+1}^{T} \gamma^{k-t-1} r_{k} \\
|
||||
&=r_{t+1}+\gamma G_{t+1}
|
||||
\end{aligned}
|
||||
$$
|
||||
上一个 step 和下一个 step 的未来总收益可以有这样子的一个关系。所以在代码的计算上,我们就是从后往前推,一步一步地往前推,先算 $G_T$,然后往前推,一直算到 $G_1$ 。
|
||||
|
||||

|
||||
|
||||
REINFORCE 代码主要看最后四行,先产生一个 episode 的数据,比如 $(s_1,a_1,G_1),(s_2,a_2,G_2),\cdots,(s_T,a_T,G_T)$。然后针对每个 action 来计算梯度。 在代码上计算时,我们要拿到神经网络的输出。神经网络会输出每个 action 对应的概率值,然后我们还可以拿到实际的 action,把它转成 one-hot 向量乘一下,我们可以拿到 $\ln \pi(A_t|S_t,\theta)$ 。
|
||||
|
||||

|
||||
|
||||
手写数字识别的项目是很经典的一个多分类的问题,就是我们输入一张手写数字的图片,经过神经网络输出的是各个分类的一个概率。目的是希望我输出的这个概率的分布尽可能地去贴近真实值的概率分布。因为真实值只有一个数字 9,可是你用这个 one-hot 向量的形式去给他编码的话,也可以理解为这个真实值也是一个概率分布,9 的概率就是1,其他的概率就是 0。神经的网络输出一开始可能会比较平均,通过不断的迭代训练优化之后,我会希望 9 输出的概率可以远高于其他数字输出的概率。
|
||||
|
||||

|
||||
|
||||
如上图所示,就是提高 9 对应的概率,降低其他数字对应的概率。让神经网络输出的概率能够更贴近这个真实值的概率分布。那我们可以用交叉熵(Cross Entropy)来去表示两个概率分布之间的差距。
|
||||
|
||||

|
||||
|
||||
我们看一下它的优化流程,就是怎么让这个输出去逼近这个真实值。它的优化流程就是将图片作为输入传给神经网络,然后神经网络会给这个图片属于哪一类数字,输出所有数字可能的概率。然后再计算这个交叉熵,就是神经网络的输出 $Y_i$ 和真实的标签值 $Y_i'$ 之间的距离 $-\sum Y_{i}^{\prime} \cdot \log \left(Y_{i}\right)$。我们希望尽可能地缩小这两个概率分布之间的差距,计算出来的 cross entropy 就可以作为这个 loss 函数传给神经网络里面的优化器去优化,去自动去做神经网络的参数更新。
|
||||
|
||||

|
||||
|
||||
那类似的,policy gradient 预测每一个状态下面应该要输出的这个行动的概率,就是输入状态 $s_t$,然后输出动作的概率,比如 0.02,0.08,0.09。实际上输出给环境的动作是我随机选了一个 action,比如说我选了右这个 action。它的 one-hot 向量就是 0,0,1。我们把神经网络的输出和实际动作带入 cross entropy 的公式就可以求出输出的概率和实际的动作之间的差距。但这个实际的动作 $a_t$ 只是我们输出的真实的 action,它并不一定是正确的 action,它不能像那个手写数字识别一样作为一个正确的标签来去指导我的神经网络朝着正确的方向去更新。所以我们在这里会需要乘以一个奖励回报 $G_t$。这个奖励回报相当于是对这个真实 action 的评价,$G_t$ 具体越大,未来总收益越大,说明当前输出的这个真实的 action 就越好,那这个 loss 就越需要重视。如果 $G_t$ 越小,那就说明做这个 action $a_t$ 并没有那么的好,那我的 loss 的权重就要小一点。优化力度就小一点。通过这个和那个手写输入识别的一个对比,我们就知道为什么 loss 会构造成这个样子。
|
||||
|
||||

|
||||
|
||||
实际上我们在计算这个 loss 的时候,我们要拿到那个 $\ln \pi(A_t|S_t,\theta)$。我就拿我实际执行的这个动作,先取个 one-hot 向量,然后再拿到神经网络预测的动作概率,这两个一相乘,我就可以拿到算法里面的那个 $\ln \pi(A_t|S_t,\theta)$。这个就是我们要构造的 loss。因为我们会拿到整个 episode 的所有的轨迹,所以我们可以对这个这一条整条轨迹里面的每个 action 都去计算一个 loss。把所有的 loss 加起来之后,我们再扔给那个 adam 的优化器去自动更新参数就好了。
|
||||
|
||||

|
||||
|
||||
上图是 REINFORCE 的流程图。首先我们需要一个 policy model 来输出动作概率,输出动作概率后,我们用 sample 函数去得到一个具体的动作,然后跟环境交互过后,我们可以得到一整个 episode 的数据。拿到 episode 数据之后,我再去执行一下 learn() 函数,在 learn() 函数里面,我就可以拿这些数据去构造 loss function,扔给这个优化器去优化,去更新我的 policy model。
|
||||
|
||||
## References
|
||||
|
||||
|
||||
BIN
docs/chapter3/img/3.20.png
Normal file
|
After Width: | Height: | Size: 491 KiB |
BIN
docs/chapter3/img/3.21.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
docs/chapter3/img/3.22.png
Normal file
|
After Width: | Height: | Size: 520 KiB |
BIN
docs/chapter3/img/3.23.png
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
docs/chapter3/img/3.24.png
Normal file
|
After Width: | Height: | Size: 275 KiB |
BIN
docs/chapter3/img/3.25.png
Normal file
|
After Width: | Height: | Size: 435 KiB |
BIN
docs/chapter3/img/3.26.png
Normal file
|
After Width: | Height: | Size: 434 KiB |
BIN
docs/chapter3/img/3.27.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
docs/chapter3/img/3.28.png
Normal file
|
After Width: | Height: | Size: 392 KiB |