【调参13】如何使用Batch Normalization提高模型性能



1. Batch Normalization(批归一化)简介


【Paper】Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift


训练数十层的深度神经网络具有挑战性,因为它们可能对初始随机权重和学习算法的配置敏感。造成此困难的一个可能原因是,在每次批批处理之后,当权重更新时,输入到网络深层的分布可能会发生变化。这可能导致学习算法永远追逐运动目标。网络中各层的输入分布的这种变化,在技术上称为内部协变量平移(internal covariate shift)

批归一化是一种用于训练非常深的神经网络的技术,该技术可将每个批处理的输入标准化。不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中“梯度弥散”的问题,从而使得训练深层网络模型更加容易和稳定。在某些情况下,可以将训练时间减少一半或更短,并提供一些正则化功能,从而减少泛化误差。


1.1 训练深层网络的问题

这一挑战的一个方面是,使用误差估计将模型从输出到输入逐层更新,该估计假定当前层之前各层的权重是固定的。实际上,会同时更新所有层。由于在更新过程中所有层均已更改,因此更新过程将永远追逐移动的目标。例如,给定期望先前层输出具有给定分布的值的情况下,更新层的权重。在更新前一层的权重后,此分布可能会更改。

训练深度神经网络非常复杂,因为在训练过程中,随着先前各层的参数发生变化,各层输入的分布也会发生变化。通常会设置较低的学习率和仔细的参数初始化来减缓训练速度,并且训练具有饱和非线性的模型非常困难。提出批归一化的论文作者将训练期间输入分布的变化称为内部协变量平移(internal covariate shift)


1.2 标准化层输入

批归一化(Batch Normalization),简称batchnorm,它提供了一种重新配置几乎所有深层网络的绝佳方法。重新参数化大大减少了跨多个层协调更新(coordinating updates)的问题。

它通过标准化每个小批量的每个输入变量的激活,例如来自上一层的节点的激活,来缩放该层的输出。标准化(standardization)是指重新缩放数据以使其平均值为零,标准差为1,例如高斯标准化(standard Gaussian)。当应用于计算机视觉中的图像时,此过程也称为增白(whitening)

标准化前一层的激活意味着,假设后一层在权重更新期间对输入的分布和分布所做的假设不会改变,至少不会显着改变。这具有稳定和加快深度神经网络训练过程的效果。批归一化的作用是仅标准化每个单元的均值和方差,以稳定学习,但允许单元之间的关系和单个单元的非线性统计发生变化。

标准化对图层的输入会影响模型的训练,从而大大减少所需的时期数。它具有正则化效果,与使用激活正则化的方式非常相似,可以减少泛化误差。批量归一化可以对优化性能产生巨大影响,尤其是对于卷积网络和具有sigmoidal 非线性的网络。


1.3 如何标准化层输入

可以在训练期间通过计算每个批次的每个输入变量到一个层的平均值和标准偏差并使用这些统计信息执行标准化来实现批次标准化。或者,可以在批次之间维持平均值和标准偏差的移动平均值,但可能会导致训练不稳定。

训练后,可以将输入层的平均值和标准偏差设置为在训练数据集上观察到的平均值。对于小批量或不包含来自训练数据集的示例的代表性分布的小批量,训练和推理(训练后使用模型)之间的标准输入差异可能会导致性能上的明显差异。可以通过对称为**批重新归一化(BatchRenorm)**的方法进行修改来解决,该方法可使变量平均值和标准偏差的估计在批次之间更加稳定。批重归一化使用每个维度的校正扩展了batchnorm,以确保激活在训练网络和推理网络之间匹配。


【Paper】Batch Renormalization: Towards Reducing Minibatch Dependence in Batch-Normalized Models


输入的这种标准化可以应用于第一隐藏层的输入变量,也可以应用于来自较深层的隐藏层的激活。在实践中,通常允许该层学习两个新参数,即分别是新的均值Beta和标准差Gamma,这些参数允许自动缩放(scaling)和移动(shifting)标准化层输入。在训练过程中,模型会学习这些参数。

重要的是,将反向传播算法更新为对转换后的输入进行操作,并且误差还用于更新模型学习到的新比例(scale)和移位(shifting)参数。标准化应用于层的输入,即输入变量或来自先前层的激活函数的输出。给定激活函数的选择,该层的输入分布可能是非高斯的。在这种情况下,在上一层中的激活函数之前对总的激活进行标准化可能会有好处。


1.4 批归一化应用案例

概要 Paper 年份
Google的作者Sergey Ioffe和Christian Szegedy展示了基于Inception的卷积神经网络的显着加速,该神经网络可用于对照片进行分类超过了基线方法。通过仅使用批处理归一化,在不到训练步数一半的情况下就达到了Inception的准确率 Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift 2016
何恺明等人在非常深的模型ResNet中对卷积层进行了归一化处理(在每次卷积之后和激活之前都采用批量归一化),然后在ImageNet数据集上实现了最新的结果,这是标准的照片分类任务。 Deep Residual Learning for Image Recognition 2015
Christian Szegedy等人在GoogleNet Inception-v3中使用了批量归一化,从而在ImageNet数据集上获得了最先进的结果。(BN-auxiliary是指辅助分类器的全连接层也进行批标准化,而不仅仅是卷积。 Rethinking the Inception Architecture for Computer Vision 2016
百度的Dario Amodei在其端到端深度模型中使用了批量归一化递归神经网络的变体来进行语音识别。将其应用于大型数据集上非常深的RNN网络时,除了加速训练外,使用的BatchNorm变体还大大改善了最终泛化误差 Deep Speech 2 : End-to-End Speech Recognition in English and Mandarin 2016

1.5 批归一化使用技巧

1.5.1 与不同的网络类型一起使用

批量归一化是一种通用技术,可用于将输入归一化到一个层。它可用于大多数网络类型,例如多层感知器,卷积神经网络和递归神经网络。

1.5.2 激活前使用

在上一层激活功能之前或之后,可以在该层的输入上使用批量归一化。

像双曲正切和逻辑函数这样的S形激活函数,可能更适合在其之后使用批归一化。像ReLU这样的激活函数更适合在其之前使用。

批量归一化的目标是在整个训练过程中实现激活值的稳定分布,在我们的实验中,我们在非线性之前应用它,因为在此情况下,匹配第一和第二时刻更可能导致稳定分布。

1.5.3 使用大学习率

使用批量归一化可以使网络在训练过程中更加稳定。这可能需要使用比正常学习率大得多的速度,进而可以进一步加快学习过程。

1.5.4 对权重初始化不敏感

深度神经网络可能对训练之前用于初始化权重的技术非常敏感。批归一化带来的训练稳定性可以使训练深度网络对权重初始化方法的选择不那么敏感。

1.5.5 标准化输入数据

批量标准化可以用来标准化具有不同比例的原始输入变量。

如果为每个输入特征计算的均值和标准差是在批次上而不是在整个训练数据集上计算的,则批次大小必须足以代表每个变量的范围。对于数据分布高度非高斯的变量可能不合适,在这种情况下,最好将数据缩放作为预处理步骤。

1.5.6 不与Dropout 一起使用

批量归一化提供了一些正则化效果,减少了归纳误差,也许不再需要使用dropout进行正则化。从修改后的BN-Inception中删除Dropout可以加快训练速度,而不会增加过度拟合的情况。

此外,在同一网络中使用批处理规范化和Dropout可能不是一个好主意。原因是,考虑到在Dropout过程中节点随机退出(dropping),用于归一化先前层激活的统计信息可能会变得嘈杂。


2. Tensorflow.Keras API

tf.keras.layers.BatchNormalization(
    axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True,
    beta_initializer='zeros', gamma_initializer='ones',
    moving_mean_initializer='zeros', moving_variance_initializer='ones',
    beta_regularizer=None, gamma_regularizer=None, beta_constraint=None,
    gamma_constraint=None, renorm=False, renorm_clipping=None, renorm_momentum=0.99,
    fused=None, trainable=True, virtual_batch_size=None, adjustment=None, name=None,
    **kwargs
)

该层将转换输入,使其标准化,这意味着它们的平均值为零,标准差为1。在训练期间,该层将跟踪每个输入变量的统计信息,并使用它们来标准化数据。

此外,可以使用学习的Beta和Gamma参数来缩放标准化输出,这些参数定义了转换输出的新均值和标准差。该层可以配置为分别通过中心(center)和比例(scale)属性控制是否使用这些附加参数。默认情况下,它们是启用的。

用于执行标准化的统计信息(例如,每个小批量的每个变量的平均值和标准偏差)都会更新,并保持运行平均值。动量(momentum)参数可以控制在计算更新时要包含的上一个批处理中的统计量。默认情况下,该值保持为0.99。可以将其设置为0.0,以仅使用当前批次的统计信息,如原始论文所述。

2.1 输入和隐藏层输入

可以将BatchNormalization层添加到模型中,以标准化原始输入变量或隐藏层的输出。

不建议使用批量归一化来替代模型的适当数据准备。但是,当用于标准化原始输入变量时,该层必须指定input_shape参数;例如:

...
model = Sequential
model.add(BatchNormalization(input_shape=(2,)))
...

当用于标准化隐藏层的输出时,可以像其他任何层一样将层添加到模型中。

...
model = Sequential
...
model.add(BatchNormalization())
...

2.2 在激活函数之前或之后使用

BatchNormalization规范化层可用于标准化上一层激活功能之前或之后的输入。引入该方法的原始论文建议在前一层的激活函数之前添加批处理规范化,例如:

...
model = Sequential
model.add(Dense(32))
model.add(BatchNormalization())
model.add(Activation('relu'))
...

一些研究表明,在前一层的激活函数之后添加批归一化层时,性能会更好;例如:

...
model = Sequential
model.add(Dense(32, activation='relu'))
model.add(BatchNormalization())
...

如果时间和资源允许,应该在模型上测试这两种方法,并使用可产生最佳性能的方法。

2.3 MLP批归一化

# example of batch normalization for an mlp
from tensorflow.keras.layers import Dense, BatchNormalization
...
model.add(Dense(32, activation='relu'))
model.add(BatchNormalization())
model.add(Dense(1))
...

2.4 CNN批归一化

# example of batch normalization for an cnn
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, BatchNormalization
...
model.add(Conv2D(32, (3,3), activation='relu'))
model.add(Conv2D(32, (3,3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D())
model.add(Dense(1))
...

2.5 RNN批归一化

# example of batch normalization for a lstm
from tensorflow.keras.layers import Dense, LSTM, BatchNormalization
...
model.add(LSTM(32))
model.add(BatchNormalization())
model.add(Dense(1))
...

参考:
https://machinelearningmastery.com/batch-normalization-for-training-of-deep-neural-networks/
https://machinelearningmastery.com/how-to-accelerate-learning-of-deep-neural-networks-with-batch-normalization/
https://www.tensorflow.org/api_docs/python/tf/keras/layers/BatchNormalization?hl=en

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章