前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度强化学习算法是否需要使用批归一化(Batch Norm) 或归一化,文本带你详解。

深度强化学习算法是否需要使用批归一化(Batch Norm) 或归一化,文本带你详解。

作者头像
汀丶人工智能
发布2023-10-11 17:45:24
5220
发布2023-10-11 17:45:24
举报
文章被收录于专栏:NLP/KGNLP/KG

深度强化学习算法 (DRL, Deep Reinforcement Learning Algorithm) 的神经网络是否需要使用批归一化 (BN, Batch Normalization) 或归一化(白化 whitening)?

深度强化学习不需要批归一化,但是可以用归一化。(长话短说)

归一化指的是深度学习的白化(whitening),这种操作可以让神经网络舒服地训练。本文讨论了 state action 这些输入值 以及 Q 值(reward)这些输出值 的归一化问题。见下方目录。

舒服地训练:让神经网络的输入值,或者输出值尽可能靠近正态分布,从而让激活函数正常工作,随机初始化的参数不需要被夸张地调整,梯度下降优化器的超参数可以不调。

代码与对应的流程,如下:

1.BN 在 RL 中是如何失效的?

在深度学习中 BN 很有用,特别监督学习:从训练集中抽取数据进行训练,通过随机抽取保证每个批次的数据符合独立同分布 (i.i.d.)。在这种稳定的训练环境下,BN 可以计算出稳定变化的 mean 和 std 用于归一化

在强化学习中,BN 会失效:智能体 (agent) 训练越快,BN 越难以发挥作用。与监督训练不同,RL 的智能体需要通过**「经验回放」技术与环境交互**来获取训练数据,这些数据无法在开始前就准备好(给定)。所以 RL 无法为 BN 提供足够稳定的训练数据,每当训练数据发生变化(智能体搜集到大量新的状态 state),而 BN 来不及适应新的数据,造成估值函数和策略函数相继奔溃(估值函数的估值不准,策略函数的策略退化)。

**「经验回放」**技术是什么?详见 DRL 的经验回放 (Experiment Replay Buffer) 用 Numpy 实现让它更快一点 的章节 1. 简单介绍「经验回放」 与环境交互来获取训练数据:因为智能体的动作会影响它下一步的状态 (state),因此要通过交互去收集数据。请注意有反例:如果金融 RL 的智能体控制的资金量少,那么可以认为它的交易行为不会对市场的大环境产生影响,因此在开始前就准备好(给定)金融 RL 的训练数据。

在有监督的深度学习中:

  1. 无论网络性能如何,我们一直都从训练集随机抽样得到稳定的训练数据(绿色箭头起点)
  2. 在训练数据稳定时,BN 也趋于稳定,并算出稳定的均值和方差(绿色箭头终点)

而在深度强化学习中:

  1. 训练数据由智能体与环境交互从零开始收集,一开始就不稳定(橙色箭头起点)
  2. 经过长时间采样,训练数据变多,并趋于稳定(橙色箭头终点),BN 也渐渐稳定
  3. 此时由于策略提升,智能体开始收集到新的状态,训练数据发生变化(红色箭头起点)
  4. 受采样数据中新状态的影响,之前 BN 算出的均值与方差不适应新的数据,因此开始波动,可是策略的性能在 BN 算出稳定的新值之前就已经发生了明显的下降。
  5. 策略性能下降,导致智能体与环境的交互受到影响,加剧了采样数据的不稳定,最终 BN 与采样数据双双滑落到不稳定的状态(红色箭头终点)。
  6. 循环以上过程 2~5

请注意,复现得差的 DRL 代码训练效率低,这味意着采样数据稳定,那么它用了 BN 反而能获得性能的提升(成绩垫底,发挥稳定,有较大提升潜力)。

传统的机器学习算法(如 sk-learn 里的),会超参数搜索技巧的人得到的结果差不多 深度学习算法可以在 kaggle 上办比赛,尽管大家的算法差不多,但是复现效果明显有差别(如自称 YOLO5 的算法的确比 YOLO4 好,可它本质上还是 YOLO4) 深度强化学习的算法不同人类复现的效果天壤之别。“这个环境我用 DRL 的 XXX 算法跑不出来啊”,他可能把 DRL 算法当成是 sk-learn 里面那些算法了。

若你在外看到有人宣称使用了 BN 让他的 DRL 算法训练更快了,可能是因为他实现的 DRL 算法差。例如,对于完全相同的某个任务(如 Ant-v0-pybullet):

  • 好的 DRL 算法复现,平均训练 0.5m 步,加上 BN,训练 1m 步,得出结论:BN 不适合 RL
  • 差的 DRL 算法复现,平均训练 10m 步,加上 BN,训练 5m 步,得出结论:BN 适合 RL

2.尽管 RL 不需要批归一化 BN,但 RL 可以使用归一化(白化)

对训练数据使用归一化(白化 whitening):将输入神经网络的数值事先除以其均值和方差,让输入的张量符合标准正态分布。深度学习使用这种方法消除输入数据的量纲,随机初始化的网络在白化后的输入数据训练会很舒服:假如输入一个绝对值很大的数字 -10000,那么神经网络的 wx+b 的参数 w、b 需要经过很多步的更新才能从 0 → 1000,让这一层的输出也接近正态分布,才能让我们的激活函数 ReLU、Tanh 等正常工作。因此深度强化学习也可以对输入数据进行白化操作,具体操作如下:

  1. 开始 DRL 的训练,然后将历史训练数据保存在经验回放 (relpay buffer) 里
  2. 训练结束后,计算 replay buffer 里 state 每个维度的均值和方差,结束整个训练流程
  3. 下一次训练开始前,对所有输入网络的 state 用固定的均值和方差进行归一化
  4. 重复一两次此过程

Critic 一般以 state 和 action 作为输入,为何一般只对 state 做归一化而忽略 action? 在动作空间是连续的情况下,一个设计得好的环境,其 action 的均值方差最好接近 0 和 1。要做到这点非常容易,例如我将动作空间定为 -1 到 1。 「Reward 需要归一化吗?」见下文。Reward 不能归一化,但是可以成倍地调整其大小

此外,一边训练一边计算用于归一化的均值与方差是可行的。与批归一化不同:这里的归一化统计的不是某一批次的数据,而是统计了历史出现的所有数据,因此它在训练后期非常稳定。如下:

代码语言:javascript
复制
# https://github.com/zhangchuheng123/Reinforcement-Implementation/blob/master/code/ppo.py
# 详细过程去看他的代码

classRunningStat(object):
    def mean(self):
    def std(self):

class ZFilter:
    def __call__(self, x, update=True):
        x = x - self.rs.mean
        x = x / (self.rs.std + 1e-8)  # 用1e-5更保险
        x = np.clip(x, -self.clip, self.clip)
        return x

然而,我自己从来不用 running mean std 这个 trick,因为我认为这个太耗费性能了。我直接手动地统计出 mean 和 std,然后在完全重新开始训练时,直接让 state 除以 std 减去 mean 这两个常数,效果同样很好。详见下方「我不用 running mean std 这个 trick,我直接算出 norm 的定值

还认为 RL 应该用 BN?RLlib ray-project 这些开源 DRL 库都不用。知名的强化学习算法库:伯克利的 Ray RLLIB、OpenAI 的 baselines 等 都没有在他们的 DRL 算法中使用 BN,这是有说服力的证据。若看到这里还有人认为 RL 应该使用 BN,那么可能只有把深度学习当成是实验科学,并用实验数据和代码才能说服了,代码见 ElegantRL (中文名可能叫 “强化学习库:小雅?) ,里面有各种 DRL 算法以及标准的训练环境。想要通过实践去检验的人,可以随便挑一个算法,在你自己认为合适的地方加上 BN 层,如下:

代码语言:javascript
复制
self.net = nn.Sequential(nn.Linear(state_dim, mid_dim), nn.ReLU(),
                         nn.BatchNorm1d(mid_dim), # 随便挑一个地方加上BN层
                         nn.Linear(mid_dim, action_dim), nn.Tanh(), )

实验数据见下方论文截图。

  1. 列举出学界对 BN in RL 的讨论并点评

  • 反方 Paper1, Paper2 的观点与我相同,认为不需要:
  • 正方 Paper3, Paper4 认为 RL 需要 BN

2.1 Paper1 认为 RL 不能使用 BN

CrossNorm: On Normalization for Off-Policy TD Reinforcement Learning. 2019.10 “Results improve only little over those without normalization and often are substantially worse.”

上面这篇文论发现在 DRL 中使用 BN 会带来很小的提升,但通常情况下甚至更差(训练更长久,且训练不稳定)。因此他们对 BN 进行改进,提出了 CrossNorm。**我在我的 DRL 代码中尝试了 BN,观测到的现象与他们描述的相符。**此外,我尝试了他们的 CrossNorm 却没有得到显著的提升,我不推荐 CrossNorm。

2.2 Paper2 认为 RL 不需使用 BN

Continuous control with deep reinforcement learning. ICLR. 2016 In Fig. 2, they compare “target network update” with “BN”. the blue curve (with target network, not BN) is no significant difference between other methods with BN.

早在 2016 年,就有人讨论过 BN in RL 了,他们的结论也是:RL 不需要使用 BN,BN 带来的性能提升微乎其微,远远不如 soft target update、(和后来的)Generalization Advantage Estimate 等技术。

2.3 Paper3 认为 BN 可以提升 DL 的训练

Batch normalization: Accelerating deep network training by reducing internal covariate shift. 2015. Cited by 17773 (till 2020-05-14)

在 DQN 提出用 Q network 取代 Q table,DDPG 提出用 Actor Network 取代 DQN 的 贪婪策略 argmax 后,强化学习的无模型算法逐渐与深度学习进行结合。以至于知乎讨论的「强化学习」很大程度上是指「深度强化学习」(Deep RL)。

这篇文章只说:BN 可以给深度网络带来提升,把它算成是正方已经很勉强。尽管深度强化学习也是一种深度学习,但是我个人认为深度强化学习中 BN 会失效。原因是深度强化学习 (DRL) 不使用训练集进行训练,其训练数据没有深度学习那么稳定。详见本页面的「1. BN 在 RL 中是如何失效的?」

2.4 Paper4 认为 BN 可以提升 RL 的训练

A Novel DDPG Method with Prioritized Experience Replay. IEEE SMC 2017. They cited Paper3 and claimed BN can improve DRL.

这篇文章在他们的 DRL 算法 DDPG 中 尝试使用 BN,并认为用了更好(我反对此观点)。下面是我个人的吐槽:

  • 为何在 2017 年出了 A3C.2016 的情况下还要用 DDPG.2014?
  • 若没有大厂背书(或是落地),没有开源代码的研究成果可视为不存在。
  • Paper3 说的是 BN 可以提升 DL,而没有直接说 BN 可以提升 DRL,不应该犯这种错误。
  • 这篇文章发表在 IEEE SMC 2017. 还好不是讨论强化学习的地方,这篇文章能过侧面说明了当时这几个审稿人可能需要先入门深度强化学习。
  • 这篇文章把 DQN 的 Prioritized Experience Replay 和 DDPG 结合起来,这是 A+B 式的科研,其创新程度不高,可以作为优秀的本科毕业设计,更不该成为可发表的论文。在标题上写 Novel DDPG 不恰当。

3. 其他技巧

3.1 running mean std

running mean std 这个 trick 是有用的,它记录智能体遇到的所有 state 的均值与方差。既然记录的是所有的 state,那么随着训练的进行,它算出来的均值与方差会趋于稳定。因此:

  • 在训练前期,它算出来的均值与方差不稳定,对 RL 的训练有影响,在简单任务上更明显(训练步数小于 1e6)
  • 在训练后期,它算出来的均值与方差几乎不变。那么我为何还要使用这个 trick 呢?

综合考虑,我不使用 running mean std 这个 trick,我会使用本文章节 2 提及的方法:直接用上一轮 experiment replay 中 state 计算出固定的均值与方差,这样一来:我能在训练前期归一化并保持均值方差的稳定(它们是常数,固然稳定),训练后期,我不需要让程序反复更新均值与方差,算法运行效率高一点点。

尽管做好一个细节只可以让算法运行效率高一点点。但是多个细节都做好,运行效率的提升是显而易见的。我自己写了一个强化学习库:小雅?ElegantRL ,里面尽可能地将不需要写在循环的东西都移除了,我只希望像有更多优雅的 RL 代码可以被人使用。至于为何要自己写一个新的,出发点和他们是一样的:stable-baselines 可能是觉得 baselines 不够稳定才不得已新开一个 fork ,可是 stable-baselines 也不够稳定,而 RLLib 却过于臃肿,高耦合度的代码让 follow 的人感到头大。我也是无可奈何才决定从头开始构建一个库。(有时间会写一写我认为「baselines 里面那些部分做得不好,需要如何改」)

3.2 reward 定制化

「奖励归一化有用吗?不能对 reward 归一化,但可以调整它的大小」

首先,神经网络的输入和输出要尽量靠近正态分布,神经网络的激活函数生效范围、默认超参数、梯度下降算法等更加适应正态分布,因此神经网络在归一化(白化)操作后训练会比较舒服。

然而,我们不能对 reward 做归一化。使用了贝尔曼公式(极致简约版

Q = r + \gamma Q'

)的强化学习不能让 reward 减去一个非零常数,这会破坏环境本身的 reward function,让 Q 值变成一个受执行步数影响的值。若

r+1

,那么智能体只要呆坐不动,其总收益就能一直 + 1。反之

r-1

,那么智能体会倾向于尽快结束游戏。可即便是每一轮训练步数固定的任务也不能让 reward 减去一个非零常数,因为折扣因子

\gamma

是一个略小于 1 的数,任何实数乘以折扣因子都会向 0 靠近一点点,它能让智能体用更多步数避开事件型的负收益,用更少步数靠近事件型的正收益。

尽管我们不能对 reward 做归一化,但我们可以让它乘上一个系数用于调整大小,详见的深度强化学习调参技巧:以 D3QN、TD3、PPO、SAC 算法为例 的**【奖励比例】reward scale**。

能对 Reward 做归一化的特例:如果你的 agent 无论采用何种策略,都不影响它在环境中的探索步数,也不影响它触发某些事件的步数,(例如训练环境的每轮训练 episode 的终止步数是固定的,或者奖励非常稠密),那么你可以让 reward 加减一个数值。

能对 Reward(Q 值)做归一化的特例:对 Q 值进行正则化操作不会破坏 Reward Function,效果不错。请注意,这里在 Q 值 上做 norm,而不是在 reward 上做 norm。

Stack Overflow 的回答 Normalizing Rewards to Generate Returns in reinforcement learning如何选择深度强化学习算法?MuZero/SAC/PPO / 等 的【**PPO+GAE】。**以下代码,见「强化学习库:小雅」的 AgentZoo.py

代码语言:javascript
复制
class AgentPPO():
    ...
    def update_policy():
        ...
        all__adv_v = (all__adv_v - all__adv_v.mean()) / (all__adv_v.std() + 1e-5)  # advantage_norm:
        ...
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深度强化学习算法 (DRL, Deep Reinforcement Learning Algorithm) 的神经网络是否需要使用批归一化 (BN, Batch Normalization) 或归一化(白化 whitening)?
  • 1.BN 在 RL 中是如何失效的?
  • 2.尽管 RL 不需要批归一化 BN,但 RL 可以使用归一化(白化)
    • 2.1 Paper1 认为 RL 不能使用 BN
      • 2.2 Paper2 认为 RL 不需使用 BN
        • 2.3 Paper3 认为 BN 可以提升 DL 的训练
          • 2.4 Paper4 认为 BN 可以提升 RL 的训练
          • 3. 其他技巧
            • 3.1 running mean std
              • 3.2 reward 定制化
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档