批标准化(Batch Normalization)

在学习Batch Normalization之前,我们来看一道某知名互联网公司算法题。

以下关于batch normalization说法正确的是()

     A. normalization的均值⽅差计算是基于全部训练数据的

     B. normalization的均值方差只基于当前的mini-batch

     C. normalization对输入层的每一维单独计算均值方差

     D. normalization的输出分布服从均值为0,方差为1的高斯分布

对于这道题一下就知道 Batch Normalization,这篇博客就基本可以跳过去了,但对于还有疑惑的同学,我们可以带着问题来进一步探索。

Batch Normalization

Batch Normalization是优化深度神经网络中最激动人心的最新创新之一。实际上它并不是一个优化算法,而是一个自适应的重新参数化的方法,试图克服神经网络层数加深导致模型难以训练。目前最常用的深度学习基础模型包括前向神经网络(MLP),CNN 和 RNN。 Batch Normalization 在这些基础网络结构中均有得到应用,大量数据表明,Batch Normalization 在 MLP 和 CNN 上效果很显著的,但在 RNN 上效果不明显。

Batch Normalization中文一般称为 “批标准化/规范化”,是一种对数值的特殊函数变换方法,也就是说假设原始的某个数值是 x,套上一个起到规范化作用的函数,对规范化之前的数值 x 进行转换,形成一个规范化后的数值,即:

所谓规范化,是希望转换后的数值 x ̂满足一定的特性,至于对数值具体如何变换,跟规范化目标有关, f() 函数的具体形式,不同的规范化目标导致具体方法中函数所采用的形式不同。

在介绍深度学习 Normalization 前,我们先普及下神经元的活动过程。深度学习是由神经网络来体现对输入数据的函数变换的,而神经网络的基础单元就是网络神经元,一个典型的神经元对数据进行处理时包含两个步骤的操作(参考图 1):

  1. 对输入数据进行线性变换,产生净激活值:

         

          其中,Xi 是输入,Wi 是权重参数,b 是偏置,Wi 和 b 是需要进行训练学习的网络参数

      2. 加入非线性激活函数,神经网络的非线性能力来自于此,目前深度学习最常用的激活函数是 Relu 函数 x=Relu(a)

这样一个神经元就完成了对输入数据的非线性函数变换。这里需要强调下,步骤1 中的输出一般称为净激活(Net Activation),步骤2 经过激活函数后得到的值为激活值。为了描述简洁,本文后续文字中使用激活的地方,其实指的是未经激活函数的净激活值,而非一般意义上的激活,这点还请注意。

Normalization 操作方法

神经网络里主要有两类实体:神经元连接神经元的边,所以深度学习中的 Normalization,按照规范化操作涉及对象的不同可以分为两大类:

  • 一类是对第 L 层每个神经元的激活值或者说对于第 L+1 层网络神经元的输入值进行 Normalization 操作,比如 BatchNorm/LayerNorm/InstanceNorm/GroupNorm 等方法都属于这一类;
  • 另外一类是对神经网络中连接相邻隐层神经元之间的边上的权重进行规范化操作,比如 Weight Norm 就属于这一类。广义上讲,一般机器学习里看到的损失函数里面加入的对参数的 L1/L2 等正则项,本质上也属于这第二类规范化操作。L1 正则的规范化目标是造成参数的稀疏化,就是争取达到让大量参数值取得 0 值的效果,而 L2 正则的规范化目标是有效减小原始参数值的大小。有了这些规范目标,通过具体的规范化手段来改变参数值,以达到避免模型过拟合的目的。

那么对于第一类的 Normalization 操作,其在什么位置发挥作用呢?

目前有两种在神经元中插入 Normalization 操作的地方(参考图 2):

  • 第一种是最早由Google研究员在其论文中提出的Batch Normalization,放在激活函数之前
  • 另外一种是后续研究提出的,放在激活函数之后,不少研究表明将 BN 放在激活函数之后效果更好。本文在理解时仍然遵循 BN 原始论文,后续讲解都可以看成是将 Normalization 操作放在激活函数之前进行

                                 图 2. Normalization 加入的位置

对于神经元的激活值来说,不论哪种 Normalization 方法,其规范化目标都是一样的,就是将其激活值规整为 均值为 0,方差为 1 的正态分布(本文开头问题答案的既视感)。即规范化函数统一都是如下形式:

                         (1)

其中,ai 为某个神经元原始激活值,ai^norm 为经过规范化操作后的规范后值

整个规范化过程可以分解为两步,第一步参考公式(2),是将激活值规整到均值为 0,方差为 1 的正态分布范围内。

      (2)                 

       (3)

神经元在训练过程中学习到对应的两个调节因子,对规范到均值为 0 ,方差为1 的值进行微调。因为经过第一步操作后,Normalization 有可能降低神经网络的非线性表达能力,所以会以此方式来补偿 Normalization 操作后神经网络的表达能力。

其中,μ 是通过神经元集合 S(至于 S 如何选取读者可以先不用关注,后文有述)中包含的 m 个神经元各自的激活值求出的均值,即:

σi 为根据均值 μ 和神经元集合 S 中神经元各自激活值求出的激活值标准差:

     

其中,ε 是为了增加训练稳定性而加入的小的常量数据。

不论是早期提出的提出的 Batch Normalization,还是 Batch Normalization 的改进版本。其基本计算步骤都如上所述,大同小异,最主要的区别在于神经元集合 S 的范围怎么定,不同的方法采用了不同的神经元集合定义方法。

神经元集合 S 的范围如何确定

为什么这些 Normalization 需要确定一个神经元集合 S 呢?原因很简单,前面讲过,这类深度学习的规范化目标是将神经元的激活值限定在均值为 0 方差为 1 的正态分布中。而为了能够对网络中某个神经元的激活值 a_i 规范到均值为 0 和方差为 1 的范围,必须有一定的手段求出均值和方差,而均值和方差是个统计指标,要计算均值和方差这两个指标一定要在一个集合范围内才可行,所以这就要求必须指定一个神经元组成的集合,利用这个集合里每个神经元的激活来统计出所需的均值和方差,这样才能达到预定的规范化目标。

                                   图 3 Normalization 的一个计算过程

(参考图 3) 给出了这类 Normalization 的一个计算过程的具体例子,例子中假设网络结构是前向反馈网络,对于隐层的三个节点来说,其原初的激活值为 [0.4, -0.6, 0.7],为了可以计算均值为 0 方差为 1 的正态分布,划定集合 S 中包含了这个网络中的 6 个神经元,至于如何划定集合 S 读者可以先不用关心,此时其对应的激活值如图中所示,根据这 6 个激活值,可以算出对应的均值和方差。有了均值和方差,可以利用公式(1)对原初激活值进行变换,设定两个调节因子为 1,那么可以得到转换后的激活值 [0.21,-0.75, 0.50],对于新的激活值经过非线性变换函数比如 RELU,则形成这个隐层的输出值 [0.21, 0, 0.50]。这个例子中隐层的三个神经元在某刻进行 Normalization 计算的时候共用了同一个集合 S,在实际的计算中,隐层中的神经元可能共用同一个集合,也可能每个神经元采用不同的神经元集合 S,并非一成不变,这点还请留心与注意。

针对神经元的所有 Normalization 方法都遵循上述计算过程,唯一的不同在于如何划定计算统计量所需的神经元集合 S

 前向神经网络中的 Batch Normalization

图 4  前向神经网络 Batch Normalization

对于前向神经网络来说,Batch Normalization 在计算隐层某个神经元 k 激活的规范值的时候,对应的神经元集合 S 范围是如何划定呢?(参考图 4) 给出了示意,因为对于 Mini-Batch 训练方法来说,根据 Loss 更新梯度使用 Batch 中所有实例来做,所以对于神经元 k 来说,假设某个 Batch 包含 n 个训练实例,那么每个训练实例在神经元 k 都会产生一个激活值,也就是说 Batch 中 n 个训练实例分别通过同一个神经元 k 的时候产生了 n 个激活值,Batch Normalization的集合 S 选择入围的神经元就是这 n 个同一个神经元被 Batch 不同训练实例激发的激活值。划定集合 S 的范围后,Normalization 的具体计算过程与前文所述计算过程一样,采用公式(1) 即可完成规范化操作。

CNN 网络中的 Batch Normalization

常规的 CNN 一般由卷积层、下采样层及全连接层构成。全连接层形式上与前向神经网络是一样的,所以可以采取前向神经网络中的 BatchNorm 方式,而下采样层本身不带参数所以可以忽略,所以 CNN 中主要关注卷积层如何计算 Batch Normalization。

图 7  CNN 的卷积核

CNN 中的某个卷积层由 m 个卷积核构成,每个卷积核对三维的输入(通道数*长*宽)进行计算,激活及输出值是个二维平面(长*宽),对应一个输出通道(参考图 7),由于存在 m 个卷积核,所以输出仍然是三维的,由 m 个通道及每个通道的二维平面构成。

图8 CNN 中的 BatchNorm 过程

在CNN卷积层中,如果要对通道激活二维平面中某个激活值进行 Normalization 操作,怎么确定集合 S 的范围呢?

图 8 给出了示意图。类似于前向神经网络中的 BatchNorm 计算过程,对于 Mini-Batch 训练方法来说,反向传播更新梯度使用 Batch 中所有实例的梯度方向来进行,所以对于 CNN 某个卷积层对应的输出通道 k 来说,假设某个 Batch 包含 n 个训练实例,那么每个训练实例在这个通道 k 都会产生一个二维激活平面,也就是说 Batch 中 n 个训练实例分别通过同一个卷积核的输出通道 k 的时候产生了 n 个激活平面

假设激活平面长为 5,宽为 4,则激活平面包含 20 个激活值,n 个不同实例的激活平面共包含 20*n 个激活值。那么 BatchNorm 的集合 S 的范围就是由这 20*n 个同一个通道被 Batch 不同训练实例激发的激活平面中包含的所有激活值构成(对应图 8 中所有标为蓝色的激活值。划定集合 S 的范围后,激活平面中任意一个激活值都需进行 Normalization 操作,其 Normalization 的具体计算过程与前文所述计算过程一样,采用公式(1) 即可完成规范化操作。这样即完成 CNN 卷积层的 BatchNorm 转换过程。

描述起来似乎有些复杂,但是从概念上,其实可以把 CNN 中的 卷积层 想象成前向神经网络中的一个 隐层,然后把对应的某个卷积核 想象成 MLP 隐层中的一个神经元节点,两者不同之处是:

  • CNN 输出是个二维激活平面而 MLP 的神经元输出是一个激活值
  • 另外一个不同是这个神经元覆盖的输入部分不同,CNN 的卷积核是局部覆盖输入,通过滑动窗口来实现输入的全覆盖,   而 MLP 的神经元则是一步到位全局覆盖输入 。如果从这个角度思考 CNN 和 MLP 中的 BatchNorm 的话,其实两者的做法是一致的。

Batch Normalization 优点

  1. 可以加快模型 收敛速度 ,不再依赖精细的参数初始化过程,
  2. 可以调大 学习率 等,
  3. 同时引入的 随机噪声 能够起到对模型参数进行 正则化 的作用,有利于增强模型泛化能力。

Batch Normalization 不足

  1. 如果 Batch Size 太小,则 BN 效果明显下降。因为在小的 BatchSize 意味着数据样本少,因而得不到有效统计量,也就是说噪音太大。
  2. 对于有些像素级图片生成任务来说,BN 效果不佳;对于图片分类等任务,只要能够找出关键特征,就能正确分类,这算是一种粗粒度的任务,因为在 Mini-Batch 内多张无关的图片之间计算统计量,弱化了单张图片本身特有的一些细节信息。
  3. RNN 等动态网络使用 BN 效果不佳且使用起来不方便
  4. 训练时和推理时统计量不一致

参考:

1. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

2. 深度学习中的Normalization模型

  • 24
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值