深度学习中的Normalization
引言
normalization中文意思是标准化,标准化就是对一组数据集合将其变成均值为0,方差为1的过程。
在深度网络中主要有两种实体:神经元和相邻两层相连的权重边。根据规范化对象的不同,可以分为两类:一类是对L层网络的输出值进行Normalization的操作,再根据如何划分输出值数据集合,可以分为BatchNormalization、LayerNormalization、InstanceNormalization和GroupNormalization。另一类是对神经网络相邻隐藏层神经元之间边上的权重进行规范化操作,比如Weight Normalization,代表的有对权重加l1,l2规范化。L1规范化目标造成参数稀疏,争取让大量参数取得0的效果,L2正则的目标是有效减少原始参数值的大小。
【L1与L2如何选择?】
BatchNormalization
在机器学习领域有一个很重要假设:独立同分布:就是假设训练数据和测试数据满足独立同分布,因此在训练集上训练出的模型在测试集上才会有好的效果。
而BatchNormalization就是让每一层神经网络的输入保持相同分布。
在深度学习中,随着网络层数加深,收敛越来越慢,Relu激活函数,残差网络都是用来解决这样问题的,BatchNormalization也是解决该问题。 在训练过程中,我们使用的是Mini-Batch SGD,相对于One Example SGD的优势:
1、梯度方向更新准确 2、并行速度快。
缺点:1、超参调起来麻烦(这里的超差指的是batch size吗?)
将batch数据输入到网络中,在每一层经过非线性转换之后,随着网络层数加深,数据分布逐渐发生偏移或者变动,之所以训练收敛慢,就是因为整体分布逐渐往非线性函数取值区间的上下限两端靠近,对于sigmoid函数来说这就导致后向传播过程中底层网络出现梯度消失现象,这就是为什么收敛变慢,而BN通过一定的规范化手段,将每层神经网络的输入的分布强行拉到均值为0,方差为1的标准正态分布,这样使得函数值落在非线性函数对输入比较敏感的区域,即使在输入上有微小的变化也会导致损失函数有较大的变化。这样使得就会让梯度变大,避免梯度消失,梯度变大意味着学习收敛速度快。
【疑问】:如果这样通过BN,不就把非线性函数替换成线性函数效果了?
多层线性函数变换是没意义的,多层线性网络同一层线性网络等价。BN为了保证非线性,对变化后的标准正态分布又进行了scale和shift操作(y=scale*x+shift),每个神经元增加两个参数(scale和shift),这两个参数是通过训练学习到的,意思是通过scale和shift将标准正态分布从正中心周围的线性区往非线性区移动。
就是通过缩放(scale)和平移(shift),尽量保持原来非线性函数学习到的特征。
核心思想就是找到一个线性和非线性较好的平衡点,既能享受非线性区较强表达能力的好处【为什么非线性区有较强的表达能力?以sigmoid为例,越接近两端结果越准,表达越清晰】,又能避免太靠非线性区两头使得网络收敛速度太慢。
BN如何训练
BN在MLP,CNN上非常成功,在RNN上效果不明显。 对一个Batch为n的数据,在某层神经元k上都会有一个输出值,所以在神经元k上会有n个输出,BN就是对在同一个神经元下batch的输出集合进行标准化。 CNN中,某一卷积层可能会有多个卷积核,CNN中规范化的集合就是同一个卷积核在batch个数据下输出的全部结果。 可以将一个卷积核想象成MLP中的一个神经元,就理解CNN规范化的数据集合了。
BN的缺点:
1、Batch Size太小,BN效果明显下降
原因:Batch size少,意味着数据样本少,BN是对一个Batch的数据进行统计(求均值求方差),数据样本少导致得不到有效的统计量,就是噪声太大。
2、对于有些像素级图片生成任务来说,BN效果不佳;
mini-batch内多张无关的图片之间计算统计量,弱化了单张照片本身特有的一些细节信息。
3、RNN等动态网络使用BN效果不佳且用起来不方便
对于输入是不定长的sequence, 同一个mini-batch中的训练实例长度不同。对于这样的mini-batch,意味着RNN在不同步会看到不同数量的输入数据,如果输入是一个特别长的例子,对于RNN来说统计量不方便且有效性也值得怀疑。
4、训练和推理时统计量的不一致
推理时是单个实例,没法获取均值和方差。解决方式是采用训练时刻记录的各个mini-batch的统计量,来推算全局的均值和方差。这样使得训练和推理统计量计算方式不一致。
总结:
使用BN时会使得batch内实例之间的相互依赖和影响,如何解决这个问题,就是不依赖batch内的数据,将数据单独拿出来统计均值和方差。
BN中的反向传播
https://kevinzakka.github.io/2016/09/14/batch_normalization/
LayerNormalization
一个数据如何形成一个数据的集合? 对于一个数据输入到隐藏层,不同的神经单元都会有一个输出结果,将同一层网络的不同神经元的输出结果作为规范化的集合就是LayerNormalization. MLP:就是同一隐藏层不同的神经元的输出 CNN:就是同一卷积层,不同卷积核的输出 RNN:也是同一隐藏层不同神经元的输出
InstanceNormalization
LayerNormalization抛弃了Batch的概念,将同层内所有神经元的输出作为统计集合,这个统计集合是否可以缩小?
【为什么缩小】我觉着是减少相关性吧,统计集合越大可能噪声也越多.
在LN的基础上,我们只统计一个卷积核的输出,LayerNormalization是统计全部卷积核的输出。 RNN和MLP是无法进行使用IN的。
对于BN中batch size为1的情况和Instance Norm 类似,【不同点?】
GroupNormalization
LayerNormalizaton是对某一卷积层所有的卷积核的输出进行统计,Instance Normalization是对某一卷积层每一个卷积核的输出进行统计,GroupNormalization是一种折中,对卷积核进行分组,再对每个组中的卷积核的输出进行统计。