- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
强化学习里的 env.reset() env.step() 就是训练环境。其编写流程如下:
先写一个简化版的训练环境。把任务难度降到最低,确保一定能正常训练。记录正常训练的智能体的分数,与随机动作、传统算法得到的分数做比较。 DRL算法的分数应该明显高于随机动作(随机执行动作)。DRL算法不应该低于传统算法的分数。如果没有传统算法,那么也需要自己写一个局部最优的算法 。
评估策略的性能: 大部分情况下,可以直接是对Reward Function 给出的reward 进行求和得到的每轮收益episode return作为策略评分。有时候可以需要直接拿策略的实际分数作为评分 需要保证这个简化版的代码:高效、简洁、可拓展 。
让任务难度逐步提高,对训练环境env 进行缓慢的修改,时刻保存旧版本的代码同步微调 Reward Function,可以直接代入自己的人类视角,为某些行为添加正负奖励。注意奖励的平衡(有正有负)。注意不要为Reward Function 添加太多额外规则,时常回过头取消一些规则,避免过度矫正。 同步微调 DRL算法,只建议微调超参数,但不建议对算法核心进行修改。因为任务变困难了,所以需要调整超参数让训练变快。同时摸清楚在这个训练环境下,算法对 哪几个超参数是敏感的 。有时候为了节省时间,甚至可以为 off-policy 算法保存一些典型的 trajectory(不建议在最终验证阶段使用)。 每一次修改,都需要跑一下记录不同方法的分数,确保:随机动作 < 传统方法 < DRL算法。这样才能及时发现代码逻辑上的错误。要极力避免代码中出现复数个的错误,因为极难排查.
尝试慢慢删掉Reward Function 中一些比较复杂的东西,删不掉就算了。 选择 高低两组超参数 再跑一次,确认没有优化空间.
【网络宽度、网络层数】 越复杂的函数就需要越大容量的神经网络去拟合。在需要训练1e6步的任务中,我一般选择 宽度 128、256 ,层数小于8的网络(请注意,乘以一个w算一层,一层LSTM等于2层)。使用ResNet等结构会有很小的提升。一般选择一个略微冗余的网络容量即可,把调整超参数的精力用在这上面不划算,我建议这些超参数都粗略地选择2的N次方, 。
因为:防止过度调参,超参数选择x+1 与 x-1并没有什么区别,但是 x与2x一定会有显著区别
2的N次方大小的数据,刚好能完整地放进CPU或GPU的硬件中进行计算,如Tensor Core
过大、过深的神经网络不适合DRL,
因为:深度学习可以在整个训练结束后再使用训练好的模型。
而强化学习需要在几秒钟的训练后马上使用刚训好的模型。
这导致DRL只能用比较浅的网络来保证快速拟合(10层以下)
并且强化学习的训练数据不如有监督学习那么稳定,无法划分出训练集测试集去避免过拟合,
因此DRL也不能用太宽的网络(超过1024),避免参数过度冗余导致过拟合
【dropout、批归一化】 她们在DL中得到广泛地使用,可惜不适合DRL。如果非要用,那么也要选择非常小的 dropout rate(0~0.2) ,而且要注意在使用的时候关掉dropout。我不用dropout.
好处:在数据不足的情况下缓解过拟合;像Noisy DQN那样去促进策略网络探索 坏处:影响DRL快速拟合的能力;略微增加训练时间 。
【批归一化】 经过大量实验,DRL绝对不能直接使用批归一化,如果非要用,那么就要修改Batch Normalization的动量项超参数.
【记忆容量】 经验回放缓存 experimence replay buffer 的最大容量 max capacity,如果超过容量限制,它就会删掉最早的记忆。在简单的任务中(训练步数小于1e6),对于探索能力强的DRL算法,通常在缓存被放满前就训练到收敛了,不需要删除任何记忆。然而,过大的记忆也会拖慢训练速度,我一般会先从默认值 2 ** 17 ~ 2 ** 20 开始尝试,如果环境的随机因素大,我会同步增加记忆容量 与 batch size、网络更新次数,直到逼近服务器的内存、显存上限(放在显存训练更快) 。
【批次大小、更新次数】 一般我会选择与网络宽度相同、或略大的批次大小batch size。我一般从 128、256 开始尝试这些2的N次方。在off-policy中,每往Replay 更新几个数据,就对应地更新几次网络,这样做简单,但效果一般。(深度学习里)更优秀的更新方法是:根据Replay中数据数量,成比例地修改更新次数。Don't Decay the Learning Rate, Increase the Batch Size. ICLR. 2018 。,经过验证,DRL也适用.
【折扣因子】 discount factor、discount-rate parameter 或者叫 gamma 。0.99 。
同策略(A3C、PPO、PPO+GAE)与异策略(DQN、DDPG、TD3、SAC)的主要差异是:
异策略off-policy:ReplayBuffer内可以存放“由不同策略”收集得到的数据用于更新网络 。
同策略on-policy:ReplayBuffer内只能存放“由相同策略”收集得到的数据用于更新网络 因此以下超参数有不同的选择方法:
记忆容量:经验回放缓存 experimence replay buffer 的最大容量 max capacity 。
批次大小:batch size。使用优化器更新时,每次更新使用的数据数量 。
更新次数:update times。使用梯度下降更新网络的次数 。
【记忆容量】 on-policy 算法每轮更新后都需要删除“用过的数据”,所以on-policy的记忆容量应该大于等于【单轮更新的采样步数】,随机因素更多的任务需要更大的单层采样步数才能获得更多的 轨迹 trajectory,才能有足够的数据去表达环境与策略的互动关系。详见下面PPO算法的【单轮更新的采样步数】 。
【批次大小】 on-policy 算法比off-policy更像深度学习,它可以采用稍大一点的学习率(2e-4)。因为【单轮更新的采样步数】更大,所以它也需要搭配更大的batch size(2 9 ~ 2 12)。如果内存显存足够,我建议使用更大的batch size,我发现一些很难调的任务,在很大的batch size(2 ** 14) 面前更容易获得单调上升的学习曲线(训练慢但是及其稳定,多GPU分布式)。请自行取舍.
【更新次数】 一般我们不直接设置更新次数,而是通过【单轮更新的采样步数】、【批次大小】和【数据重用次数】一同算出【更新次数】,详见下面PPO算法的【数据重用次数】 。
如果你擅长调参,那么可以可以考虑TD3算法。如果你的算法的 最优策略通常是边界值 ,那么你首选的算法就是TD3---- 最佳策略总在动作边界 。
【TD3的探索方式】 让其很容易在探索「边界动作」:
好处: 一些任务的最优策略本就存在存在大量边界动作,TD3可以很快学得很快。 坏处: 边界动作都是 -1或 +1,这会降低策略的多样性,网络需要在多样性好数据上训练才不容易过拟合。对于clip 到正负1之间的action,过大的噪声方差会产生大量边界动作 .
【探索噪声方差 exploration noise std】 就是上图中的s。需要先尝试小的噪声方差(如0.05),然后逐渐加大。大的噪声方差刻意多探索边界值,特定任务下能让探索更快。 且高噪声下训练出来的智能体更robust(稳健、耐操) 。 请注意:过大的噪声方差(大于上图蓝线的0.5)并不会让探索动作接近随机动作,而是让探索动作更接近单一的边界动作。此外,过大的噪声会影响智能体性能,导致她不容易探索到某些state.
因此,合适的探索噪声方差只能慢慢试出来,TD3适合愿意调参的人使用。在做出错误动作后容易挽回的环境,可以直接尝试较大的噪声。 我们也可以模仿 epslion-Greedy,设置一个使用随机动作的概率,或者每间隔几步探索就不添加噪声,甚至也在TD3中使用探索衰减。这些操作都会增加超参数的数量,慎用.
【策略噪声方差 policy noise std】 确定了探索噪声后,策略噪声只需要比探索噪声稍大 (1~2倍) 。TD3对策略噪声的解释是“计算Q值时,因为相似的动作的Q值也是相似的,所以TD3也为动作加一个噪声,这能使Q值函数更加光滑,提高训练稳定性 我们还能多使用几个添加噪声的动作,甚至使用加权重要性采样去算出更稳定的Q值期望。在确定策略梯度算法里的这种“在计算Q值时,为动作加noise的操作”,让TD3变得有点像随机策略梯度。无论是否有clip,策略噪声方差最大也不该超过0.5.
【延迟更新频率 delay update frequency】 TD3认为:引入目标网络进行 soft update 就是为了提高训练稳定性,那么既然 network 不够稳定,那么我们应该延迟更新目标网络 target network,即多更新几次 network,然后再更新一次target network。从这个想法再拓展出去,我们甚至可以模仿TTUR的思想做得更细致一点,针对双层优化问题我们能做:
环境随机因素多,则需要尝试更大的延迟更新频率,可尝试的值有 1~8,默认值为2 提供策略梯度的critic可以多更新几次,再更新一次actor,可尝试的值有 1~4< 。
提供策略梯度的critic可以设计更大的学习率,例如让critic的学习率是actor 的1~10倍 。
由于critic 需要处理比 actor 更多的数据,因此建议让critic网络的宽度略大于actor 。
尽管下面列举了4个超参数,但是后三个超参数可以直接使用默认值(默认值只会有限地影响训练速度),第一个超参数甚至可以直接通过计算选择出来,不需要调整.
reward scaling 是指直接让reward 乘以一个常数k (reward scale),在不破坏reward function 的前提下调整reward值,从而间接调整Q值到合适的大小。 修改reward scale,相当于修改lambda1,从而让可以让 reward项 和 entropy项 它们传递的梯度大小接近。与其他超参数不同,只要我们知晓训练环境的累计收益范围,我们就能在训练前,直接随意地选定一个reward scaling的值,让累计收益的范围落在 -1000~1000以内即可,不需要精细调整:
【温度系数、目标策略熵】 Temperature parameters (alpha)、target 'policy entropy'。SAC的第二篇论文加入了自动调整 温度系数 alpha 的机制:通过自动调整温度系数,做到让策略的熵维持在目标熵的附近(不让alpha过大而影响优化,也不让alpha过小而影响探索) 。
策略熵的默认值是 动作的个数 的负log,详见SAC的第二篇论文 section 5 Automating Entropy Adjustment for Maximum Entropy 。SAC对这个超参数不敏感,一般不需要修改。有时候策略的熵太大将导致智能体无法探索到某些有优势的state,此时需要将目标熵调小.
【温度系数 alpha 的学习率】 learning rate of alpha 温度系数alpha 最好使用 log 形式进行优化,因为alpha是表示倍数的正数。一般地,温度系数的学习率和网络参数的学习率保持一致(一般都是1e-4)。当环境随机因素过大,导致每个batch 算出来的策略熵 log_prob 不够稳定时,我们需要调小温度系数的学习率.
【温度系数 alpha 的初始值】 initialization of alpha 温度系数的初始值可以随便设置,只要初始值不过于离奇,它都可以被自动调整为合适的值。一般偷懒地将初始值设置为 log(0) 其实过大了,这会延长SAC的预热时间,我一般设置成更小的数值,详见 The alpha loss calculating of SAC is different from other repo · Issue #10 · Yonv1943/ElegantRL .
常规参数:
无人机初始位置 | 用户初始位置 | 无人机覆盖半径(米) | 最大关联数 | UAV飞行距离 |
---|---|---|---|---|
【20,180】 | 【20,180】 | 【75,100】 | 【20,30】 | 【0,30】 |
时延记录: | ||||
前景(MB) | 0.125 | 0.5 | 1 | 1.25 |
-- | -- | -- | -- | -- |
背景(MB) | 0.5 | 2 | 4 | 5 |
local(ms) | 13 | 52 | 105 | --- |
UAV(ms) | 47 | 29.4 | 39.7 | --- |
coop(ms) | 44 | 29.6 | 38.2 | ---- |
超参数: | ||||
ACTOR_LR | CRITIC_LR | BATCH_SIZE | GAMMA | TAU |
-- | -- | -- | -- | -- |
【1e-4 ,1e-5】 | 【1e-3 ,1e-4】 | 【256,512】 | 0.99】 | 0.005 |
EXPL_NOISE | policy_noise | noise_clip | policy_freq | hid_size |
0.1、0.05 | 0.2、0.1 | 0.5 | 【1,8】默认:2 | 【128,512】 |
目前采用组合有如下:
可以看到模型训练的稳定性和收敛效果越来越好,调多了你也就知道哪些超参数影响的大了 。
最后此篇关于强化学习调参技巧二:DDPG、TD3、SAC算法为例:的文章就讲到这里了,如果你想了解更多关于强化学习调参技巧二:DDPG、TD3、SAC算法为例:的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是新手。查看 Google 新闻...上下滚动页面时请注意左侧导航栏。 看看它是如何滚动一点,然后在它消失之前粘在页面顶部的? 关于如何做到这一点有什么想法吗? jQuery 和 CSS 可以复制吗
技巧 1:在 Web 服务器上缓存常用数据 技巧 2:在 Application 或 Session 对象中缓存常用数据 技巧 3:在 Web 服务器磁盘上缓存数据和 HTML 技巧 4:避免
我在 excel 中有一个电子表格,其中包含以下行: COLUMN Value1.Value2.Value3 Value4.Value5.Value6 Value7.Value8.Val
GNU Makefile 中是否有任何技巧来获取规则的所有依赖项? 例子: rule1: dep1_1 dep1_2 dep1_3 rule2: dep2_1 dep2_2 rule1 dump_
人们使用什么来追踪内存泄漏?我已经通过代码检查设法解决了一些问题,但我不知道下一步该做什么/当我的程序变大时我将如何管理问题。我知道我在泄漏什么类型的对象,但我不知道是什么让它保持活力。 在 Wind
有什么好的方法可以将“xlSum”、“xlAverage”和“xlCount”等字符串转换为它们在 Microsoft.Office.Interop.Excel.XlConsolidationFunc
我们都见过这个: javascript:document.body.contentEditable='true'; document.designMode='on';无效 0 但我的问题是,这实际上是
我的应用程序将输出一个图形,其布局由用户定义。自定义布局类应该实现我定义的接口(interface)。我应该怎么做?有一个特殊的文件夹,我可以在其中查找布局类?用户是否将类名作为参数传递给应用? 如有
我在弄清楚如何在 Javascript 中自引用表行时遇到了一些麻烦。 这是简化的代码: $( "#listitems tbody" ).append( "" + "" + id.va
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this q
我正在将代码库从一种编程风格转移到另一种编程风格。 我们有一个名为 Operand 的类型,定义如下: class Operand {...}; 然后我们有 class OperandFactory
我使用以下缩略图类在我的内容包装器中显示 4x3 缩略图: .thumbnail { float:left; width:300px; height:200px; ma
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我认为这是不可能的,但我想在放弃之前问问你。 我想要类似 constexpr 增量的东西。 #include constexpr int inc() { static int inc = 0;
是否有任何适合 C++ 新手的技术和描述的好列表。我在想一个描述 RAII、RVO、左值的列表……这适用于目前不了解这些技术或来自不适用这些技术的其他语言的新手。 最好是短小精悍的:-) 最佳答案 是
我有一个二进制字符串 '01110000',我想在不编写 forloop 的情况下返回前面的前导零数。有谁知道如何做到这一点?如果字符串立即以“1”开头,最好也返回 0 最佳答案 如果您真的确定它是一
我需要优化我的应用程序的 RAM 使用率。 请省去那些告诉我在编写 Python 代码时不应该关心内存的讲座。我有内存问题,因为我使用非常大的默认字典(是的,我也想快点)。我目前的内存消耗是 350M
有时,当我看到一个我喜欢的网站或来自受人尊敬的人的网站时,我会查看源代码并尝试理解它们(就像我们所有人一样)。 关于 Jeremy Keiths他使用以下代码的网站: [role="navigatio
这是我怎样设置 Git 来管理我的家目录的方法。 我有好几台电脑。一台笔记本电脑用于工作,一台工作站放在家里,一台树莓派(或四台),一台 Pocket CHIP,一台 运行
shell 技巧 表变量 HBase 0.95 版本增加了为表提供 jruby 风格的面向对象引用的 shell 命令。以前,作用于表的所有 shell 命令都具有程序风格,该风格始终将表的名称作
我是一名优秀的程序员,十分优秀!