一、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层的加入,模型的准确率会更高。