深度学习——Internal Covariate Shift与Normalization

转载自 https://blog.****.net/sinat_33741547/article/details/87158830

Internal Covariate Shift与Normalization

一、“Internal Covariate Shift”问题

什么是“Internal Covariate Shift”?

深度神经网络涉及到很多层的叠加,而每一层的参数更新会导致上层的输入数据分布发生变化,通过层层叠加,高层的输入分布变化会非常剧烈,这就使得高层需要不断去重新适应底层的参数更新。为了训好模型,我们需要非常谨慎地去设定学习率、初始化权重、以及尽可能细致的参数更新策略。
Google 将这一现象总结为 Internal Covariate Shift,简称 ICS.

所以ICS是什么呢?将每一层的输入作为一个分布看待,由于底层的参数随着训练更新,导致相同的输入分布得到的输出分布改变了。

机器学习领域有个很重要的假设:IID独立同分布假设,就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。

细化到神经网络的每一层间,每轮训练时分布都是不一致,那么相对的训练效果就得不到保障,所以称为层间的covariate shift。Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。

深度学习——Internal Covariate Shift与Normalization

可以看到,随着网络层数的加深,输入分布经过多次线性非线性变换,已经被改变了,但是它对应的标签,如分类,还是一致的,即使条件概率一致,边缘概率不同。

因此,每个神经元的输入数据不再是“独立同分布”,导致了以下问题:

1、上层网络需要不断适应新的输入数据分布,降低学习速度。
2、下层输入的变化可能趋向于变大或者变小,导致上层落入饱和区,使得学习过早停止。
3、每层的更新都会影响到其它层,因此每层的参数更新策略需要尽可能的谨慎。

解决思想

前面说到,出现上述问题的根本原因是神经网络每层之间,无法满足基本假设"独立同分布",那么思路应该是怎么使得输入分布满足独立同分布。

白化(Whitening)

白化(Whitening)是机器学习里面常用的一种规范化数据分布的方法,主要是PCA白化与ZCA白化。

白化是对输入数据分布进行变换,进而达到以下两个目的:
1、使得输入特征分布具有相同的均值与方差,其中PCA白化保证了所有特征分布均值为0,方差为1;而ZCA白化则保证了所有特征分布均值为0,方差相同
2、去除特征之间的相关性。
通过白化操作,我们可以减缓ICS的问题,进而固定了每一层网络输入分布,加速网络训练过程的收敛。

Normalization

白化计算成本太高,每一轮训练中的每一层都需要做白化操作;同时白化改变了网络每一层的分布,导致网络层中数据的表达能力受限。因此提出了normalization方法,能够简化计算过程;又能够让数据尽可能保留原始的表达能力。

Normalization,标准化就是将分布变换为均值方差一致的分布。

这么做能够加速收敛的本质是什么呢?

假设存在U=Wx+b ,Z=F(U) ,其中x 是输入,F 是**函数,那么:
在训练过程中,随着网络加深,分布逐渐发生变动,导致整体分布逐渐往**函数的饱和区间移动,从而反向传播时底层出现梯度消失,也就是收敛越来越慢的原因。
而Normalization则是把分布强行拉回到均值为0方差为1的标准正态分布,使得**输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,避免梯度消失问题产生,加速收敛,如下:深度学习——Internal Covariate Shift与Normalization

如上,假设正态分布均值是-2,方差是0.5,如上图绿色曲线,通过标准化操作转换为均值为0,方差为1的正态分布,如上图红色曲线。实际上是将输入x的取值正态分布整体右移2(均值变化),图形曲线更平缓了(方差变化)。那么这么做的好处是什么呢?

深度学习——Internal Covariate Shift与Normalization

上图为标准正态分布的图形,可以看到,在一个标准差范围,有68%的概率x其值落在[-1,1]的范围内;在两个标准差范围,有95%的概率x其值落在了[-2,2]的范围内,假如这就是需要进行**的分布,**函数为sigmoid,如下:深度学习——Internal Covariate Shift与Normalization

可以看到,在[-2, 2]的范围内,即是标准正态分布两个标注差范围内,在sigmoid函数中为线性变换区域,微小的变化就能得到很大的改变,也即是梯度比较大。
如果不经过变换,存在一个均值为-6,方差为1的分布,对应到**函数中就是[-8, -4]的区域,这已经是饱和区了,这也就是所谓的梯度消失。
所以标准化其实就是把大部分**的值落入非线性函数的线性区内,其对应的导数远离导数饱和区,这样来加速训练收敛过程。

这样看起来很美好,但是实际上呢?
如果使用标准化,那就相当于把非线性**函数替换成线性函数了。那么使用非线性**的意义在哪里呢,多层线性网络跟一层线性网络是等价的,也就是网络的表达能力下降了。

为了保证非线性表达能力,后面又对此打了个补丁,对变换后的满足均值为0方差为1的x进行了scale加上shift操作,形成类似y=scale∗x+shift这种形式,参数通过训练进行学习,把标准正态分布左移或者右移一点,并且长胖一点或者变瘦一点,将分布从线性区往非线性区稍微移动,希望找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力,又能够享受线性区较大的下降梯度。因此,通用的标准化公式如下:

深度学习——Internal Covariate Shift与Normalization

(1)μ——平移参数(shift parameter),σ——缩放参数(scale parameter),通过这两个参数进行shift和scale变换,得到的数据符合均值为0,方差为1 的标准分布

深度学习——Internal Covariate Shift与Normalization

(2)b——再平移参数(re-shift parameter),b——再缩放参数(re-scale parameter),将上一步得到的深度学习——Internal Covariate Shift与Normalization进一步变换为

深度学习——Internal Covariate Shift与Normalization,最终得到的数据符合均值为b, 方差为g^2的分布。