前言
1.批量归一化
1.1什么是批量归一化?
批量归一化(Batch Normalization),通常缩写为BN,是一种在训练深度神经网络时用于提高训练速度、稳定性和性能的技术。它通过规范化(归一化)层的输入来减少内部协变量偏移,从而使得网络的每一层都输入到一个相对稳定的环境中。批量归一化的核心思想是通过对神经网络中的输入进行归一化处理,从而稳定这些输入的分布,减少训练过程中输入分布的变化。
这种方法不仅有助于加速训练,还能够提高模型的泛化能力和稳定性。通过引入可学习的缩放和平移参数,批量归一化保持了网络的表达能力,允许模型学习到有用的特征表示。
1.2为什么需要批量归一化?
在训练过程中,每层输入的分布不断的变化,这使得下一层需要不断的去适应新的数据分布,在深度神经网络中,这让训练变得非常复杂而且缓慢。对于这样,往往需要设置更小的学习率、更严格的参数初始化。通过使用批量归一化(Batch Normalization, BN),在模型的训练过程中利用小批量的均值和方差调整神经网络中间的输出,从而使得各层之间的输出都符合均值、方差相同高斯分布,这样的话会使得数据更加稳定,无论隐藏层的参数如何变化,可以确定的是前一层网络输出数据的均值、方差是已知的、固定的,这样就解决了数据分布不断改变带来的训练缓慢、小学习率等问题。
2.特征归一化
计算公式如上图。其中,代表
的第一个元素,
代表
的第一个元素,以此类推。
3. BN源码实现
m = K.mean(X, axis=-1, keepdims=True)#计算均值
std = K.std(X, axis=-1, keepdims=True)#计算标准差
X_normed = (X - m) / (std + self.epsilon)#归一化
out = self.gamma * X_normed + self.beta#重构变换
正文
深度学习的归一化如下图:
在这里,代表归一化的特征,把它丢到深度网络中,去做接下来的计算和训练。
通过第一层得到
,有可能通过激活函数,不管是选 sigmoid 或者 ReLU 都可以,再得到
,接着再通过下一层等等。对每个都做类似的事情。
虽然 已经做归一化了,但是通过
以后,没有做归一化。如果
通过
得到
,而
不同的维度间,它的数值的分布仍然有很大的差异,训练
,第二层的参数也会有困难。对于
,
或
其实也是一种特征,也应该要对这些特征做归一化。如果选择 sigmoid比较推荐对
做特征归一化,因为sigmoid是一个
的形状,其在0附近斜率比较大,如果对
做特征归一化,把所有的值都挪到0附近,到时候算梯度的时候,算出来的值会比较大。如果使用别的激活函数,可能对
归一化也会有好的结果。一般而言,特征归一化,要放在激活函数之前,之后都是可以的,在实现上,没有太大的差别。
下面对进行归一化,计算公式如下图:
归一化过程如下图:
批量归一化可以理解为网络的一部分
但是,存在这么个问题:如上图所示,接下来可以通过激活函数得到其他向量,跟
都是根据
,
,
计算出来的。改变了
的值,
的值也会改变,
和
也会改变。
,
改后,
,
,
,
的值也会改变。之前的
,
,
是独立分开处理的,但是在做特征归一化以后,这三个样本变得彼此关联了。所以有做特征归一化的时候,可以把整个过程当做是网络的一部分。即有一个比较大的网络,该网络吃一堆输入,用这堆输入在这个网络里面计算出
,
,接下来产生一堆输出。这边就会有一个问题了,因为训练数据非常多,现在一个数据集可能有上百万笔数据,GPU 的显存无法把它整个数据集的数据都加载进去。因此,在实现的时候,我们不会让这一个网络考虑整个训练数据里面的所有样本,而是只会考虑一个批量里面的样本。比如批量设 64,这个网络就是把 64笔数据读进去,计算这 64 笔数据的
,
,对这 64笔数据做归一化。因为实际实现的时候,只对一个批量里面的数据做归一化,所以技巧称为批量归一化。一定要有一个够大的批量,才算得出
,
。所以批量归一化适用于批量大小比较大的时候,批量大小如果比较大,也许这个批量大小里面的数据就足以表示整个数据集的分布。这个时候就不需要对整个数据集做特征归一化,而改成只在一个批量上做特征归一化作为近似。
在做批量归一化的时候,如下图所示,往往还会做如下操作:
其中,代表逐元素的相乘。
,
可以想成是网络的参数,需要另外再被学习出来。
还要对这个归一化的数值进行伸缩(Scale)和偏移(Shift)。是一个伸缩系数,可以对数据扩大或缩小,它和
的维度相同,
表示
中的每个元素与归一化之后的
按元素(Element-wise)做乘法。
是一个偏移系数,它和
的维度相同,按元素做加法。
和
是两个需要学习的参数。对于一个输入
,经过
后,得到的数据符合均值为
,方差为
的分布。
一个疑问是,明明是为了进行归一化,我们得到了均值为0,方差为单位误差的分布了,为什么又在归一化的基础上加了伸缩和平移?怎么又变回去了?答案是:为了保障模型的表达能力不因为归一化而下降。直观上来讲,神经网络某一层的在努力地学习,如果只做,那么这一层的输出会被粗暴地限制到某个固定的范围,后续层输入都是这样一个分布的数据。有了伸缩和平移,而且这两个参数是需要学习的参数,那么这一层的输出就不再被粗暴归一化的了。
声明
本学习笔记为此笔记发布者使用,以便完成Datawhale AI 夏令营第五期Task03打卡任务,同时记录自己的学习过程。该笔记在原文的基础上进行删改,对个别部分用黑体或者其他字体着重强调以便及时记忆理解。本笔记并不做任何以盈利为目的的用途,仅供个人学习使用,若有侵权,请第一时间告知本人,侵删。