论文笔记-Batch Normalization: Accele
论文原文:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate
1. 介绍
深度学习模型训练的主要方法是 Stochastic gradient descent (SGD) ,SGD 优化网络的参数,从而最小化损失。
使用 mini-batch 近似估计损失函数对于参数的梯度,其估计的质量随着 batch size 的增大而提高,并且计算效率更高。
虽然随机梯度简单有效,但它需要仔细调整模型超参数,特别是优化中使用的学习率,以及模型参数的初始值。由于每一层的输入受所有前面层参数的影响,网络参数的微小变化都会随着网络变得更深而放大。
这种输入分布的变化会导致后面的每一层都要去适应一个新的分布,会导致整个网络学习变慢。
另一方面,当使用 sigmoid 的时候,随着网络层数加深,在训练中输入的分布很容易移动到饱和区域,使梯度变化很小,很容易产生梯度消失。通常的解决办法是使用 ReLU 作为非线性激活函数,并使用合适的初始化和较小的学习率。但是,如果可以让每一层的输入分布保持稳定以避免陷入饱和区,训练也会加速。
保持每一层输入分布的不变有利于使训练更有效。
作者将训练过程中深层网络内部节点分布的变化称为 internal covariante shift 。消除他可以显著加速神经网络的训练。方法就是作者提出的(现在神经网络标配的)Batch Normalization。
使用 BN 可以:
- 减少参数梯度对于参数范围或者初始值的依赖,使得我们能使用更高的学习率
- 减少了 Dropout 的需求
- 使用 Sigmoid 等有饱和区域的非线性函数时,可以避免网络陷入饱和
2. 关于减少 internal covariante shift
作者定义 Internal Covariate Shift 作为训练过程中网络参数变化引起的网络激活分布的变化。为了改进训练,我们寻求减少 internal covariante shift 。在训练过程中,将每层输入的分布固定,以提高训练速度。
这一点已经被 LeCun 在1998年提出了,如果输入被白化(whiten),即线性变换为具有零均值和单位方差,并且去相关,网络训练收敛得更快。
通过对每一层的输入进行白化,我们将朝着实现输入的固定分布迈出一步,从而消除 internal covariante shift 的不良影响。
我们希望得到的是,对于任何参数值,网络总是可以得到需要的数据分布,这样就可以让损失函数对于模型参数的梯度也与 normalization 有关。假设 是某一层的输入, 是整个训练集, normalization 可以写作 。
其中 都与模型参数 有关(因为是某一层的输出),因此在反向传播的时候需要计算梯度
由于白化计算需要计算协方差矩阵来进行去相关,计算成本高。一些研究也表明了只是用统计学的方法对单个训练样本或者某个位置的特征图进行处理,发现这样会改变数据的表达能力,因为它抛弃了数据范围的信息(discarding the absolute scale of activations)。 因此我们需要一个能够在网络中保留信息的 Normalizatin 操作。
3. Normalization Statistics via Mini-Batch
完全对每一层的输入进行白化操作计算昂贵且不是处处可微分的,因此作者进行了两点简化:
- 分别对每个特征 normalize, 让它均值为0,方差为1
- 由于使用了 mini-batch 训练, 作者利用每个 mini-batch , 而不是整个数据集,的激活值来估计均值和方差
简单的 normalization 会改变输入数据的表达能力,比如对于 sigmoid 函数, 会让输入被限制在线性区域,失去非线性。为此。作者加入了一个变换操作,以确保网络可以实现一个恒等变换(identity transform)。
对于每个激活值 , 有
当 时, 我们可以还原数据。
Batch Normalizing TRansforrmBN 是可微的变换,在反向传播的时候可以计算各个参数的梯度。
求梯度3.1 训练与推理
在训练阶段使用 BN 可以加速训练, 但是在推理阶段(验证、测试)可能没有 batch。
利用训练时得到的mini-batch 的统计值, 为 batch size,对所有 batch 的均值方差做平均:
然后对测试的数据进行 normalization
训练流程3.2 卷积层BN
假设一个仿射变换 , 其中 是可学习的参数,这个形式可以包括全连接层和卷积层。 代表非线性函数。
作者将 BN 直接加载非线性函数之前,也就是 normalize 。 原因是 更有可能有一个对称的,非稀疏的分布,在这里做 normalization 更有可能得到一个稳定的分布。
因为 normalize了,偏差可以被忽略掉,因为它的影响将被随后的均值减法抵消, 被替换为 ,其中 BN 变换独立应用于 的每个维度,每个维度有一对单独的学习参数 。
3.3 BN可实现更高的学习率
在传统的深度网络中,过高的学习率可能会导致梯度爆炸或消失,以及陷入不良的局部最小值。批量标准化有助于解决这些问题。通过对整个网络的激活进行标准化,它可以防止参数的微小变化放大为梯度激活的较大和次优变化;比如,它可以防止训练陷入非线性的饱和状态。
BN 还使训练对参数规模更具弹性。通常,较大的学习率可能会增加层参数的规模,会放大反向传播过程中的梯度,并导致模型爆炸。然而,通过BN,通过层的反向传播不受其参数规模的影响。
假设有 ,在反向传播中
规模不影响每层雅可比矩阵,也不影响梯度传播。此外,较大的权重会导致较小的梯度,批量归一化将稳定参数增长。
3.4 Batch Normalization 正则化
模型使用 Batch Normalization 进行训练时,会看到一个训练样本与 mini-batch 中的其他样本相结合,并且训练网络不再为给定的训练示例生成确定性值。在作者的实验中,发现这种效果有利于网络的泛化。虽然 Dropout 通常用于减少过拟合,但在 BN 网络中,我们发现它可以被移除或减少使用。
4. pytorch 中的 BN 层
pytorch 中提供了 BatchNorm1d
, BatchNorm2d
,BatchNorm3d
,这里以BatchNorm2d
为例子,参数包括:
- num_features: 输入的通道数,如果输入大小为 (N,C,H,W),这里的值应该是C
- eps: 一个保持计算中数值稳定的值,默认值 1e-5
- momentum: 一个用来计算 running_mean 和 running_var 的值,可以设置为 None,会变为简单的计算平均,默认值为 0.1
- affine: 布尔值,为 True 时 BN 层会有两个可学习的参数, 也就是论文中的 ,默认值为 True
- track_running_stats: 布尔值,为 True 时 会追踪计算 running_mean 和 running_var;为 False 时,不追踪统计信息,并将缓冲区中的 running_mean 和 running_var 初始化为 None。当它们为 None 时,BN 在训练和推理阶段dou会只使用 batch 的统计信息,默认值为 True
输出 size 与输入相同,都是 (N,C,H,W)。
关于momentum,与 optimizer 中控制梯度下降的 momentum 不同, 这里的momentum 是用在计算统计量的,,其中 是估计的整个数据集的统计量,是新观测到的值,也就是当前 mini-batch 计算得到的统计量。
这个公式可以这样理解,在上面的 algorithm2 中,推理阶段使用的 需要每一个Batch的均值和方差,训练完成之后按照公式计算平均。对于 ,在第n个 batch时更新
当 时, 就是上面的计算平均的公式。
参考:
https://zhuanlan.zhihu.com/p/50444499
https://blog.csdn.net/qq_37524214/article/details/108559989
https://blog.csdn.net/APTX2334869/article/details/102716147
https://blog.csdn.net/joyce_peng/article/details/103163048