写点什么

强化学习调参技巧二:DDPG、TD3、SAC 算法为例:

作者:汀丶
  • 2022-12-15
    浙江
  • 本文字数:5358 字

    阅读完需:约 18 分钟

1.训练环境如何正确编写

强化学习里的 env.reset() env.step() 就是训练环境。其编写流程如下:

1.1 初始阶段:

先写一个简化版的训练环境。把任务难度降到最低,确保一定能正常训练。记录正常训练的智能体的分数,与随机动作、传统算法得到的分数做比较。DRL 算法的分数应该明显高于随机动作(随机执行动作)。DRL 算法不应该低于传统算法的分数。如果没有传统算法,那么也需要自己写一个局部最优的算法


评估策略的性能: 大部分情况下,可以直接是对 Reward Function 给出的 reward 进行求和得到的每轮收益 episode return 作为策略评分。有时候可以需要直接拿策略的实际分数作为评分需要保证这个简化版的代码:高效、简洁、可拓展

1.2 改进阶段:

让任务难度逐步提高,对训练环境 env 进行缓慢的修改,时刻保存旧版本的代码同步微调 Reward Function,可以直接代入自己的人类视角,为某些行为添加正负奖励。注意奖励的平衡(有正有负)。注意不要为 Reward Function 添加太多额外规则,时常回过头取消一些规则,避免过度矫正。 同步微调 DRL 算法,只建议微调超参数,但不建议对算法核心进行修改。因为任务变困难了,所以需要调整超参数让训练变快。同时摸清楚在这个训练环境下,算法对哪几个超参数是敏感的。有时候为了节省时间,甚至可以为 off-policy 算法保存一些典型的 trajectory(不建议在最终验证阶段使用)。每一次修改,都需要跑一下记录不同方法的分数,确保:随机动作 < 传统方法 < DRL 算法。这样才能及时发现代码逻辑上的错误。要极力避免代码中出现复数个的错误,因为极难排查。

1.3 收尾阶段:

尝试慢慢删掉 Reward Function 中一些比较复杂的东西,删不掉就算了。选择高低两组超参数再跑一次,确认没有优化空间。

2. 超参数解释分析

2.1 off-policy 算法中常见的超参数

  • 网络宽度: network dimension number。DRL 全连接层的宽度(特征数量)

  • 网络层数: network layer number。一个输入张量到输出需要乘上 w 的次数

  • 随机失活: dropout

  • 批归一化: batch normalization

  • 记忆容量: 经验回放缓存 experimence replay buffer 的最大容量 max capacity

  • 批次大小: batch size。使用优化器更新时,每次更新使用的数据数量

  • 更新次数:update times。使用梯度下降更新网络的次数

  • 折扣因子: discount factor、gamma

  • 【网络宽度、网络层数】 越复杂的函数就需要越大容量的神经网络去拟合。在需要训练 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

2.2 on-policy 算法中常见的超参数

同策略(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(29 ~ 212)。如果内存显存足够,我建议使用更大的 batch size,我发现一些很难调的任务,在很大的 batch size(2 ** 14) 面前更容易获得单调上升的学习曲线(训练慢但是及其稳定,多 GPU 分布式)。请自行取舍。


【更新次数】 一般我们不直接设置更新次数,而是通过【单轮更新的采样步数】、【批次大小】和【数据重用次数】一同算出【更新次数】,详见下面 PPO 算法的【数据重用次数】

3. TD3 特有的超参数

  • 探索噪声方差 exploration noise std

  • 策略噪声方差 policy noise std

  • 延迟更新频率 delay update frequency


如果你擅长调参,那么可以可以考虑 TD3 算法。如果你的算法的最优策略通常是边界值,那么你首选的算法就是 TD3----最佳策略总在动作边界


【TD3 的探索方式】 让其很容易在探索「边界动作」:


  • 策略网络输出张量,经过激活函数 tanh 调整到 (-1, +1)

  • 为动作添加一个 clip 过的高斯噪声,噪声大小由人类指定

  • 对动作再进行一次 clip 操作,调整到 (-1, +1)


好处: 一些任务的最优策略本就存在存在大量边界动作,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 的思想做得更细致一点,针对双层优化问题我们能做:


环境随机因素多,则需要尝试更大的延迟更新频率,可尝试的值有 18,默认值为 2 提供策略梯度的 critic 可以多更新几次,再更新一次 actor,可尝试的值有 14<


提供策略梯度的 critic 可以设计更大的学习率,例如让 critic 的学习率是 actor 的 1~10 倍


由于 critic 需要处理比 actor 更多的数据,因此建议让 critic 网络的宽度略大于 actor

4. SAC 特有的超参数

尽管下面列举了 4 个超参数,但是后三个超参数可以直接使用默认值(默认值只会有限地影响训练速度),第一个超参数甚至可以直接通过计算选择出来,不需要调整。


  • reward scale 按比例调整奖励

  • alpha 温度系数 或 target entropy 目标 策略熵

  • learning rate of alpha 温度系数 alpha 的学习率

  • initialization of alpha 温度系数 alpha 的初始值 SAC 有极少的超参数,甚至这些超参数可以在训练开始前就凭经验确定。

  • 任何存在多个 loss 相加的目标函数,一定需要调整系数 lambda,例如 SAC 算法、共享了 actor critic 网络的 A3C 或 PPO,使用了辅助任务的 PPG。我们需要确定好各个 lambda 的比例。SAC 的第二篇论文加入了自动调整 温度系数 alpha 的机制,处于 lambda2 位置的温度 alpha 已经用于自动调整策略熵了,所以我们只能修改 lambda1。


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 。

5. 自己模型训练调参记录(TD3)

5.1 模型环境参数

常规参数:



目前采用组合有如下:


  • ACTOR_LR = 1e-4 # Actor 网络的 learning rate 学习率 1e-3

  • CRITIC_LR = 1e-3 # Critic 网络的 learning rate 1e-3

  • EXPL_NOISE = 0.05 # 动作噪声方差

  • self.hid_size=256

  • self.hid1_size=128

  • policy_noise=0.1,

  • noise_clip=0.5,

  • policy_freq=2

5.2 调参效果:

可以看到模型训练的稳定性和收敛效果越来越好,调多了你也就知道哪些超参数影响的大了

5.3 造成波动的原因,然后采用对应的解决方案:

  • 如果在策略网络没有更新的情况下,Agent 在环境中得到的分数差异过大。那么这是环境发生改变造成的:-1. 每一轮训练都需要 env.reset(),然而,有时候重置环境会改变难度,这种情况下造成的波动无法消除。-2. 有时候是因为 DRL 算法的泛化性不够好。此时我们需要调大相关参数增加探索,以训练出泛化性更好的策略。

  • 如果在策略网络没有更新的情况下,Agent 在环境中得到的分数差异较小。等到更新后,相邻两次的分数差异很大。那么这是环境发生改变造成的: 1. 把 learning rate 调小一点。2. 有时候是因为算法过度鼓励探索而导致的,调小相关参数即可。


发布于: 刚刚阅读数: 4
用户头像

汀丶

关注

本博客将不定期更新关于NLP等领域相关知识 2022-01-06 加入

本博客将不定期更新关于机器学习、强化学习、数据挖掘以及NLP等领域相关知识,以及分享自己学习到的知识技能,感谢大家关注!

评论

发布
暂无评论
强化学习调参技巧二:DDPG、TD3、SAC算法为例:_强化学习_汀丶_InfoQ写作社区