2. 关于DRL的一些经验

转自知乎专栏, 原文 深度强化学习落地方法论 https://zhuanlan.zhihu.com/p/95989190

需求分析

这里作者强主要强调DRL并不是万能的解药
弱点(过拟合与环境和泛化能力弱)。作者单独强调这俩是想和监督学习做对比。监督学习是在training set上训练test set上测试,但是强化学习是在真正环境中也就是test set上训练继而把自己好的经验都保留下来。这样就导致DRL是很依赖于环境的,一方面为了训练得足够多的数据,这也就依赖于模拟器;另一方面一旦环境发生变化,得重新训练。作者把这一现象描述为value function过拟合于环境,policy function过拟合于value function.
适用场景:作者给出了适用DRL的五个条件
场景固定:这里所谓的场景,是非agent之外的所有环境dynamics一定要是stationary的. 比如在multi-agent RL (MARL) 中, 其他agent的不断演化就属于非稳态环境。
目标明确:这个一般问题的目标都是确定了的,目标越明确,reward越好design
数据廉价:这个很好理解,因为具体环境中的learning需要大量的data
过程复杂:实际环境的规律难以总结或者很难找到解决方法才有学习的必要
自由度高:选择空间越大,自由度越高,人越容易出现选择困难症,但是这对DRL却是极好的。

算法选择

本节作者主要highlight了三种最基本的框架,一般在这三重大的框架下我们还要进行微调。
总的来说,DRL是一种由exploration慢慢转化为exploitation的算法,充分的探索对学习性能的影响至关重要,各种exploration的设计本文没有提及
DQN:DQN一般大家都很熟悉了,就是一个Q值网络由状态学习到各个action的values再选最大的。几个需要注意的特性:1)离散状态空间;2)off-policy当前用于学习的经验并不一定是当前policy采集的;3)epsilon greedy exploration。DQN也有很多问题,其中一个我想重复的是:off-policy对历史数据重复利用但是环境不能变化。比如MARL中off policy效果就不是很好,因为各个agent都在不断进化。
DDPG(soft actor critic?):DQN是离散action space,DDPG可以用在连续action space,它的主要特征是:1)与DQN相比有了一个显式的policy,而且这个policy是确定性,而非传统 actor-critic 中概率分布式的policy;2)action + noise to explore. DDPG也有一些问题,我们强调1)连续动作一般比离散动作要难,所以离散化连续空间也许比连续动作空间学习的更好;2)高维度action表现不好,维度灾难;3)critic的误差全部传给了actor,稳定性不足。
A3C (→同步版本A2C):这是作者着力推荐的框架, 与DDPG相比actor输出的是action的概率分布,因此梯度无法直接由critic流向actor, instead梯度定义为advantage function和actor梯度的乘积A(s,a)▽logπ(a|s) (这里得复习一下A3C+PPO以回顾具体算法流程)。它是一种on-policy方法,即每次训练policy net的经验都是由当前policy net产生的,更适用于MARL场景。总之,作者根据自己的经验最推荐A3C+PPO或者其同步版本A2C+PPO的组合,说比DQN和DDPG都要好。

动作空间

动作空间的选择一般比较简单,一般这个是由具体问题直接决定的,几个注意事项:
尽量选择离散空间(互斥,可穷举,表示成one-hot vector );注意离散化并不是代表着性能差,反而还会因为容易学习带来性能提升!
one-hot vector
如果实在无法离散化比如高维action,那么最好把action space归一化到 [-1,1].
特定状态下引起严重后果的action应该直接屏蔽。

状态空间

状态空间的优化非常重要,也就是所谓的feature engineering. 一般,用未经处理的状态空间做端到端学习效果是极差的,一方面时间成本,一方面干扰信息是致命的。所以说设计状态空间非常重要。
四步设计状态空间:

  1. 任务分析:本文举例在一个遍布障碍物的的区域内有若干小车在随机位置待命。目的是让他们最短时间内行驶到各自终点停下来,且过程中不发生任何碰撞。目标可以分解为1)到达终点;2)避免碰撞;3)最快。这三部分的要求分别对应着1)各个小车知道自己在哪终点在哪;2)知道障碍物和其他小车的位置运动状态;3)少绕路行驶速度快,尽量避免减速刹车。因此,我们第一步要总结出所有的可用的信息。
    2.相关信息筛选:在列出所有可用信息之后,我们要去筛选与主任务和子任务相关的那些信息。RL中action的质量最终是要通过reward来反馈回来的,所以说实际上我们在学习的就是各个状态和reward/value之间的关系,进而利用这层关系来指导action。所以说状态的设计和reward的设计息息相关,我们要设计的让神经网络更快更好的学习到他俩之间的关系!可以想象,在某个状态下得到的reward反馈越快,那么这层关系越容易学习到。因此,给定reward的设计之后,我们可以根据反馈时间长短把信息分为两类
    1) 直接相关信息:与某个reward直接相关的信息,比如距离周围障碍物的距离,这一信息直接影响着碰撞这一事件(假设碰撞引起很大的负reward),因此我们称其为直接相关信息。
    2) 间接相关信息:间接相关信息指的是这一信息的反馈得很久很久之后才能得到。比如小车到达终点得先拿到钥匙开门,但是我们没有设置拿钥匙这一奖励。那么,距离钥匙远近这一信息就是间接相关信息,因为我们只有在打开了门最终到达终点才发现拿钥匙是必要条件。
    Remark: 显然间接信息是可以转换为直接信息的,因为我们可以单独设计一个吃钥匙的奖励,所以说状态设计和reward设计是相关的。
    Remark: 其实已经不言自明了,如果我们把状态设计为一幅地图让小车自己学习拿钥匙这个动作,肯定会比直接告诉他钥匙坐标来的慢,因此状态的设计直接影响到学习效率。

  2. 统一性考虑:这一步是保证我们设计的状态有泛化性而不只是局限于某一场景
    1)外在形式统一。比如说,如果我们把所有小车的数据都当做状态,那么当小车的个数变化时,这一状态就不可用了尼?所以这就属于bad design。好的design比如我们把整个地图当做一幅图,原本环境是一幅图,所有小车位置是一幅图,重点位置是一幅图,然后把图叠在一起。
    2) 逻辑统一。比如说我们把小车当前位置和终点位置当做信息输入。那么神经网络会记住这张图和终点位置坐标,如果换一幅图就得重新学习。一个更好的设计是输入两个位置的差,这样的话神经网络看到的是终点在小车自身坐标系中的相对位置,如果换一幅图,那么学习到的内容勉强还能用。这样的policy就和具体地图脱钩了。再比如我们设计防撞机制,说距离障碍物低于一个阈值时就要减速,那么如果我们把当前距离和绝对距离阈值输入,那么换一个阈值就得重新学习,因此我们其实可以输入一个相对比例阈值,即当前还差多少就到了阈值该减速了。

  3. 效果验证。在设计好状态空间后,我们需要验证自己设计的状态是不是合理。
    1)模仿学习验证:如果我们已经有了一个比较好的baseline,那我们可以搭建一个policy net用自己设计的状态来验证输出结果是否接近baseline。
    2)直接验证:没有baseline就直接把程序跑完把policy训练出来在比较好坏了。
    3)缺省验证:我们如果已经train得到了一个比较好的policy,那么可以用缺省验证来比较状态中不同信息对policy的影响程度,即控制变量法,其他正常输入把待测试的信息取一个平均值看看train完之后的性能。

reward

DRL是极度依赖于优秀的reward的,因为我们要靠reward来不断诱导神经网络的学习。

  1. 怎么消除对reward的依赖尼?
  1. inverse RL 利用专家示范expert demonstration来学习到reward函数,在用这个reward函数训练RL策略.
  2. Imitation Learning, 抛开reward直接拟合expert的policy
  3. Reward很难设计时,用DL自动学习reward函数,比如在actor-critic框架下再加一个reward函数(state, action直接算reward), see this paper: Deep Reinforcement Learning from Human Preferences.
  1. 主线reward和稀疏回报问题
    一般一个任务的主要任务是很容易理清楚的,所以主线reward是很好设计的。简单任务里我们只需要主线reward就够了,但是复杂的问题里通常情况下主线任务是很难难碰到的,比如说操控机器人打开盒子扔进去一个东西再拿出来再观赏盒子,这一操作的复杂程度使得机器人根本无法在主线任务上前进,因为大部分状态信息相对于主线reward也就都属于间接相关信息。这一类问题称为稀疏回报问题,解决这一问题的方案有很多比如通过鼓励agent探索未见过的状态,提高正样本利用率,或者干脆用遗传算法或进化策略代替RL学习policy网络。本文讨论的是,如何通过reward设计本身来规避稀疏回报问题,并尽可能提高训练效率和最终性能。
    解决方案是,design引导信号来诱导agent学习,也叫 credit assignment。比如说,我们要求小车尽快到终点,可以加一些转弯处罚。一些经验:
    1) 贪婪。实际上,除了主线reward应该提供正向奖励以外,其他辅助reward最好都设置为惩罚项。除非某个子目标与主线事件之间存在强关联,而且该子目标的达成是一次性的或者数量可控,否则不应轻易设置额外奖励项,因为这样很容易诱导agent学习到短视的贪婪策略,只捡芝麻,不要西瓜。
    2) 胆怯。如果惩罚项很多且绝对值相对于主线reward太大,那么agent在探索过程中会收到大量负反馈,从而变得畏首畏尾,学习到各种意想不到的“绥靖”策略。此时,只需要将惩罚项绝对值减小,突出主线奖励的影响,还可以适当降低折扣因子,让agent变成“近视眼”,更多关注眼前利益,忽略长期的负收益期望(靠后的负反馈都被折扣掉了),只要agent“迈开腿”出来探索,就有更大可能遇到主线事件。

3)鲁莽: 某个不希望出现的事件的惩罚太小,比如小车可能为了尽快到达终点宁愿撞到其他小车上也不绕远。
3. Reward Shaping
一个让RL收敛更快的方法是reward shaping:在原有reward基础上增加一项shaping reward,该项代表某种势能函数,与最终目标的差距决定了势能大小。比如说把reward修改为离终点越近奖励越高,那么agent就很容易被引导到G位置,从而大大加速算法收敛。理论上,Ng证明了理想势能函数就是V(s)因为它就是长期收益的期望,policy就是根据它优化的。如果一开始就把完美的V(s)提供给小车,那也就不用学了。对小车到终点的应用而言,用小车当前位置与终点的距离作为势能函数,增加一个惩罚项 -alpha*dist ,离终点较远时惩罚得多一些,较近时惩罚得小一些,这样就能起到reward shaping的作用。

  1. Optimal Reward Problem(ORP),
    另一个问题是,是否存在一组最优reward使得DRL算法在同等条件下收敛最快、性能最高?答案是肯定的,但要想找到它是困难的,该问题在学术界被称为ORP. 解决方案文中也列了一些。

总结一下,reward设计的原则是:尽可能稠密(最好每步都有反馈),能够反映任务目标/子目标逻辑,与状态空间相呼应,控制好各项取值和相对大小,避免异常行为,适时采用reward shaping。当算法选择好,动作空间定义好,状态空间和回报函数都设计好,接下来就该进入训练环节了

训练

在最后一节,作者介绍了DRL training的一些经验。
训练开始前:
最好可视化environment随着action的变化,因为这样可以直观发现问题。
状态空间归一化,reward scaling and clipping r=𝑐𝑙𝑖𝑝(𝑟/(𝑣𝑎𝑟(𝑅)+𝜖),−10,10)
训练进行中:
超参数
Discounting factor: 影响算法的深谋远虑。越大考虑越远但是算法越难收敛。取值原则是,在算法能够收敛的前提下尽可能大。经验公式1/(1-γ)用来估计agent做决策时往前考虑的步数。在一些细粒度任务中,决策时间间隔很短状态变化很少,如果每步都决策得设置很大的折扣函数因为很远状态才会变化很多或者到主线任务。大的折扣函数使得训练很难收敛。因此我们可以延迟决策,即跳几步再决策一次从而使得可以用小的折扣因子,在决策之间使用相同的action.
网络结构。1)Balance表达能力和复杂度,并不是越深越好。DRL算法由于数据效率低下又缺乏直接监督信号,并不擅长以end-to-end的方式训练过深的网络,如果还同时采用了RNN结构,那就更不擅长了。2)on-policy的算法,episodic形式的数据很适合用RNN来挖掘时序信息但是会提升训练难度。因此,如果hi前的经验对当前的判断很参考意义就适合用RNN比如dota,如果是仅依靠当前及时信息就足以判决就没必要了。实践中大家都是折中,将最近几个step的原始信息stack在一起输入,兼顾时序信息和训练难度。如果输入状态信息是ImageNet那样的自然图像,可以像视觉检测应用那样,先用有监督方式预训练一个backbone,然后再放到DRL里finetune
Learning rate. 和DL一样,要淬火。
下面针对于DQN, DDPG, A3C 三种架构分别分享一下经验。

DQN
Buffer size: Replay buffer的大小,通常取1e6, Buffer size过小显然不利于训练, 对于复杂任务, 适当增大buffer size往往能带来性能提升. 但过大的buffer size使得旧样本在buffer中存留时间过长阻碍优化 (prioritized replay buffer).

探索时间占比: 复杂任务的探索时间占比应设得大一些,以保证充分的探索;最终epsilon不宜过大,否则影响模型exploitation得到更好的模型。

目标网络更新频率。通常情况下根据具体问题,参考Q网络的更新周期设定,比如Q网络每1个step更新一次,目标Q网络可以设定每500个step更新一次

DDPG

1.目标网络更新频率: soft-update, (1-τ)target + τmain, τ取很小的值(DDPG paper中建议0.001)限制每次更新幅度。
2. Action + noise: Gaussian or OU 看具体任务。Adaptive parameter noise,抛弃了在输出层叠加噪声的方法,转而采用在policy网络靠近输出的若干层网络参数上叠加噪声,优点是探索更充分,毕竟参数噪声的影响范围更大,而且可以根据实际情况自适应调节探索力度。类似地,我发现参数噪声在有些任务上效果不错,但在另一些任务中不如传统噪声.
3. 此外,值得一提的是actor和critic采用了不同的学习率,且一般critic的学习率比actor大一个数量级,比如前者用1e-3,后者用1e-4。这样做的原因是,用于更新policy网络的梯度完全来自于Q网络,两者地位不是对等的

A3C
作为on-policy方法,A3C算法原理还是超参数设置与前两种DRL框架有很大不同
采样环境数量: 主要是A3C支持多核采样 (不知道后来的同步版本A2C是否支持), 该参数取决于可用的硬件资源。

episode长度: A3C的训练基于episode, 每个episode中间state到episode结束时的Return作为目标值拟合一个V网络,并用V网络作为baseline指导policy网络的更新。一般,每个环境都采集固定长度的episode并返回主进程中拼成一个batch。Episode越长,每次计算梯度时的数据量越大,但消耗内存也越多。Episode长度通常取4096, 2048, 1024等2的次幂,原因是更新网络参数时整个batch还会再分成minibatch(2的次幂比较好分),遍历若干个epoch,从而提高数据利用率,注意minibatch不能太大,否则有可能导致“学不动”的现象。在实际应用中,除了考虑内存开销,episode长度选取也跟任务难度息息相关。以小车导航为例,训练刚开始时agent可能需要探索很久才能幸运地抵达终点,episode长度最好能囊括整个探索过程,这样中间状态与理想状态(到终点)间的演进关系就很容易学习到。当然,episode不可能无限长,如果探索难度实在太高,那也只好提前终止探索,把截断的部分放到下一个episode中。
entropy系数 A3C算法的loss由三部分组成:policy loss,value loss和entropy loss。其中entropy loss项的系数是一个非常重要的超参数,对收敛速度和最终性能有直接影响。我在算法选择篇介绍A3C的探索-利用平衡时,说过随着训练进行policy输出的action分布的variance会越来越小,反映到统计指标上就是entropy越来越小。这本来是一个自然发生的过程,不需要人的干预,然而DRL训练早期往往受到各种local minima的干扰,容易陷入“拣了芝麻丢了西瓜”的怪圈。为了避免模型过早迷失方向,A3C加入了entropy loss用于强迫policy输出不那么“尖锐”的action分布,从而起到加强探索的效果。Entropy系数负责调节这种“强迫”力度,合理的系数既能确保训练早期充分探索从而使模型向正确方向前进,又能使模型在训练中后期充分利用学到的技能从而获得高性能。对于不同任务,最优entropy系数往往各不相同,需要若干次试错才能找到。比如在训练开始后policy entropy快速下降说明模型陷入了局部最优,根本没学到有用技能,这时就应该提升entropy系数;如果训练很长时间policy entropy仍然未下降或者下降缓慢,说明模型探索过头了,学到的知识被随机性淹没,无法进一步用来提升性能,此时应该适当降低entropy系数。
V网络系数 V网络系数是A3C loss中value loss项的系数,通常取0.5(policy loss系数默认是1),在实践中不太需要修改。由于on-policy算法对数据的使用方式是“现采现用,用完就扔”。为了防止policy跑偏,在错误道路上越走越远,需要通过特定方法限制其每次参数更新的幅度。PPO(proximal policy optimization)就属于这一类方法,最早由OpenAI提出。PPO与更早的TRPO,核心思想都是针对更新前后policy输出的KL散度设定阈值,但PPO通过一个简单的clip操作大大简化了运算,兼顾了效率和性能
PPO cliprange(这里就默认采用PPO作为稳定训练的措施) PPO相关的参数主要是cliprange,通常取略大于0的小数,代表使policy更新前后KL散度控制在1-cliprange到1+cliprange之间,超出该范围的梯度直接被忽略(相当于对应数据被弃用)。Cliprange越小训练越稳定,越大越节省数据。一般在训练早期取较小的值,比如0.2,保证训练平稳进行;到训练后期可以适当放大,因为此时policy已经足够优秀,所采集数据中正样本比例非常高,可以放心利用。
GAE factor此外,PPO原paper提出了General Advantage Estimation,相应增加了一个超参数GAE factor,其作用跟折扣因子γ类似,也是在(0,1]内取值,一般都默认取0.95。

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值