您的位置:

Batch_Normalization详解

Batch_Normalization,简称BN,是一种针对神经网络中分布不稳定的提出的正则化手段。在深度学习中,BN是十分重要的一个模块,它可以在训练过程中加速网络收敛,同时增加了模型的泛化能力。在本文中,我们将对BN进行详细的介绍。

一、batchnorm的方差shape

对于输入的$N\times C \times H \times W$的四维数据,BN中对于每个channel需要统计出其平均值和方差。具体来说,如下:

// 计算每个channel的均值和方差
mean = sum(x, (0, 2, 3), keepdim=True) / (x.shape[0] * x.shape[2] * x.shape[3])
variance = sum((x - mean) ** 2, axis=(0, 2, 3), keepdim=True) / (x.shape[0] * x.shape[2] * x.shape[3])

对于计算出的均值和方差,可以使用以下公式对BN进行标准化:

y = (x - mean) / sqrt(variance + eps)

其中eps为一个较小的数,用来避免分母为零的情况。最后加入了权重和偏置项,以得到最终标准化结果。

二、BatchNormalizationLayer Matlab

在Matlab中,可以很方便地使用BatchNormalizationLayer层来进行BN。

% 创建一层batchnorm,inputSize为输入数据的size
batchnormLayer = batchNormalizationLayer('Name','bn','Epsilon',0.001,'Offset',zeros(1,inputSize(3),'single'),'Scale',ones(1,inputSize(3),'single'));

% 前向传播
bn_res = predict(batchnormLayer, x);

三、Normalization

除了BN,还有一种正则化方法叫做Normalization。Normalization是对于某一层的所有输入数据进行正则化,而BN是对于每个channel进行标准化,因此Normalization所需要的参数要比BN多,更难训练。但是Normalization在某些情况下可能表现更好,比如处理非常稀疏的数据。

四、Layer Normalization

BN在处理图像分类等场景表现比较好,但是对于RNN等序列问题表现较差,这时候可以使用Layer Normalization。它与BN的区别在于:BN是在数据在$N\times C \times H \times W$的四个维度上进行标准化,而LayerNorm是在$N\times L \times C$的三个维度上进行标准化,即一个batch的所有样本都共用一组mean和variance。LayerNormalization的具体公式如下:

z = (x - mean) / sqrt(variance + eps)
y = gamma * z + beta

五、Batchnorm的原理和作用

BN是一种归一化方法,其主要原理就是让每一层的输入数据分布尽量接近于标准正态分布。在深度神经网络中,随着层数的增加,输入数据的分布越来越偏离标准正态分布,容易出现梯度消失和梯度爆炸等问题,影响网络的训练效果。而BN可以通过标准化来解决这个问题,并且在训练过程中动态调整输入数据的均值和方差,降低了网络对初始化的依赖,加速了网络训练的收敛速度。此外,BN还可以起到正则化的作用,避免过拟合。

六、Batchnorm会造成illegal memory

在某些情况下,BN可能会导致illegal memory访问错误,这是由于batch size过小,导致方差为0。此时,可以在BN的代码中增加一定的容错机制,比如将eps设置成一个较小的数(如$1e-5$),即可解决该问题。

七、Batchnormalization层的作用

BN层是深度学习中很重要的一层,主要作用如下:

  • 加速网络训练:
  • 减少了网络对参数初始化的依赖,加速了网络收敛的速度。

  • 提高网络泛化能力:
  • 在训练过程中动态调整输入数据的均值和方差使得网络更加鲁棒,具有更好的泛化能力。

  • 正则化:
  • 通过对输入数据进行标准化来避免过拟合。

八、Batchnormalization和Layer选取

在选择使用哪一种归一化方法时,需要考虑输入数据的性质和具体的任务。如果是图像分类等场景,可以优先选择BN。如果是序列问题,可以选择LN。 在实际应用中,也可以同时使用BN和LN,进一步提高泛化性。

代码示例

以下是tensorflow中BN的具体代码,以MNIST数据集为例。

import tensorflow as tf

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test, verbose=2)

在上面的代码中,使用了Sequential模型,加入了一个BN层以及两个全联接层。代码简单易懂,并且有了BN层的加入,模型的准确率会更高。