批标准化(Batch Normalization)

BatchNormalization(批标准化)是深度学习中的一种优化技术,能够加速模型训练并提高模型泛化能力。该技术通过规范化每层神经元的输入,使得网络在训练过程中更加稳定。文章详细介绍了BatchNormalization的工作原理、计算过程及其在前馈神经网络和卷积神经网络中的应用。

在学习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模型

<think>嗯,用户想了解批量归一化(Batch Normalization)的概念、原理及应用。首先,我需要回忆一下批量归一化的基本知识。记得它是由Sergey Ioffe和Christian Szegedy在2015年提出的,主要是用来解决深度神经网络训练中的内部协变量偏移问题。这个概念可能有点抽象,需要解释清楚。 内部协变量偏移是指每一层输入的分布随着前一层参数的变化而发生变化,导致训练变得困难。批量归一化通过对每一层的输入进行标准化处理,使其均值接近0,方差接近1,从而加速训练并提高模型稳定性。 接下来是原理部分。批量归一化通常在激活函数之前应用,对每个小批量数据进行处理。步骤包括计算均值和方差、标准化、缩放和平移。这里需要注意数学公式的正确性,比如标准化公式应该是减均值除以标准差加上一个epsilon防止除零。然后使用可学习的参数gamma和beta来恢复网络的表达能力。 然后是应用场景。比如加速训练、允许更高的学习率、减少对初始化的依赖、起到轻微的正则化效果等。可能还需要提到在卷积神经网络中的应用,比如在激活函数之后应用,或者在卷积层和全连接层的不同处理方式。 用户可能还关心批量归一化的优缺点,比如在Batch较小时效果不佳,这时候可能转向其他归一化方法,比如Layer Normalization或者Instance Normalization。另外,在推理阶段,使用的是整个训练集的均值和方差的移动平均,而不是小批量的统计量,这一点也需要说明。 参考引用部分,虽然用户提供的引用中没有直接提到批量归一化,但可能需要关联到优化指标或初始化方法。不过可能更适合直接引用原始论文或其他可靠来源,但根据用户提供的引用,可能需要调整。比如引用[1]提到优化指标,可以联系到批量归一化如何作为优化训练过程的技术。而引用[2]关于He初始化,可以对比批量归一化如何减少对初始化的依赖。 最后,生成相关问题的时候,要围绕批量归一化的原理、实现细节、与其他技术的比较、应用中的挑战等展开。比如与其他归一化技术的区别,实际应用中的注意事项,或者如何与不同的初始化方法结合使用。 需要确保回答结构清晰,分点解释,并且使用正确的中文术语。数学公式要使用$$...$$格式,例如标准化过程。同时,代码示例可能展示批量归一化的实现,比如在TensorFlow或PyTorch中的使用方式。 可能还需要注意用户的背景,如果是深度学习的学习者,可能需要更详细的原理解释,而如果是实践者,可能更关注应用和调参技巧。但根据问题描述,用户需要概念、原理和应用,所以应全面覆盖这些方面。 检查是否有遗漏的关键点,比如批量归一化在训练和测试阶段的不同处理,为什么能加速收敛,以及其正则化效果的原因。同时,确保LaTeX格式正确,例如变量用$符号包裹,独立公式用双美元符号。 最后,确保回答中引用的部分自然添加标识,比如在提到减少对初始化依赖时引用[2]关于初始化的内容,或者在提到优化训练目标时引用[1]中的优化指标概念。</think>### 批量归一化(Batch Normalization)的概念、原理及应用 #### 1. **概念** 批量归一化(Batch Normalization, BN)是深度学习中一种用于加速训练、提升模型稳定性的技术。其核心思想是对神经网络每一层的输入进行标准化处理,使得输入分布接近均值为0、方差为1的高斯分布,从而缓解**内部协变量偏移**(Internal Covariate Shift)问题[^1]。 #### 2. **原理** **步骤详解**(以全连接层为例): - **输入**:某一层的输入为小批量数据 $B = \{x_1, x_2, ..., x_m\}$。 - **计算均值和方差**: $$ \mu_B = \frac{1}{m} \sum_{i=1}^m x_i, \quad \sigma_B^2 = \frac{1}{m} \sum_{i=1}^m (x_i - \mu_B)^2 $$ - **标准化**: $$ \hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} \quad (\epsilon \text{为防除零的小常数}) $$ - **缩放和平移**(引入可学习参数 $\gamma$ 和 $\beta$): $$ y_i = \gamma \hat{x}_i + \beta $$ 此操作使网络能够自适应地恢复数据的表达能力[^2]。 #### 3. **应用** - **加速训练**:标准化后的输入分布更稳定,允许使用更高的学习率。 - **缓解梯度消失/爆炸**:归一化减少了激活值的动态范围,梯度更易传播。 - **正则化效果**:小批量数据的噪声对模型参数更新有轻微正则化作用。 - **降低对初始化的敏感度**:参数初始化的影响被削弱,减少了对复杂初始化方法的依赖。 **应用场景示例**: - **卷积神经网络**:对每个特征图(Channel)独立归一化。 - **循环神经网络**:需结合时间步调整归一化方式。 - **生成对抗网络**(GANs):稳定生成器和判别器的训练。 #### 4. **代码示例(PyTorch)** ```python import torch.nn as nn class Model(nn.Module): def __init__(self): super().__init__() self.fc = nn.Linear(100, 50) self.bn = nn.BatchNorm1d(50) # 批量归一化层 self.relu = nn.ReLU() def forward(self, x): x = self.fc(x) x = self.bn(x) # 通常在激活函数前应用BN x = self.relu(x) return x ``` #### 5. **注意事项** - **推理阶段**:使用训练时计算的移动平均 $\mu$ 和 $\sigma$,而非实时统计量。 - **小批量问题**:当 Batch Size 过小时,统计量不准确,可改用 Layer Normalization 或 Group Normalization
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值