声明: 本文来源于知乎专栏,作者授权转载,仅供学习交流,原文链接见文末。
系列5: 状态空间篇
1. 前言
DRL的状态信息代表了agent所感知到的环境信息,以及因自身的action带来的变化。状态信息是agent制定决策和评估其长期收益的依据,而状态设计的好坏直接决定了DRL算法能否收敛、收敛速度以及最终性能,兹事体大,不可不察。通常在一些公共平台,如Gym,大部分domain的状态空间都是现成的,学者们在上边比的是谁的算法收敛快、性能好;然而,在实际项目中,状态空间设计工作却要自己来,根据我的个人经验,增加一个优秀的新状态信息所带来的性能提升明显高于其他方面的工作(如调参),性价比非常高,因此状态空间的优化工作几乎贯彻项目始终。
大家注意到我多次使用“设计”这个词,这不就是特征工程(feature engineering)嘛,9102年都快过完了,怎么还搞这一套?直接上深度神经网络呀!真要那么简单就好了……把所有原始信息一股脑堆砌起来,让神经网络去挑选其中有用的成分并学习它们与决策间的相关性,原理上是没毛病的,可端到端的DRL学习效率实在不太给力,比有监督学习差老远了,即使经过大量训练神经网络能够最终提取到有用信息,因为训练时间的延长也会导致算法实用性的下降。更糟糕的是,一些不相关的干扰信息还会起到反作用。因此,要想在可控时间内得到比较好的policy,的确需要人为筛选出一些好的状态信息,可以是raw information,也可以是经过二次加工的信息,帮助神经网络更轻松准确地建立起决策相关性。
2. 状态设计的四个步骤
那么具体该如何做呢?我把状态空间设计的精髓总结成以下4个步骤:任务分析,相关信息筛选,统一性考虑,效果验证。
2.1 任务分析
任务分析是状态设计的灵魂,好的状态信息建立在对任务逻辑的深入理解之上。客户提出最终目标,优秀的算法工程师需要把这个目标进一步分解,研究该目标的本质是什么,要实现它涉及到哪些重要环节,每个环节有哪些影响因素,每个因素又由哪些信息体现。对任务逻辑的深入分析也有助于我们设计优秀的回报函数(reward),并反哺状态空间的设计。对一个复杂任务的理解,除非天赋异禀或者相关经验丰富,一般都是要经过一段时间的摸爬滚打后才会深入到一定程度,期间还可能不断推翻之前的错误认知,更伴随瞬间顿悟的喜悦,因此要保持足够的耐心。
2. 状态设计的四个步骤
那么具体该如何做呢?我把状态空间设计的精髓总结成以下4个步骤:任务分析,相关信息筛选,统一性考虑,效果验证。
2.1 任务分析
任务分析是状态设计的灵魂,好的状态信息建立在对任务逻辑的深入理解之上。客户提出最终目标,优秀的算法工程师需要把这个目标进一步分解,研究该目标的本质是什么,要实现它涉及到哪些重要环节,每个环节有哪些影响因素,每个因素又由哪些信息体现。对任务逻辑的深入分析也有助于我们设计优秀的回报函数(reward),并反哺状态空间的设计。对一个复杂任务的理解,除非天赋异禀或者相关经验丰富,一般都是要经过一段时间的摸爬滚打后才会深入到一定程度,期间还可能不断推翻之前的错误认知,更伴随瞬间顿悟的喜悦,因此要保持足够的耐心。
为了便于说明,这里引入一个简单任务场景:在一个遍布障碍物的平面区域内有若干辆小车在随机位置待命,现在要求它们以最短时间行驶到各自的终点位置停下来,期间避免与障碍物或者其他小车发生碰撞。我们可以把上述目标分解成三部分:1.达到终点,2.避免碰撞,3.用时短。到达终点要求小车知道自己在哪,还要知道终点在哪;避免碰撞要求小车知道附近障碍物的位置,自己和周围其他小车的位置及运动状态;用时短要求小车少绕路,行驶速度快,尽量避免减速和刹车。
2.2 相关信息筛选
带着以上分析,我们就可以进入下一个环节——相关信息筛选。顾名思义,就是在所有可用信息中找出与任务目标、子目标有关的那些。我们都知道RL任务逻辑最终是以回报函数(reward)为载体呈现的,而RL算法优化的则是该reward系统下的长期累计收益。神经网络的作用是将原始状态信息经过层层非线性提炼后转化为与长期收益高度关联的形式,并进一步指导生成action决策。理想情况下,状态空间应该完全由筛选出的相关信息组成。某个状态信息所代表的事件在越短时间内得到反馈,神经网络就越容易学会如何对其进行加工并建立起决策相关性。按照这个反馈时间的长短,我们还可以粗略地将这些相关信息分为直接相关信息和间接相关信息。
2.2.1 直接相关信息
所谓直接相关信息,就是与某个reward奖励项或惩罚项即时联动的信息。比如为了更有效地避免小车之间发生碰撞,回报函数里设计了“最近小车距离反比”惩罚项 [公式] ,其中 [公式] 是靠近惩罚阈值,当agent与周围最近小车距离 [公式] 小于 [公式] 时,即开始反比惩罚,靠得越近罚得越多。这里的 [公式] 相对于该惩罚项就属于直接相关信息,agent在每一步都能收到与 [公式] 线性相关的反馈,很容易建立起决策相关性。再举一个例子,我们希望小车在电量不足时主动停止工作转而去指定地点充电,除了在reward中设置电量不足的惩罚项,同时也应该在状态空间中增加当前剩余电量,小于设定阈值时即在每步做惩罚。这也属于直接相关信息,没有这个信息,小车是无法建立起电量不足与该惩罚的相关性的,也就无从学会主动去充电。
直接相关信息不仅对DRL算法学习很友好,在有对口reward奖励/惩罚项的前提下,对算法工作者来说也更容易设计。事实上,DRL的状态空间设计往往和reward设计同时进行,为了达到某个目的需要增加一项奖励/惩罚,并相应增加一个或多个直接相关状态信息,帮助模型识别现象与反馈之间的因果关系,这一设计理念很直观也很有效。
2.2.2 间接相关信息
间接相关信息指的是reward中没有即时联动项的状态信息,其所代表的事件需要一段时间后才得到反馈。相对于直接相关信息,DRL利用它们建立决策相关性的难度更高,学习效率更差。比如下图中的游戏画面,agent要通关必须先吃钥匙,假如reward没有专门设置“吃钥匙”的奖励项,那么吃钥匙的好处要等到通关的时候才能体现出来。
再比如小车要学会到达终点,当前位置坐标、朝向、速度、加速度、终点坐标、周围障碍物的分布似乎都与到达终点这一目标有关,假如我们暂时没有针对这个目标做更细化的credit assignment,而只设置了到达终点奖励,那么这些信息就都属于间接相关信息,agent只有经过充分探索后才能发现某时刻这些信息的变化与最终达到终点之间的联系。
间接相关信息通过某些手段可以转化为直接相关信息,从而提高DRL的学习效率。最简单的方法是对任务目标做更详细的credit assignment并增加相应的reward奖励/惩罚项,如果某状态信息恰好与之即时联动,相应状态信息就成为了直接相关信息。还以小车为例,如果在reward中增加靠近终点奖励或远离终点惩罚,那么小车的朝向(配合小车当前坐标和终点坐标)就成为了直接相关信息。更多关于reward函数设计的内容我在下一篇中再详细介绍。
2.2.3 相关信息预处理
无论是直接相关还是间接相关,原始信息都要经过神经网络的提炼才能转化为action输出,提炼难度与学习效率和最终性能呈反向相关。如果我们提前对原始信息做些二次加工,人为提炼出与学习目标更相关的因素,相当于替神经网络干了一部分活儿,虽然不那么elegant,但往往能收到奇效。举个极端例子,直接告诉agent钥匙的相对坐标在哪儿,一定比神经网络通过原始图像更容易学到吃钥匙的操作。由于强化学习的优化目标是折扣累加的长期收益,这使得reward起作用的方式较为间接,无法像有监督学习那样为神经网络的feature extraction提供很好的指导,这也是DRL训练效率低下的根本原因。因此,我们在状态空间上多下一点功夫,DRL学习的难度就降低一点。在资源有限的情况下这很有可能就是训不出来和训得出来的区别,也有可能是性能不达标与性能达标的区别。
2.3 统一性考虑
当我们已经筛选出了所有相关信息,接下来该以何种形式使用它们呢?把他们拉成一组向量塞到神经网络里行不行?当然可以,但那样做只能得到适用于当前特定场景的policy。比如状态信息中包含了其他小车的信息,则训练出的policy只适合特定数量小车的任务,假如车数增加或减少,输入向量维度随之变化,policy就没法用了。因此,我们必须合理设计状态信息使其对环境主要因素的改变有最起码的兼容性,我把它称之为统一性考虑。具体地,这里的统一性又包含形式统一和逻辑统一。
2.3.1 形式统一
为了保证输入向量长度恒定,我们需要找到一种统一形式把不同信息填到对应的位置。比如小车周围装了一圈测距雷达,按固定顺序输出一维距离向量,那么无论把小车放到什么地方,这些信息所代表的含义也不会变;或者采用imagelike的状态表示方式,把地图信息网格化,无论是作为二维channel或拉成一维向量,都能保持外在形式的统一。
针对上述第二种方案,为了将信息离散化到网格点上,不可避免地会带来精度损失。但在实际应用中,只要网格尺寸合理,这样的精度损失是可以接受的。事实上,离散化操作本身会在一定程度上降低学习难度从而带来性能的提升,有paper报告在Montezuma's Revenge游戏里通过离散化agent和环境的信息,DRL模型性能不仅没有下降,反倒提升了30%多。
2.3.2 逻辑统一
状态空间只做到外在形式统一是不够的。比如我们把小车当前位置 [公式] 和终点位置坐标 [公式] 作为状态信息同时输入网络,按照DRL的过拟合天性,神经网络最终会记住这张地图每个坐标处的特征以及在这里通行的最佳路线,policy在这幅地图里测试性能会很高,但换幅地图就完全不能用了。通常情况下,我们并不希望DRL用这种方式获得高性能,而是希望它能学会应对不同地形的通用知识,即使换张地图也至少能达到“勉强能用”的地步,再通过在新地图中finetune即可快速具备实用价值。因此,更合理的方式是将两个绝对坐标合并为一个相对坐标[公式] ,即终点位置在小车坐标系中的坐标,这样就可以使policy与具体地图“脱钩”,从而学习到更加通用的导航知识。可见,要想让网络学到我们希望它学到的知识,前提是输入正确形式的状态信息。
再说回上一节的自动充电任务,如果输入的是绝对电量,而不包含低电量阈值(预警电量),DRL模型需要通过大量探索,根据当前电量与是否被惩罚的经验去摸索出预警电量是多少,并用于指导action的生成。这个隐性阈值会固化到网络参数中,如果客户后续希望提升预警电量,policy就又要用新阈值重新训练了。为了避免这种情况,我们可以把绝对电量改为相对电量(绝对电量/预警电量),能够直接反映当前电量与预警电量的关系,即使预警电量被改变也不影响模型的使用,因为此时固化到网络参数中的知识不再是某个电量阈值而是比例阈值。
2.4 效果验证
当我们设计好状态空间或对原状态空间进行修改后,接下来需要通过实验验证其是否达到预期效果。验证方法可以分为三类:模仿学习验证,直接验证和缺省验证。
2.4.1 模仿学习验证
如果项目已经有一个较好的baseline,可以搭建一个policy网络,专门模仿该baseline在各种状态下的action,如果状态中包含了正确决策所需的相关信息,那么得到的policy性能就会越接近baseline。考虑到有监督学习的高效性,这是验证状态信息有效性的一种较快方式,尤其适用于项目初期一片懵懂的时候。
2.4.2 直接验证
如果没有这样的baseline,那就只能用直接验证了,即用DRL训练一个policy并验证其效果。为了提升效率,也可以只比较训练中途(固定步数、固定样本量)的性能,因为很多时候好状态和差状态的won-lost关系在较早的时候就确定了,当然这必须建立在对特定任务和特定算法训练过程较为熟悉的基础上,在DRL训练中,早期的性能优势无法保持到最后的情形也时有发生。另外可以优先选择收敛速度较快的DRL算法(先不考虑绝对性能),从而快速验证新状态相对旧状态的改进效果。
2.4.3 缺省验证
当我们已经训练得到一个不错的policy时,可以用缺省的方式验证每个状态信息的作用大小,即正常输入其他信息,而将目标信息取合理区间内的定值(如区间中点),测试性能损失的百分比。损失越大说明该状态信息越关键,反之则说明作用越边缘化,有时候甚至会发现性能不降反升,说明该信息有干扰作用,还是去掉的好。缺省验证的意义在于,剔除那些无用或起反作用的状态,为进一步优化关键状态和弱作用状态提供指导。
3. 总结
与学术研究不同,在DRL落地工作中,状态空间设计是如此的重要,所以我用了很长的篇幅探讨了其中各种细节。此外,尽管我已经十分克制,但仍然不得不引入了大量关于回报函数(reward)的描述和设计理念,这是因为在实践中,状态空间和回报函数的设计几乎是水乳交融的,很难做到泾渭分明,往往修改了其中一个,另一个也需要相应做出改变。在下一篇中,我将集中介绍回报函数的设计,当然难免也会涉及到一些状态空间设计的内容,总之,一起服用效果更佳~
系列6:回报函数篇
1. 前言
回报函数(reward)设计在DRL应用中是极其重要的一环,通过将任务目标具体化和数值化,reward就如同一种特殊语言,实现了目标与算法之间的沟通,算法工作者在这里面承担了翻译的角色,翻译的好坏体现了其对任务逻辑的理解深度,决定了agent最终是否能学到期望的技能,并直接影响算法的收敛速度和最终性能。结合上一篇的内容,我们知道DRL算法中reward负责引导神经网络挖掘状态信息中的决策相关因素并经过提炼后用于action的计算生成。既然reward设计这么重要,想必分析起来又会是像状态空间那样的长篇大论吧。AI时代有了深度神经网络,也不缺数据和算力,难道这点人工就不能省下来吗?
2. 非要手工设计吗?
鉴于强化学习算法对优秀reward函数设计的依赖,学术界提出了很多方法改善这一状况。比如逆向强化学习,利用expert demonstration(专家示范)学习到reward函数,再用这个reward函数训练RL策略。此外,还有一大堆模仿学习的方法,干脆抛开reward直接拟合专家策略。以上方法的前提是要有专家数据,不具备普适性,这里就不多说了。
近年来学术界有个趋势,希望通过深度神经网络自动学习reward函数,从而代替手工设计。其中一篇比较有代表性的工作[1],在传统Actor-Critic框架的基础上,又增加了一个Reward网络,输入当前的状(state)和动作(action),输出这一步的reward值。Actor和Critic网络都依据最新的reward网络输出进行优化,而reward网络则依据人类(supervisor)的喜好用有监督的方式进行更新,具体方法是周期性地采集一些episode片段并成对地让人类观看,后者反馈更喜欢哪个片段,再由reward网络拟合这个二分类问题。这篇paper的思想我非常欣赏,现实生活中确实存在很多难以分解和量化的目标,比如让agent学会后空翻,reward就很难设计;有些目标虽然是本身是量化的,但过于笼统难以分解成具体的reward,此时这种方法就很有吸引力。
可惜啊~~,我们在现实中遇到的需求不大可能是第一种情况,比起“不能做→能做”,工业界更喜欢“能做→做得更好”,一般都会给出一个明确的指标用来最大化或最小化。假如这个指标能通过少量采样统计出来或体现出优劣关系,那就适合采用这种方法自动学习reward函数,而且不需要人的介入,全程自动化进行。但如果这个指标必须通过大量采样才能统计出来或者获得可靠的优劣关系,该方法的效率就非常低了,这种情况下就得老老实实地手工设计reward,走传统DRL路线了。
3. 主线reward和稀疏回报问题
当我们拿到一个任务目标,往往能够简单分析就能找出与该目标紧密联系的主线事件,比如小车到达终点的任务中“到终点”就是这样的事件,拳皇里“KO”也是这样的事件,超级马里奥中“通关”还是这样的事件。此时我们就有了第一个reward项,我把它称之为主线reward,一般是正奖励,当主线事件发生时即反馈给agent。理论上,只要有主线reward就可以用强化学习算法进行训练了。在很多简单任务中,agent在探索过程中靠误打误撞就能以一定概率遇到主线事件,通过正反馈尝到甜头后通过更新policy逐渐提升得到奖励的概率直至收敛。可是当问题稍微复杂一些,通过随机方式探索到主线事件(正样本)的概率变得很低,而强化学习算法本身的数据效率不高,只靠这些少得可怜的正样本,算法难以收敛或收敛很慢。下面我引用伯克利RL大神Pieter Abbeel的课程CS294-40中的例子具体说明。
在上图中agent从最左端起始位置S处出发(state=1),目标是到达最右端的G位置(state=5),允许的动作包括向左一格和向右一格。在图中的reward系统下,agent只有到达G才能得到1分的奖励(主线reward),其他状态都没有任何反馈,那么仅靠随机探索agent是很难到达G的,因为中间缺乏有效信号来指导agent向正确的方向前进。在强化学习中,这一类问题被称作稀疏回报问题(Sparse Reward Problem),一直都是DRL领域研究的热点。显然,只定义了主线reward的任务几乎都是稀疏回报问题,对数据效率低下的RL算法而言,学习难度是很大的。
当稀疏回报问题遇上高难度探索(Hard Exploration)问题,DRL算法收敛更是难上加难,几乎是不可能完成的任务。比如让机器人学会打开盒子,抓起木块放到盒子里,然后再把盒子盖上,如果只在成功完成这一系列动作的时候才给出奖励,那么用一般的DRL算法和探索策略根本不可能学会目标技能,因为正样本产生的概率跟闭着眼用针尖扎到平面上一点的概率差不多,可以认为是0。
针对稀疏回报问题,学术界提出了很多方法,比如通过鼓励agent探索未见过的状态,提高正样本利用率,或者干脆用遗传算法或进化策略代替RL学习policy网络。这些方法不在本篇的讨论范围内,我们关心的是如何通过reward设计本身来规避稀疏回报问题,并尽可能提高训练效率和最终性能。
此外,联系上一篇状态空间设计的内容,由于主线事件通常难以一蹴而就,大部分状态信息相对于主线reward也就都属于间接相关信息,这也从另一个角度解释了为什么在稀疏回报下算法训练难度高。
4. 目标分解和辅助reward
既然只有主线reward不行,我们接下来就要将原始任务目标进一步分解成子目标,并分别给予合理的奖励或惩罚,从而达到引导agent趋利避害提高主线事件发生概率的目的。学术界一般称该过程为credit assignment,credit意译过来就是功劳,说的是某个子目标在达成总目标的过程中起了多大作用,是正向作用还是负向作用。这些子目标对应的reward可以称之为辅助reward,它们使reward不再稀疏。通常情况下,为了保证主线奖励的核心地位和吸引力,各种辅助reward的绝对值都设得相对较小,以免喧宾夺主。
4.1 目标分解实例
Agent在环境中探索时需要获得反馈,即刚刚的决策好不好,反馈越及时学得越快,理想情况是每一步都有反馈。还以小车导航到终点的应用为例,除了抵达终点+10分,如果每次靠近终点也+1分,那么小车在抵达终点之前就学会主动靠近终点,这样探索到抵达终点的概率也大大提高了,DRL算法收敛速度自然会加快。
除了抵达终点,小车还要避免与障碍物和其他小车发生碰撞,我们还要对碰撞事件做出惩罚。为了使agent更好地学会避免碰撞,我们除了对已经发生的碰撞事件给予惩罚,还可以再增加一个预防式的靠近惩罚,并利用状态空间里的直接相关信息——与最近邻居的距离,提高算法学习效率,具体可以参考状态空间篇。
辅助reward的设计建立在对任务逻辑的深刻分析和理解之上,有很多细节都会对最终目标的实现产生正向或负向的影响,值得我们深入挖掘。比如,为了使小车尽快到达终点,就要求少绕路,而绕路的典型表现是转弯多,于是可以增加对转弯的惩罚。类似这样的链式思考有助于找到更好的辅助reward,帮助降低学习难度和提升最终性能。
此外,由于将最终目标分解成了子目标,在设计对应辅助reward时往往很容易找到与之即时联动的直接相关状态信息,或者相关性较强的间接相关信息。事实上,我们每设计一个reward项,就应该回过头去检查状态空间中是否包含了直接或间接相关信息,已经包含的信息是否足够直接高效,有没有改进的空间。
4.2 杜绝异常行为
OK,让我们来捋一捋目前的reward项:抵达奖励,靠近终点奖励,碰撞惩罚和转弯惩罚。Reward项一多,我们就要特别注意它们之间的相对大小。首先,应该避免某个(些)reward项的绝对值过大,以至于淹没其他reward项的影响,必要时应使用系数加以调控;其次,应该避免reward项的不合理取值及多项reward之间的不合理相对大小,导致agent学到异常行为。因为不合理reward造成的常见异常行为主要包括三种类型:鲁莽、贪婪和胆怯,怎么感觉我在说炒股呢~~~
4.2.3 鲁莽
鲁莽行为指的是reward中漏掉了针对某个不希望出现的事件的惩罚项或者惩罚力度太小,被其他reward项盖过,导致agent无法学到主动规避该事件或者权衡利弊后仍然选择接受该事件的惩罚以换取更大收益。比如下图中金币搜索任务中,设计者忘了给予进入岩浆的惩罚,结果机器人为了尽快得到金币而甘愿“赴汤蹈火”;在小车导航的例子中,碰撞惩罚相对于远离惩罚过小,小车可能为了尽快到达终点宁愿撞到其他小车上也不愿意绕远。
4.2.1 贪婪
靠近终点奖励使reward变稠密了,但这样做就够了吗?我们说过RL追求的是长期收益,事实上对小车来说收益最高的选择不是尽快抵达终点,而是不断重复“靠近-远离”的动作,如此一点点地累加,收益远超过抵达终点的一锤子买卖!很显然,agent钻了reward设计漏洞的空子,变得不思进取,贪得无厌。为了防止这种情况发生,我们还要对原地不动或远离终点的行为进行惩罚,而且相对于靠近奖励,扣分太少也不行,否则agent仍然会发现钻空子是划算的。一劳永逸的办法是,将靠近终点的正向奖励改成微小惩罚,绝对值小于原地不动或远离惩罚,这样做的好处是不仅不给agent钻空子的机会,而且还能督促小车尽快向终点行驶。
再比如在蒙特祖玛的复仇中,要想通关(主线事件,+10)必须先吃到钥匙,为了鼓励agent吃钥匙我们还可以为这个子目标提供专门的奖励(+1)。这种情况下房间只有一把钥匙还好,但如果到处都是钥匙呢?Agent很可能会变得乐不思蜀,一直留在房间里找新的钥匙,忘记通关这回事了。如果真是这样,那就不如不设吃钥匙奖励,只保留主线奖励,由Agent自己去发掘通关与吃钥匙之间的内在联系。
实际上,除了主线reward应该提供正向奖励以外,其他辅助reward最好都设置为惩罚项。除非某个子目标与主线事件之间存在强关联,而且该子目标的达成是一次性的或者数量可控,否则不应轻易设置额外奖励项,因为这样很容易诱导agent学习到短视的贪婪策略,只捡芝麻,不要西瓜。
4.2.2 胆怯
与贪婪相反的另一个异常行为是胆怯,如果惩罚项很多且绝对值相对于主线reward太大,那么agent在探索过程中会收到大量负反馈,从而变得畏首畏尾,学习到各种意想不到的“绥靖”策略。比如在小车到终点的例子中,假如碰撞惩罚和转弯惩罚绝对值过大,agent有可能宁愿选择原地不动,这是因为训练初期policy很差,需要经历大量转弯和碰撞后才可能出现主线事件(到达终点),而收到的负反馈完全湮没了主线奖励,因此在agent看来原地不动的长期累计收益暂时不比到终点差,尽管只是暂时的,但agent很可能陷在这个局部最优里出不来了。
在上述情况下,你会发现只需要将惩罚项绝对值减小,突出主线奖励的影响,其他什么也不用干,DRL模型就能顺利收敛了。当然,还可以适当降低折扣因子,让agent变成“近视眼”,更多关注眼前利益,忽略长期的负收益期望(靠后的负反馈都被折扣掉了),只要agent“迈开腿”出来探索,就有更大可能遇到主线事件,并在主线reward的奖励下学习到目标技能。折扣因子的设置技巧我将在训练篇中详细介绍。
4.3 Reward Shaping
把任务目标分解得足够细,又避开了上述各种坑,这样就完美了吗?并没有~~如果你读过Andrew Ng在1999年发表的关于reward shaping的paper,你就会发现还可以让RL算法收敛得更快一些。Reward shaping技术的证明这里就不赘述了,喜欢手推公式的朋友可以去读原著。我大概说下原理,在原有reward基础上增加一项shaping reward,该项代表某种势能函数,与最终目标的差距决定了势能大小。对于我们上一节举过的例子,如果把reward修改为下图中的形式,agent每向右移动一格都会获得奖励,且离G越近奖励越高,那么agent就很容易被引导到G位置,从而大大加速算法收敛。
Ng从理论上证明了理想势能函数就是V(s),这很好解释,我们前边说过V(s)是对长期收益的期望,policy就是根据它优化的,如果一开始就把完美的V(s)提供给小车,那也就不用学了。对小车到终点的应用而言,用小车当前位置与终点的距离作为势能函数,增加一个惩罚项 [公式] ,离终点较远时惩罚得多一些,较近时惩罚得小一些,这样就能起到reward shaping的作用。此外,参考上一篇状态空间设计的内容,你会发现增加的惩罚项可以与状态空间中描述小车与终点相对位置的信息即时联动,从而使后者由间接相关信息转变为直接相关信息,这就从另一个角度解释了reward shaping为什么能提高算法训练的效率。
Optimal Reward Problem
看到这里你可能会问,针对特定任务,比如小车导航到终点,是否存在一组最优reward使得DRL算法在同等条件下收敛最快、性能最高?答案是肯定的,但要想找到它是困难的,该问题在学术界被称为Optimal Reward Problem(ORP),解决方案包括暴力搜索[2]、基于在线策略梯度的PGRD[3]、分层强化学习[4]、遗传算法[5]、Bayes方法[6]等等,有兴趣的朋友可以找来相关paper读一读,相关参考文献我列到最后。
总结
总结一下,reward设计的原则是:尽可能稠密(最好每步都有反馈),能够反映任务目标/子目标逻辑,与状态空间相呼应,控制好各项取值和相对大小,避免异常行为,适时采用reward shaping。当算法选择好,动作空间定义好,状态空间和回报函数都设计好,接下来就该进入训练环节了。
参考
- Christiano, P. F.; Leike, J.; Brown, T. B.; Martic, M.; Legg, S.; and Amodei, D. 2017. Deep Reinforcement Learning from Human Preferences. Neural Information Processing Systems: 4299-4307.
- Sorg, J.; Singh, S. P.; and Lewis, R. L. 2010. Internal Rewards Mitigate Agent Boundedness. International Conference on Machine Learning: 1007-1014.
- Sorg, J.; Lewis, R. L.; and Singh, S. P. 2010. Reward Design via Online Gradient Ascent. Neural Information Processing Systems: 2190-2198.
- Bratman, J.; Singh, S. P.; Sorg, J.; and Lewis, R. L. 2012. Strong Mitigation: Nesting Search for Good Policies within Search for Good Reward. Adaptive Agents and Multi Agents Systems: 407-414.
- Niekum, S.; Barto, A. G.; and Spector, L. 2010. Genetic Programming for Reward Function Search. IEEE Transactions on Autonomous Mental Development 2(2): 83-90.
- Hadfield-Menell, D.; Milli, S.; Abbeel, P.; Russell, S.; and Dragan, A. D. 2017. Inverse Reward Design. Neural Information Processing Systems: 6765-6774.
系列7: 训练篇
为了保证DRL算法能够顺利收敛,policy性能达标并具有实用价值,结果有说服力且能复现,需要算法工作者在训练前、训练中和训练后提供全方位一条龙服务。我记得GANs刚火起来的时候,因为训练难度高,有人在GitHub上专门开了repository,总结来自学术界和工业界的最新训练经验,各种经过或未经验证的tricks被堆砌在一起,吸引了全世界AI爱好者的热烈讨论,可谓盛况空前。在玄学方面,DRL算法训练有得一拼。但毕竟在科研领域没有人真的喜欢玄学,只有久经考验的一般化规律才能凝结成知识被更多的人接受和推广。本篇接下来的内容融合了许多个人经验和各种参考资料,算是在DRL训练“去玄学”化上做出的一点微不足道的努力。
1. 训练开始前
1.1 环境可视化
如果条件允许,开始训练前最好先可视化一个随机环境,观察是否会出现你希望的状态(即上一篇里的主线事件)。如果靠随机选择action都能以一定概率探索到目标状态,那说明该任务难度比较低,心里就可以更有底;如果从来不会出现目标状态,说明该任务难度较高,需要在状态空间和reward函数设计时特别下功夫,从而更好地引导agent向目标状态前进。
1.2 数据预处理
你还可以实时打印出state和reward,看看它们是否在合理范围内取值,是否存在幅值过大的情况,如果是则需要增加必要的归一化操作。事实上,我推荐无条件进行状态空间归一化和reward rescale & clipping,实践证明这两个操作无论在收敛速度还是最终性能上都会带来明显提升。前一个操作很好理解,我只介绍一下reward rescale & clipping,该操作尤其适合基于episode的A3C/A2C/PPO算法,参考形式为r=clip(r/(std(Return)+ [公式] ),-10,10),其中Return = [公式] ,是一段episode内reward的折扣累加和,也就是V网络拟合的对象,而V网络输出又为policy优化提供参考,使用该值的统计方差对reward进行rescale,可以反过来有效降低Return的variance,有助于V网络和policy网络进行更加无偏地学习。训练过程中通常采用Return的running std来rescale当前reward。最外层的clip操作可以滤除那些绝对值过大的reward,作用类似。
注意reward只能进行rescale,而不能整体平移(减去均值)。回报函数中各项reward的符号以及它们之间的相对大小唯一确定了回报函数的实际功能,各项reward的整体缩放对其没有影响,但整体平移会改变这种相对大小,也就改变了回报函数的功能。事实上,哪怕是clip操作也在一定程度上存在这种问题,但通常影响不大。
2. 训练进行中
2.1 拥抱不确定性
终于要开始调参了!如果你做过CV项目,会发现相对来说DRL训练的不确定性更高,可复现性更差。这是因为DRL算法不仅超参数多,而且对它们非常敏感,这里贴张图给大家感受一下。
上图是三个DRL算法(纵向)在五个Atari游戏(横向)中的得分随学习率变化的趋势。可以看到,以10倍为单位,高性能所对应的学习率区间普遍很窄,要达到最优性能真得靠地毯式搜索。其实原作者本意是想通过这张图表明他们的方法对超参数变化抵抗力较好……,况且这还只是针对学习率这一个超参数。
当我们刚开始尝试用DRL算法解决一个全新问题时,性能好坏甚至都是其次,能否收敛才是最关键的。牛逼闪闪的OpenAI Five都听说过吧?其团队成员在接受采访时承认,他们第一次将训练跑起来后因为心里实在没底,干脆全体度假去了,回来后打开屏幕发现竟然收敛了,上帝保佑!
尽管DRL对超参数如此敏感,也没有必要过分悲观。当我们在心理上接受了这一事实,并开始潜心研究时,就会发现DRL训练还是有迹可循的,尤其是随着实际经验的积累和对算法本质理解的不断深入,将每个超参数的作用都了然于胸,那么训练出优秀policy的可能性就会大很多。接下来我以DQN,DDPG和PPO为例,介绍一下其中的主要超参数和调参技巧。
2.2 DRL通用超参数
有些超参数不是某个算法所特有,而是DRL普遍使用的,而且作用原理和设置依据都差不多,我放到最前面集中介绍。典型的通用超参数包括折扣因子、网络结构和学习率。
2.2.1 折扣因子
2.2.1.1 作用原理
折扣因子通常以符号γ表示,在强化学习中用来调节近远期影响,即agent做决策时考虑多长远,取值范围(0,1]。γ越大agent往前考虑的步数越多,但训练难度也越高;γ越小agent越注重眼前利益,训练难度也越小。我们都希望agent能“深谋远虑”,但过高的折扣因子容易导致算法收敛困难。还以小车导航为例,由于只有到达终点时才有奖励,相比而言惩罚项则多很多,在训练初始阶段负反馈远多于正反馈,一个很高的折扣因子(如0.999)容易使agent过分忌惮前方的“荆棘丛生”,而宁愿待在原地不动;相对而言,一个较低的折扣因子(如0.9)则使agent更加敢于探索环境从而获取抵达终点的成功经验;而一个过低的折扣因子(如0.4),使得稍远一点的反馈都被淹没了,除非离终点很近,agent在大多数情况下根本看不到“光明的未来”,更谈不上为了抵达终点而努力了。
2.2.1.2 选取方法
总之,折扣因子的取值原则是,在算法能够收敛的前提下尽可能大。在实践中,有个经验公式1/(1-γ),可以用来估计agent做决策时往前考虑的步数。根据对特定任务的分析,合理选择γ值,避免“近视”和“远视”。比如可以根据观察或统计agent到达终点所需的步数分布,选择合适的步数使得agent在该步数内的探索下有一定概率到达终点(正样本),注意这个概率越高训练难度就越小,然后利用经验公式把该步数换算成γ即可。
2.2.1.3 Frame Skipping
上述折扣因子的选择方法并非无往不利,有时我们会面临这样的窘境:无法设置合理的γ在“近视”和“远视”间找到满意折中,常见于“细粒度”复杂任务。复杂决定了agent需要看得很远才能做出合理决策,而“细粒度”指agent决策间隔很短以至于一段较长的episode只对应较少的agent状态变化。仍以小车导航为例,0.1s的决策间隔显然满足了实时防碰撞的机动性要求,但也大大延长了episode长度,即到达终点所需步数。如果agent平均需要1min才能到达终点,那就要求向前考虑1min/0.1s=600步,按照经验公式计算合理的折扣因子γ≈1-1/600=0.998,如此高的折扣因子+如此长的episode,训练难度可想而知。
假如我们在保证足够机动性的前提下适当延长决策间隔,比如0.5s,中间4帧重复上一次决策的action不变,相当于跳了几帧达到“快进”效果,从而使episode长度大大缩短,训练难度也直线下降,即使采用较高折扣因子也能顺利收敛。通过这个例子我们也可以知道,在DRL中agent“看得远”表面上指的是向前考虑的步数多,实质上是指agent向前考虑的系统动态演化跨度大。
2.2.2 网络结构
DRL算法中的网络结构也属于超参数,然而与CV任务不同,DRL绝不应该片面追求网络的复杂化,否则你会发现训练根本无法收敛。对于网络结构的选择,DRL有自己的规矩——契合状态,够用就好。前者针对网络类型,后者针对网络深度。
2.2.2.1 网络类型
网络类型的选择主要取决于状态空间设计,如果状态信息是向量式的,即一组拉成一维的标量,比如位置、角度、速度等,那就适合采用全连接(MLP)网络;如果状态信息是imagelike的,比如图像,或者其他以二维形式重组的信息,就适合采用卷积神经网络(CNN)。实际应用中往往同时包含这两种状态信息,因此网络类型也可以既有CNN也有MLP,处理完各自对应的输入信息后,在高层通过concat操作汇集在一起,再通过若干层全连接,最后输出action或Q/V值。
对于on-policy算法,episode形式的数据天然适合采用RNN来挖掘更多时序信息,但同时也会显著提高训练难度,用与不用取决于决策对时序相关性的依赖程度。换句话说,如果之前的经验对当前决策很有参考意义(比如Dota)就适合用RNN,反之仅依靠即时信息做应激式决策就足以应付就没必要用RNN。实践中经常采取折中方案,将最近几个step的原始状态信息叠加到一起作为当前时刻的实际状态信息输入policy,既可以挖掘一定范围内的时序信息,又避免增加训练难度。
2.2.2.2 网络深度
至于网络深度,千万不要认为越深越好,虽然深层网络的表征能力更强,但训练难度非常高,更适合有监督训练。DRL算法由于数据效率低下又缺乏直接监督信号,并不擅长以end-to-end的方式训练过深的网络,如果还同时采用了RNN结构,那就是相当不擅长了。除非你有DeepMind或OpenAI那样的硬件资源,否则还是现实点好。其实多读几篇DRL方向的paper就会发现,所谓deep往往只是2-3层MLP或4-5层CNN,虚张声势的背后就是这么知趣。
当然,如果任务逻辑和状态信息确实非常复杂,浅层网络不足以提供所需的特征提取和加工能力,那么可以考虑适当加深网络,但仍应以够用为准则,不可矫枉过正。我曾经试过把已经work的3层MLP改成10层,发现根本就不收敛或收敛极慢,后来在各层中加了类似ResNet的跳线,勉强收敛,但相同训练量下性能还不如3层网络。如果输入状态信息是ImageNet那样的自然图像,可以像视觉检测应用那样,先用有监督方式预训练一个backbone,然后再放到DRL里finetune。
2.2.3 学习率
从整个AI技术来看,学习率是如此的平淡无奇,相关调参技巧早就被研究透了。毕竟DRL算法里的学习率也遵循同样的基本法——大了收敛快,稳定性差,且后期影响性能;小了收敛慢,浪费时间。学习率常用的淬火操作也同样可以应用到DRL中。当然,对于不同DRL算法而言,学习率也可能有各自的特点,如有必要,我会在下文介绍DRL特色超参数的时候顺带多说几句。
2.3 DRL特色超参数
2.3.1 DQN
DQN的特色超参数主要有:buffer size,起始训练时间,batchsize,探索时间占比,最终epsilon,目标网络更新频率等。
Buffer size指的是DQN中用来提高数据效率的replay buffer的大小。通常取1e6,但不绝对。Buffer size过小显然是不利于训练的,replay buffer设计的初衷就是为了保证正样本,尤其是稀有正样本能够被多次利用,从而加快模型收敛。对于复杂任务,适当增大buffer size往往能带来性能提升。反过来过大的buffer size也会产生负面作用,由于标准DQN算法是在buffer中均匀采集样本用于训练,新旧样本被采集的概率是相等的,如果旧样本或者无效样本在buffer中存留时间过长,就会阻碍模型的进一步优化。总之,合理的buffer size需要兼顾样本的稳定性和优胜劣汰。顺便说一句,针对“等概率采样”的弊端,学术界有人提出了prioritized replay buffer,通过刻意提高那些loss较大的transition被选中的概率,从而提升性能,这样又会引入新的超参数,这里就不做介绍了。
起始训练时间的设置仅仅是为了保证replay buffer里有足够的数据供二次采样,因此与batchsize有直接关系,没啥可说的。Batchsize指的是从replay buffer中二次采样并用于梯度计算的batch大小,和CV任务中的设定原则基本一致,即兼顾训练稳定性和训练速度,也没啥好说的。
探索时间占比和最终ε共同决定了DQN探索和利用的平衡。ε-greedy策略在训练开始的时候,随机选择action的概率ε=1,探索力度最大;随着训练进行ε逐渐线性下降直至达到最终epsilon保持恒定,之后DQN的训练将以利用为主而只保留少量探索。因此,最终ε取值在区间[0,1]内靠近0的一端。探索时间占比指的是ε从1下降到最终ε的时间占总训练时间的比例,在(0,1)内取值,用来调节以探索为主到以利用为主的过渡。通常来说,复杂任务的探索时间占比应设得大一些,以保证充分的探索;最终ε不宜过大,否则影响模型最终阶段“好上加好”的性能冲刺,因为最好的状态往往是在足够好的Q网络指导下才能探索到的,训练后期过强的探索干扰了习得知识的利用,也就阻碍了性能的进一步提升。
标准DQN引入了一个延迟更新的目标网络用来计算Q的目标值,避免Q网络误差的“自激效应”,并借此来提高训练稳定性。目标网络更新频率就是用来控制这个延迟程度的,时间到了就把Q网络的参数整个复制过来。通常情况下根据具体问题,参考Q网络的更新周期设定,比如Q网络每1个step更新一次,目标Q网络可以设定每500个step更新一次。
2.3.2 DDPG
DDPG的特色超参数主要包括:buffer size,batchsize,目标网络软更新参数τ,探索噪声等。其中很多超参数与DQN类似,比如buffer size和batchsize,这里就不重复介绍了。
DDPG也使用了目标网络(目标Q网络和目标Policy网络)稳定训练,不同的是DDPG的目标网络与主网络更新频率相同,稳定效果来自于软更新(soft-update),即(1-τ)target + τmain,τ取很小的值(DDPG paper中建议0.001)限制每次更新的幅度。
DDPG值得特别介绍的是探索噪声及其参数。由于policy网络输出确定性action,DDPG的探索依靠在输出action空间叠加噪声来实现。可选的噪声类型主要包括Gaussian噪声和DDPG paper推荐的ou噪声(Ornstein-Uhlenbeck),后者相对于前者主要是增加了噪声强度逐渐衰减的功能。这两种噪声的主要参数是噪声方差,方差越大探索力度越强。虽然论文推荐使用ou噪声,但我在实践中发现ou噪声并不一定比Gaussian噪声效果好,还是要看具体任务。
后来DeepMind又提出了adaptive parameter noise,抛弃了在输出层叠加噪声的方法,转而采用在policy网络靠近输出的若干层网络参数上叠加噪声,优点是探索更充分,毕竟参数噪声的影响范围更大,而且可以根据实际情况自适应调节探索力度。类似地,我发现参数噪声在有些任务上效果不错,但在另一些任务中不如传统噪声。综上所述,关于不同噪声的优劣没有确定性结论(局限于我的个人经验),具体选择哪种噪声,还要实际试过才知道。
此外,值得一提的是Q网络和policy网络采用了不同的学习率,且一般Q网络的学习率比policy网络大一个数量级,比如前者用1e-3,后者用1e-4。这样做的原因是,用于更新policy网络的梯度完全来自于Q网络,两者地位不是对等的。
2.3.3 PPO
作为on-policy方法,PPO与前两种DRL框架有很大不同,无论是算法原理还是超参数设置。PPO的特色超参数包括:采样环境数量,episode长度,entropy系数,V网络系数,GAE factor,PPO cliprange等。
并行采样的环境数量越多,整体的探索效率越高,绝对收敛时间越快,该参数的设置主要取决于可用的硬件资源。
PPO的训练基于episode(或trajectory),将其中每个中间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中。
PPO算法的loss由三部分组成:policy loss,value loss和entropy loss。其中entropy loss项的系数是一个非常重要的超参数,对收敛速度和最终性能有直接影响。我在算法选择篇介绍PPO的探索-利用平衡时,说过随着训练进行policy输出的action分布的variance会越来越小,反映到统计指标上就是entropy越来越小。这本来是一个自然发生的过程,不需要人的干预,然而DRL训练早期往往受到各种local minima的干扰,容易陷入“拣了芝麻丢了西瓜”的怪圈。为了避免模型过早迷失方向,PPO加入了entropy loss用于强迫policy输出不那么“尖锐”的action分布,从而起到加强探索的效果。Entropy系数负责调节这种“强迫”力度,合理的系数既能确保训练早期充分探索从而使模型向正确方向前进,又能使模型在训练中后期充分利用学到的技能从而获得高性能。对于不同任务,最优entropy系数往往各不相同,需要若干次试错才能找到。比如在训练开始后policy entropy快速下降说明模型陷入了局部最优,根本没学到有用技能,这时就应该提升entropy系数;如果训练很长时间policy entropy仍然未下降或者下降缓慢,说明模型探索过头了,学到的知识被随机性淹没,无法进一步用来提升性能,此时应该适当降低entropy系数。
V网络系数是PPO loss中value loss项的系数,通常取0.5(policy loss系数默认是1),在实践中不太需要修改。
由于on-policy算法对数据的使用方式是“现采现用,用完就扔”。为了防止policy跑偏,在错误道路上越走越远,需要通过特定方法限制其每次参数更新的幅度。PPO与更早的TRPO类似,核心思想都是针对更新前后policy输出的KL散度设定阈值,但PPO通过一个简单的clip操作大大简化了运算,兼顾了效率和性能。PPO相关的参数主要是cliprange,通常取略大于0的小数,代表使policy更新前后KL散度控制在1-cliprange到1+cliprange之间,超出该范围的梯度直接被忽略(相当于对应数据被弃用)。Cliprange越小训练越稳定,越大越节省数据。一般在训练早期取较小的值,比如0.2,保证训练平稳进行;到训练后期可以适当放大,因为此时policy已经足够优秀,所采集数据中正样本比例非常高,可以放心利用。此外,PPO使用了GAE来估计advantage,相应增加了一个超参数GAE factor,用于在bias和variable之间寻求平衡,也是在(0,1]内取值,一般都默认取0.95。
2.4 给DRL初学者的建议
以热门平台作为切入点。热门平台维护频率高,关注度高,遇到问题容易找到解决方案。比如在OpenAI Gym平台上找些简单的任务多练手,baselines里提供了大量参考代码。使用现成代码训练的最大好处是可以排除bug的干扰,把注意力都放在调参上,这对于初学者非常重要。
不要迷信默认超参数。在实际应用中可以先采用参考代码里的默认超参数,但一定要记住它们不是万能的。可以用tensorboard显示出各种训练曲线,理解其中主要曲线的含义和作用,并根据这些曲线判断超参数设置是否合理,应该朝哪个方向调整。
重视首次成功经验,学会简化问题。实践多了你会发现,对于特定Domain和特定算法,最优超参数组合分布都各有特点,最困难也最关键的是首次训练,一旦有了成功经验,后续根据观察结果做些微调就能得到高性能模型了。如果原任务训练难度太高,可以先尝试做适当简化,待成功收敛后再逐渐恢复任务难度。比如要实现任务目标A,必须满足条件B,C,D…,可以先暂时去掉对C,D,…的要求,只保留B,这样探索到A的概率就会显著提升,算法训练难度直线下降,待算法收敛并获得一定的经验后再逐步恢复所有条件。
保持耐心。DRL训练本来就挺慢的,很多时候除了等待什么都不用做。除非你对相关Domain的算法训练流程已经很熟悉,否则不要轻易断定算法不收敛,可以等等再说。也不要整天一动不动地盯着屏幕发呆,既浪费时间,更浪费生命,间歇式检查一下就好。
3. 训练收敛后
当你发现policy已经可以如预期的那样完成任务了,先不要忙着喜形于色,你还需要做些检查和分析工作以确保policy性能达到了最优。以A3C为例,你至少应该:
1. 观察Value网络对Returns拟合的精度如何,value loss是否还有进一步下降的空间?
Value网络越精确,由其计算得到的advantage越有意义,也就越有利于policy的优化。注意精度和loss都是相对概念,与reward函数中各项的绝对值息息相关。一般说来,在DRL中对reward进行等比例缩放不会改变policy的最终特性,即(+10,-2,-1,-0.5)与(+100,-20,-10,-5)的作用是一样的,但体现在value loss上就差了10倍。对拟合精度更可靠的评估标准是explained variance,计算公式是 [公式] ,取值区间 [公式] ,该值越接近1说明拟合精度越高。建议训练过程中将该值实时打印到tensorboard中,并不断监测Value网络的质量。
2. 观察entropy是否处在合理范围内,相对于action维度是否过高或过低?
假如policy输出10维categorical分布,其entropy有两种极端情况:(1) 完全随机,每个维度概率均为0.1,此时entropy最大等于10[-0.1log(0.1)]=2.3;(2) 完全确定,其中一维为1.0其余都是0.0,此时entropy最小等于0。整个训练过程,entropy从2.3开始逐渐下降,当训练收敛后,entropy应该稳定在较低水平。如果太高则说明policy对决策信心不足,如果不是任务本身太复杂那就是entropy系数过大造成的,应该适当降低该系数增加exploitation的力度,很有可能继续提升模型性能。当然,entropy很少能降到0,除非是极其简单的任务。
4. 总结
经过前后近一个月零零星星的整理,这篇又臭又长的训练篇终于快要结束了,连我自己都觉得枯燥透顶,如果有哪位读者能坚持读到这里,我敬你是个勇士!我也时常怀疑写这些东西到底有没有意义,毕竟包括DRL在内的深度学习调参技巧往往琐碎而不成体系,很难总结得面面俱到,更何况新算法还在源源不断地涌现,旧的知识经验正在迅速“贬值”,就像现在有了Soft Actor-Critic,谁还用DDPG啊。最重要的是,假如读者不经过亲身实践,直接看这些干巴巴的总结,作用真心不大。对我自己来说,就权当备忘吧~
事实上,当你通过广泛阅读和动手实践,对各种DRL算法原理有了深入理解,对各种超参数的作用了然于胸,自然而然就会形成自己的调参方法论。只要算法收敛,性能达标,项目验收,调参的细节没那么重要。此外,调参工作毕竟只停留在“术”的层面,而我们应该追求的是算法之“道”,孰轻孰重每个人都要心里有数。祝愿每一个算法工程师最终都能做到“调尽千参,心中无参”。