本文是伯克利深度强化学习课程CS294策略梯度部分12的笔记,源代码部分见GitHub

策略梯度

对于强化学习问题来说,目标函数就是使得状态动作序列累计奖励最大化

其中为状态动作序列的出现概率,按照马尔科夫决策过程,其定义为

记为,那么强化学习需要优化的目标函数就是

我们采用梯度下降的方式来优化策略,目标函数的梯度为

梯度计算中存在期望,但是我们是无法直接获得期望的值的,只能通过足够多次的采样来逼近

最终整个策略梯度算法循环

  1. 运行策略,获得采样
  2. 计算

策略梯度中存在的问题

高方差

上图中横轴代表轨迹,纵轴代表轨迹对应的奖励,而蓝色的曲线代表执行策略得到的轨迹分布。如果我们采样了三个轨迹(绿色),其中一个奖励为负数并且非常低,另外两个奖励为正数但是比较低,这时算法为了最大化奖励期望,策略会趋向于在两个正数奖励轨迹附近采样。但是如果我们将三个轨迹的奖励数值都提高到正数,那么策略会向左偏移。

收敛慢

假设条件概率,奖励函数为,模型的参数为。分别求每个参数对应的偏导

时,式总是小于零;当时,式总是大于零。根据最优值是无线接近于零。但是对于式来说,当越接近零的时候,,向量更趋向于优化而不是,这就导致难以收敛到最优值。

解决高方差

向后奖励

一种解决方法就是避免将动作发生之前的奖励累加到动作发生以后的累计奖励中。

添加基准

第二种方法就是将奖励累计值减去一个基准值

减去一个基准值并不会改变累计奖励的期望,这是因为

接下来可以采用最小化方差的方法来求出理想的基准值,令

对方差求导数等于零

得到

可以视为带权的奖励累计期望。

离策略算法

重要性采样:

策略梯度算法是在策略算法,这意味着每一次更新策略之后,需要使用重要性采样对训练轨迹进行重新采样

其中

将重要性采样加入梯度函数得到

自动求导中的损失函数

现代深度学习框架都是支持自动求导的,所以我们需要将目标函数作为损失函数传给优化器,而不需要自行求导。目标函数中只有和参数有关。另外,强化学习优化目标是最大化,然而机器学习库的优化目标是最小化损失。综上所述,因此损失函数可以写成

动作评价算法

如果将策略梯度算法中累计奖励更换为累计奖励的期望,那么可以在一定程度上解决高方差问题,这就是动作评价算法。

V函数拟合

根据

只需要拟合函数即可实现动作评价。常用的方法是采用神经网络进行回归,训练数据为

上面的方法需要记录所有的奖励,另一种方法需要记录所有记录奖励

衰减参数

如果时间T为无穷,那么显然不能直接将所以的奖励累加,于是需要使用一个参数对往后的奖励进行衰减。增加了奖励衰减的动作评价算法为

奖励衰减版本的策略梯度算法为

策略梯度实验3

神经网络

实验使用的依然是全连接的神经网络,通来说一层隐层就完全足够,更多的隐层不但存在过拟合风险,也使得梯度消失等深度学习中存在的问题出现。

策略梯度算法

在实验中需要分别实现普通的奖励累计方法、向后奖励累计方法、优势函数归一化(将优势函数归一化为均值为0、方差为1的分布)和基准函数(其中)。

离散任务

小批量训练学习曲线
大批量训练学习曲线

各个曲线对应的运行参数为:

python train_pg.py CartPole-v0 -n 100 -b 1000 -e 5 -dna --exp_name sb_no_rtg_dna
python train_pg.py CartPole-v0 -n 100 -b 1000 -e 5 -rtg -dna --exp_name sb_rtg_dna
python train_pg.py CartPole-v0 -n 100 -b 1000 -e 5 -rtg --exp_name sb_rtg_na
python train_pg.py CartPole-v0 -n 100 -b 5000 -e 5 -dna --exp_name lb_no_rtg_dna
python train_pg.py CartPole-v0 -n 100 -b 5000 -e 5 -rtg -dna --exp_name lb_rtg_dna
python train_pg.py CartPole-v0 -n 100 -b 5000 -e 5 -rtg --exp_name lb_rtg_na

可以得出的结论为:

  • 批量训练数据越多,收敛越快,奖励提升过程越平稳;
  • 向后奖励的方式对于学习效果提升明显,而归一化则不明显。

连续任务

在环境中,动作可能是离散的,也可能是连续的。对于离散动作来说,神经网络输出层的一个单元就是对应着一个动作的,但是对于连续动作来说,事情要麻烦一些。

对于连续动作来说,通常采用高斯分布对动作进行采样。其中均值来自神经网络的输出,标准差是一个可学习的参数(初始化为1最佳)。所以,连续动作采样自,概率为

连续任务学习曲线
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg --exp_name sb_rtg_na
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg -bl --exp_name sb_rtg_na_bl

实验中基准函数并没有提供帮助,反而起到了负作用。

高难度任务

HalfCheetah-v2是一个比较有难度的任务,比较有效的方法是增大学习率增加批量数据

python train_pg.py HalfCheetah-v2 -e 5 -ep 150 --discount 0.9 -b 50000 -lr 0.025 -j 1 -rtg --exp_name xxlb_rtg_na
HalfCheetah-v2学习曲线

拓展部分

并行采集

并行采样是一个非常好的主意,但是由于Python存在全局解释器锁,因此使用“伪”多线程还会产生不良的副作用。但是,虽然不能实现并行采样,但是能够让模型同时计算多个观测的动作采样。

采样时间曲线
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg --exp_name sb_rtg_na
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg -j 5 --exp_name sb_rtg_na_j5
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg -j 10 --exp_name sb_rtg_na_j10

采样时间由环境模拟和动作计算两部分构成,此处的优化能够缩短动作计算时间,但是无法缩短环境模拟时间。因此,当动作计算时间所占时间较少时,并行计算的优化效果不佳,如果增加并行数目,甚至还会增加管理多个模拟环境的额外成本。

GAE-λ4

在动作评价算法中,动作评价的值为:。其中由于的存在,这是并不是一个无偏估计,GAE希望解决由带来的有偏问题。

接着尝试累加k个,采用作为符号:

接着做指数加权平均,得到GAE值

实际上动作评价算法和减去值的方法都是GAE的两个特殊情况:

GAE学习曲线
python train_pg.py Walker2d-v2 -n 100 -b 1000 -e 5 -j 5 -rtg --discount 0.99 --exp_name sb_rtg_na_discount0.99
python train_pg.py Walker2d-v2 -n 100 -b 1000 -e 5 -j 5 -rtg --discount 0.99 -g 0 --exp_name sb_rtg_na_discount0.99_g0
python train_pg.py Walker2d-v2 -n 100 -b 1000 -e 5 -j 5 -rtg --discount 0.99 -g 0.6 --exp_name sb_rtg_na_discount0.99_g0.6
python train_pg.py Walker2d-v2 -n 100 -b 1000 -e 5 -j 5 -rtg --discount 0.99 -g 0.8 --exp_name sb_rtg_na_discount0.99_g0.8
python train_pg.py Walker2d-v2 -n 100 -b 1000 -e 5 -j 5 -rtg --discount 0.99 -g 1 --exp_name sb_rtg_na_discount0.99_g1

在Walker2d中GAE的作用似乎不大,甚至当的时候性能极差。就实验中尝试的所以算法改进而言,只有向后累加的方法提升作用最明显,其他改进的提升作用几乎没有,甚至会起到负优化作用,论文中的优化作用难以复现5

多次拟合

在原来的框架中,对于每一批采集的数据,神经网络只进行了一次训练,如果增加训练次数会发生什么呢?增加次数之后,神经网络会根据当前的采样数据优化到最优值。然而,这样会导致当模型对应当前采样数据过拟合而影响模型在其他观测上的表现。

不同拟合次数对应的学习曲线
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg --exp_name sb_rtg_na
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg --epoch 3 --exp_name sb_rtg_na_epoch3
python train_pg.py InvertedPendulum-v2 -n 100 -b 1000 -e 5 -rtg --epoch 5 --exp_name sb_rtg_na_epoch5
  • 当训练次数为3次时,模型性能的提升非常快速,虽然上下浮动幅度非常大,但是总体表现优于1次训练;
  • 当训练次数为5次时,模型性能提升过程劣于3次训练,浮动幅度也大于5次训练,总体表现略优于1次训练。

参考文献