Skip to content

Commit

Permalink
update A2C
Browse files Browse the repository at this point in the history
  • Loading branch information
johnjim0816 committed Jul 29, 2023
1 parent b40d922 commit 706901a
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 13 deletions.
39 changes: 38 additions & 1 deletion docs/ch10/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,41 @@ $$

如图所示,原先的 `A2C` 算法相当于只有一个全局网络并持续与环境交互更新。而 `A3C` 算法中增加了多个进程,每一个进程都拥有一个独立的网络和环境以供交互,并且每个进程每隔一段时间都会将自己的参数同步到全局网络中,这样就能提高训练效率。这种训练模式也是比较常见的多进程训练模式,也能用于其他算法中,也包括前面讲到的基于价值的算法。

## GAE 算法
## 广义优势估计

上一小节中,我们通过引入优势函数来缓解梯度估计带来的高方差问题,但由于优势函数通本质上来说还是使用蒙特卡洛估计,因此尽管减去了基线,有时候还是会产生高方差,从而导致训练过程不稳定。这时候有读者可能会想到一句话,即“知识一般是通过螺旋式的规律来学习的,也是会螺旋式升级的”,这句话的意思是我们在学某些知识时可能不会马上用到,但是会暂时埋下一个种子,等到后面深入使用的时候会回忆起来并且加深相关知识的理解。当然这句话不是某个名人说的,而是笔者自己总结出来,也是想传达给读者的学习思路。回到正题,既然蒙特卡洛估计一定会带来高方差问题,那么读者可能回到想到前面章节中在讲到蒙特卡洛和时序差分方法的差异时,会发现这两个方法是互补的,时序差分能有效解决高方差问题但是是有偏估计,而蒙特卡洛是无偏估计但是会带来高方差问题,因此通常会结合这两个方法形成一种新的估计方式,即 TD($\lambda$) 估计。类似地,在这里我们也可以引入 $\lambda$,结合多步(n-step)的折扣回报来改进优势函数,形成一种新的估计方式,我们称之为广义优势估计(Generalized Advantage Estimation,简称 GAE)。公式如下:

$$
\begin{aligned}
A^{\mathrm{GAE}(\gamma, \lambda)}(s_t, a_t) &= \sum_{l=0}^{\infty}(\gamma \lambda)^l \delta_{t+l} \\
&= \sum_{l=0}^{\infty}(\gamma \lambda)^l \left(r_{t+l} + \gamma V^\pi(s_{t+l+1}) - V^\pi(s_{t+l})\right)
\end{aligned}
$$

其中 $\delta_{t+l}$ 表示时间步 $t+l$ 时的 TD 误差,即:

$$
\begin{aligned}
\delta_{t+l} = r_{t+l} + \gamma V^\pi(s_{t+l+1}) - V^\pi(s_{t+l})
\end{aligned}
$$

当 $\lambda = 0$ 时,GAE 退化为单步 TD 误差,即:

$$
\begin{aligned}
A^{\mathrm{GAE}(\gamma, 0)}(s_t, a_t) = \delta_t = r_t + \gamma V^\pi(s_{t+1}) - V^\pi(s_t)
\end{aligned}
$$

当 $\lambda = 1$ 时,GAE 退化为蒙特卡洛估计,即:

$$
\begin{aligned}
A^{\mathrm{GAE}(\gamma, 1)}(s_t, a_t) = \sum_{l=0}^{\infty}(\gamma \lambda)^l \delta_{t+l} = \sum_{l=0}^{\infty}(\gamma)^l \delta_{t+l}
\end{aligned}
$$

如何选择合适的 $\lambda$ 还请读者回看前面时序差分的相关章节内容,这里就不再赘述。到这里,我们就将 `Actor-Critic` 算法的基本原理讲完了,注意广义优势估计并不是 `Actor-Critic` 算法的必要组成部分,只是一种改进的方法。相反地,它更像是一种通用的模块,在实践中可以用在任何需要估计优势函数的地方,比如后面章节要讲的 `PPO` 算法中就用到了这种估计方法。

## 实战:A2C 算法
40 changes: 28 additions & 12 deletions docs/ch4/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

前面提到很多经典的强化学习算法都是免模型的,换句话说在这种情况下环境的状态转移概率是未知的,这种情况下会去近似环境的状态价值函数,这其实跟状态转移概率是等价的,我们把这个过程称为**预测(Prediction)**。换句话说,预测是在马尔可夫决策过程 $<S,A,P,R,\gamma>$ 中,输入策略 $\pi$ ,然后输出状态价值函数 $V_{\pi}$ 。相对的,**控制(Control)** 则需要我们找到一个最优策略 $\pi^*$ ,并且同时输出对应的最优状态价值函数 $V^*$ 。之所以提到这两个概念,是因为很多时候我们不能一蹴而就解决好控制问题,而需要先解决预测问题,进而解决控制问题。

## 蒙特卡洛方法
## 蒙特卡洛估计

蒙特卡洛方法在强化学习中是免模型预测价值函数的方式之一,本质是一种统计模拟方法,它的发展得益于电子计算机的发明。假设我们需要计算一个不规则图形的面积,这种情况下是很难通过规则或者积分的方式得到结果的。而蒙特卡洛基于这样的想法:比如我们有一袋豆子,把豆子均匀地在一定范围内朝这个图形上撒,撒到足够多的数量时数一下这个图形中有多少颗豆子,这个豆子的数目就是图形的面积。当豆子越小撒的越多的时候,结果就越精确。此时我们借助计算机程序可以生成大量均匀分布坐标点,然后统计出图形内的点数,通过它们占总点数的比例和坐标点生成范围的面积就可以求出图形面积。
蒙特卡洛估计方法在强化学习中是免模型预测价值函数的方式之一,本质是一种统计模拟方法,它的发展得益于电子计算机的发明。假设我们需要计算一个不规则图形的面积,这种情况下是很难通过规则或者积分的方式得到结果的。而蒙特卡洛基于这样的想法:比如我们有一袋豆子,把豆子均匀地在一定范围内朝这个图形上撒,撒到足够多的数量时数一下这个图形中有多少颗豆子,这个豆子的数目就是图形的面积。当豆子越小撒的越多的时候,结果就越精确。此时我们借助计算机程序可以生成大量均匀分布坐标点,然后统计出图形内的点数,通过它们占总点数的比例和坐标点生成范围的面积就可以求出图形面积。

那么在强化学习中蒙特卡洛方法是怎么预测状态价值函数 $V(s)$ 的呢?我们回顾 $V(s)$ 的定义公式,如下:

Expand Down Expand Up @@ -70,15 +70,15 @@ $$

此外,FVMC 是一种基于回合的增量式方法,具有无偏性和收敛快的优点,但是在状态空间较大的情况下,依然需要训练很多个回合才能达到稳定的结果。而 EVMC 则是更为精确的预测方法,但是计算的成本相对也更高。

## 时序差分方法
## 时序差分估计

时序差分方法是一种基于经验的动态规划方法,它结合了蒙特卡洛和动态规划的思想。最简单的时序差分可以表示为:
时序差分估计方法是一种基于经验的动态规划方法,它结合了蒙特卡洛和动态规划的思想。最简单的时序差分可以表示为:

$$
V(s_t) \leftarrow V(s_t) + \alpha[r_{t+1}+\gamma V(s_{t+1})- V(s_{t})]
$$

这种算法一般称为**一步时序差分(one-step TD)**,即 $TD(0)$。可以看到,在这个更新过程中使用了当前奖励和后继状态的估计,这是类似于蒙特卡罗方法的;但同时也利用了贝尔曼方程的思想,将下一状态的值函数作为现有状态值函数的一部分估计来更新现有状态的值函数。此外,时序差分还结合了自举(Bootstrap)的思想,即未来状态的价值是通过现有的估计 $r_{t+1}+\gamma V(s_{t+1})$ (也叫做**时序差分目标**)进行计算的,即使用一个状态的估计值来更新该状态的估计值,没有再利用后续状态信息的计算方法。这种方法的好处在于可以将问题分解成只涉及一步的预测,从而简化计算。此外,$\delta=r_{t+1}+\gamma V(s_{t+1})- V(s_{t})$被定义为**时序差分误差(TD error)**
这种算法一般称为**单步时序差分(one-step TD)**,即 $TD(0)$。可以看到,在这个更新过程中使用了当前奖励和后继状态的估计,这是类似于蒙特卡罗方法的;但同时也利用了贝尔曼方程的思想,将下一状态的值函数作为现有状态值函数的一部分估计来更新现有状态的值函数。此外,时序差分还结合了自举(Bootstrap)的思想,即未来状态的价值是通过现有的估计 $r_{t+1}+\gamma V(s_{t+1})$ (也叫做**时序差分目标**)进行计算的,即使用一个状态的估计值来更新该状态的估计值,没有再利用后续状态信息的计算方法。这种方法的好处在于可以将问题分解成只涉及一步的预测,从而简化计算。此外,$\delta=r_{t+1}+\gamma V(s_{t+1})- V(s_{t})$被定义为**时序差分误差(TD error)**

但有一点需要注意的是,由于基于时步的学习方式,并且终止状态没有下一步,比如当 $V(s_{t})$ 是终止状态时,$\gamma V(s_{t+1})$ 是没有意义的。因此时序差分方法在实践过程中会把终止状态单独做一个判断,即将对应未来状态的估计值设置为 $0$,然后更新当前状态的估计值,这个过程也被称作**回溯**,公式表示如下,后面所有基于时序差分的方法都会有这样的一个判断。

Expand All @@ -92,20 +92,19 @@ $$
## 时序差分和蒙特卡洛的比较
结合图 4.4 总结一下时序差分方法和蒙特卡洛方法之间的差异。

1)时序差分方法可以在线学习(online learning),每走一步就可以更新,效率高。蒙特卡洛方法必须等游戏结束时才可以学习。

(2)时序差分方法可以从不完整序列上进行学习。蒙特卡洛方法只能从完整的序列上进行学习。

(3)时序差分方法可以在连续的环境下(没有终止)进行学习。蒙特卡洛方法只能在有终止的情况下学习。

(4)时序差分方法利用了马尔可夫性质,在马尔可夫环境下有更高的学习效率。蒙特卡洛方法没有假设环境具有马尔可夫性质,利用采样的价值来估计某个状态的价值,在不是马尔可夫的环境下更加有效。
* 时序差分方法可以在线学习(online learning),每走一步就可以更新,效率高。蒙特卡洛方法必须等游戏结束时才可以学习。
* 时序差分方法可以从不完整序列上进行学习。蒙特卡洛方法只能从完整的序列上进行学习。
* 时序差分方法可以在连续的环境下(没有终止)进行学习。蒙特卡洛方法只能在有终止的情况下学习。
* 时序差分方法利用了马尔可夫性质,在马尔可夫环境下有更高的学习效率。蒙特卡洛方法没有假设环境具有马尔可夫性质,利用采样的价值来估计某个状态的价值,在不是马尔可夫的环境下更加有效。


<div align=center>
<img width="600" src="../figs/ch4/TD_3.png"/>
</div>
<div align=center>图 4.4 时序差分方法和蒙特卡洛方法的差异</div>

## n 步时序差分

把时序差分方法进一步拓展,之前只是向前自举了一步,即$TD(0)$,我们可以调整为两步,利用两步得到的回报来更新状态的价值,调整 $n$ 步就是 **n步时序差分(n-step TD)**,公式表示如下:

$$
Expand All @@ -119,6 +118,23 @@ $$

我们会发现当 $n$ 趋近于无穷大时,就变成了蒙特卡洛方法,因此可以通过调整自举的步数,来实现蒙特卡洛方法和时序差分方法之间的权衡。

以下是一些常见的方法来选择合适的 λ:

网格搜索(Grid Search):对于给定的一组 λ 值,可以通过网格搜索方法在这些值中进行遍历,并评估每个值对应的算法性能。选择在验证集上表现最好的 λ 值作为最终的选择。

随机搜索(Random Search):随机选择一组 λ 值,在验证集上评估每个值对应的算法性能。通过多次随机搜索,可以得到更好的 λ 值。

自适应选择:在训练过程中逐渐适应地调整 λ 的取值。例如,可以在训练的早期使用较小的 λ 值,以更多地依赖单步TD误差来减小偏差;在训练的后期逐渐增大 λ 值,以更多地依赖多步回报来减小方差。

交叉验证(Cross-validation):将数据集划分为多个子集,交叉验证不同的 λ 值,并平均它们的性能评估结果。这样可以更好地估计不同 λ 值的泛化性能。

经验取值:在某些情况下,根据先前的经验或已知的任务特性,可以选择一些常用的 λ 取值作为初始值,并进一步微调。

无论使用哪种方法,重要的是要在合适的验证集上评估不同 λ 值对应的算法性能。找到使得算法在验证集上表现最佳的 λ 值,以确保在测试集或真实环境中获得良好的性能。

需要注意的是,λ 的最佳取值可能因任务、环境和算法的不同而异。因此,选择合适的 λ 值是一个实验过程,需要根据具体问题进行调整。在实际应用中,可以结合多种方法来找到最佳的 λ 值,以获得更好的性能。


## 本章小结

本章重点讲解了两种常见的免模型预测方法,蒙特卡洛和时序差分方法。另外涉及到了一些关键的概念,有模型与免模型,预测与控制,建议读者熟练掌握。
Expand Down

0 comments on commit 706901a

Please sign in to comment.