标准化(Batch Normalization,BN),又叫批量归一化,是一种用于改善人工神经网络的性能和稳定性的技术。 这是一种为神经网络中的任何层提供零均值/单位方差输入的技术。

什么是标准化?

传统机器学习中标准化也叫做归一化。一般是将数据映射到指定的范围,用于去除不同维度数据的量纲以及量纲单位。归一化目的就是将不同尺度上的评判结果统一到一个尺度上,从而可以作比较,作计算。

常用的归一化方法之一

数据标准化让机器学习模型看到的不同样本彼此之间更加相似,这有助于模型的学习与对新数据的泛化。

在机器学习中,进行标准化常见的形式有:

标准化以及归一化:将数据减去其平均值使其中心为0,然后将数据除以其标准差使其标准差为1。

归一化:1)把数据变成(0,1)之间的小数。主要是为了数据处理方便提出来的,把数据映射到0~1范围之内处理,更加便捷快速。2)把有量纲表达式变成无量纲表达式,便于不同单位或量级的指标能够进行比较和加权。归一化是一种简化计算的方式,即将有量纲的表达式,经过变换,化为无量纲的表达式,成为纯量。

标准化:在机器学习中,我们可能要处理不同种类的资料,例如,音讯和图片上的像素值,这些资料可能是高维度的,资料标准化后会使每个特征中的数值平均变为0(将每个特征的值都减掉原始资料中该特征的平均)、标准差变为1,这个方法被广泛的使用在许多机器学习算法中(例如:支持向量机、逻辑回归和类神经网络)。

中心化:平均值为0,对标准差无要求

归一化和标准化的区别:归一化是将样本的特征值转换到同一量纲下把数据映射到[0,1]或者[-1, 1]区间内,仅由变量的极值决定,因区间放缩法是归一化的一种。标准化是依照特征矩阵的列处理数据,其通过求z-score的方法,转换为标准正态分布,和整体样本分布相关,每个样本点都能对标准化产生影响。它们的相同点在于都能取消由于量纲不同引起的误差;都是一种线性变换,都是对向量X按照比例压缩再进行平移。

标准化和中心化的区别:标准化是原始分数减去平均数然后除以标准差,中心化是原始分数减去平均数。 所以一般流程为先中心化再标准化。

无量纲:我的理解就是通过某种方法能去掉实际过程中的单位,从而简化计算。

什么是批标准化?

批标准化(Batch Normalization),和普通的数据标准化类似,是将分散的数据统一的一种做法,也是优化神经网络的一种方法。

不仅在将数据输入模型之前对数据做标准化。在网络的每一次变换之后都应该考虑数据标准化。即使在训练过程中均值和方差随时间发生变化,它也可以适应性地将数据标准化。

批标准化有什么好处?

批标准化解决的问题是梯度消失与梯度爆炸。批标准化一种训练优化方法。

关于梯度消失,以sigmoid函数为例子,sigmoid函数使得输出在[0,1]之间。如下图所示:

梯度爆炸

除了这个,我们知道数据预处理做标准化可以加速收敛,同理,在神经网络使用标准化也可以加速收敛,而且还有更多好处。

  • 具有正则化的效果
  • 提高模型的泛化能力
  • 允许更高的学习速率从而加速收敛

批标准化有助于梯度传播,内此计史i休日M白。入于有些特别深的网络,只有包含多个BatchNormalization层时才能进行训练。

批标准化在TensorFlow中的使用

BatchNormalization广泛用于Keras内置的许多高级卷积神经网络架构,比如ResNet50、InceptionV3和Xception。BatchNormalization层通常在卷积层或密集连接层之后使用。Tf.keras.layers.Batchnormalization()这个命令是实现批标准化的命令。

1、求每一个训练批次数据的均值

2、求每一个训练批次数据的方差

3、数据进行标准化

4、训练参数α,β

5、输出y通过α与β的线性变换得到原来的数值

在训练的正向传播中,不会改变当前输出,只记录下y与β。在反向传播的时候,根据求得的y与β通过链式求导方式,求出学习速率以至改变权值。

对于预测阶段时所使用的均值和方差,其实也是来源于训练集。比如我们在模型训练时我们就记录下每个batch下的均值和方差,待训练完毕后,我们求整个训练样本的均值和方差期望值,作为我们进行预测时进行BN的的均值和方差。

批标准化的使用位置:training: Python布尔值,指示图层应在训练模式还是在推理模式下运行。

  • training=True:该图层将使用当前批输入的均值和方差对其输入进行标准化。

  • training=False:该层将使用在训练期间学习的移动统计数据的均值和方差来标准化其输入。

代码展示

仍然使用的是之前的飞机和湖泊分类的案例:

新手入门CNN综合实例_卷积神经网络实战_卫星图像识别

其他部分都是一样的,这里仅仅改变了建立模型,在中间加了一个批标准化层。原始论文讲在CNN中一般应作用与非线性激活函数之前,但是,实际上放在激活函数之后效果可能会更好。这里还是按照原始论文的做法,在激活函数之前添加的批标准化。

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64,(3,3), input_shape=(256,256,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化层       
model.add(tf.keras.layers.Activation('relu'))                                   
# 这里的批标准化放在卷积层的后面,实际上放在激活函数之后效果可能会更好。

model.add(tf.keras.layers.Conv2D(64,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))              

model.add(tf.keras.layers.MaxPool2D())

model.add(tf.keras.layers.Conv2D(128,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化                                    
model.add(tf.keras.layers.Activation('relu'))                                   

model.add(tf.keras.layers.MaxPool2D())

model.add(tf.keras.layers.Conv2D(256,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))            

model.add(tf.keras.layers.Conv2D(64,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))            

model.add(tf.keras.layers.MaxPool2D())

model.add(tf.keras.layers.Conv2D(512,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))             

model.add(tf.keras.layers.Conv2D(512,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))

model.add(tf.keras.layers.Conv2D(512,(3,3))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))          

# 再添加一个全局平均池化,将四维数组[batch height width channel]转化为二维的[batch imageCharacter]
# 这是为了在Dense层进行读取数据
model.add(tf.keras.layers.GlobalAveragePooling2D())

# 添加Dense层
model.add(tf.keras.layers.Dense(1024))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))          

# 添加Dense层
model.add(tf.keras.layers.Dense(256))
model.add(tf.keras.layers.BatchNormalization())    # 批标准化       
model.add(tf.keras.layers.Activation('relu'))           

model.add(tf.keras.layers.Dense(1, activation='sigmoid'))   # 逻辑回归,二分类

可以通过运行一下,来查看效果:

添加批标准化的效果


版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/BatchNormalization.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!
▶ 站长邮箱 [email protected][email protected] ,如不方便留言可邮件联系。

最后修改:2022 年 09 月 28 日
如果觉得我的文章对你有用,请随意赞赏