卷积神经网络的网络结构——Inception V2

《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》
  • 2015,Google,Inception V2

Inception V2学习了VGGNet,用两个3*3的卷积代替5*5的大卷积(用以降低参数并减轻过拟合),还提出了著名的Batch Normalization(简称BN)方法。BN是一个非常有效的正则化方法,可以让大型卷积网络的训练速度加快很多倍,同时收敛后的分类准确率也可以得到大幅提高。BN在用于神经网络某层时,会对每一个mini-batch数据的内部进行标准化(normalization),使输出规范到N(0,1)的正太分布,减少了Internal Covariate Shift(内部神经元的数据分布发生变化)。BN的论文指出,传统的深度神经网络在训练时,每一层的输入的分布都在变化,导致训练变得困难,我们只能使用一个很小的学习速率解决这个问题。而对每一层使用BN之后,我们就可以有效地解决这个问题,学习速率可以增大很多倍,达到之前的准确率所需的迭代次数只有1/14,训练时间大大缩短。而达到之前的准确率后,可以继续训练,并最终取得远超于Inceotion V1模型的性能—top5错误率4.8%,已经优于人眼水平。因为BN某种意义上还起到了正则化的作用,所以可以减少或者取消Dropout,简化模型结构。

当然只是单纯地使用BN获得的增益还不明显,还需要一些相应的调整:增大学习率并加快学习衰减速度以使用BN规范化的数据;去除Dropout并减轻L2正则(因BN已经起到正则化的作用);去除LRN;更彻底地对训练样本进行shuffle;减少数据增强过程中的对数据的光学畸变(因为BN训练更快,每个样本被训练的次数更少,因此更真实的样本对训练更有帮助)。在使用这些措施后,Inception V2在训练达到Inception V1的准确率时快了14倍,并且模型在收敛时的准确率上限更高。

BN:Batch Normalization:解决在训练过程中,中间层数据分布发生改变的问题,以防止梯度消失或爆炸、加快训练速度
神经网络学习过程本质就是为了:学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低,所以需要使用输入数据归一化方法,使训练数据与测试数据的分布相同。
1. 数据预算处理(Data Preprocessing)
这里写图片描述
析:为什么输入数据需要归一化(Normalized Data)?
归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。
对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。
2. 权重初始化(Weight Initialization)
1)小的随机数
w= 0.01 * np.random.randn(fan_in,fan_out)
2)神经元将饱和,梯度为0
w = 1.0 * np.random.randn(fan_in,fan_out)
3)合理的初始化(Xavier init)
w = np.random.randn((fan_in,fan_out)/np.sqrt(fan_in)
权重初始化是一个重要的研究领域。
3. 批量归一化(BN: Batch Normalization)

3.1 BN训练
1)随机梯度下降法(SGD)对于训练深度网络简单高效,但是它有个毛病,就是需要我们人为的去选择参数,比如学习率、参数初始化、权重衰减系数、Drop out比例等。这些参数的选择对训练结果至关重要,以至于我们很多时间都浪费在这些的调参上。那么使用BN之后,你可以不需要那么刻意的慢慢调整参数。
2)神经网络一旦训练起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization,这个牛逼算法的诞生。
3)BN的地位:与激活函数层、卷积层、全连接层、池化层一样,BN(Batch Normalization)也属于网络的一层。
4)BN的本质原理:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理(归一化至:均值0、方差为1),然后再进入网络的下一层。不过文献归一化层,可不像我们想象的那么简单,它是一个可学习、有参数(γ、β)的网络层。
5)归一化公式:
这里写图片描述
6)如果是仅仅使用上面的归一化公式,对网络某一层A的输出数据做归一化,然后送入网络下一层B,这样是会影响到本层网络A所学习到的特征的。比如我网络中间某一层学习到特征数据本身就分布在S型激活函数的两侧,你强制把它给我归一化处理、标准差也限制在了1,把数据变换成分布于s函数的中间部分,这样就相当于我这一层网络所学习到的特征分布被你搞坏了,这可怎么办?于是文献使出了一招惊天地泣鬼神的招式:变换重构,引入了可学习参数γ、β,这就是算法关键之处:
这里写图片描述
上面的公式表明,通过学习到的重构参数γ、β,是可以恢复出原始的某一层所学到的特征的。
注:《参考:https://blog.csdn.net/myarrow/article/details/51848285
这里写图片描述
7)引入了这个可学习重构参数γ、β,让我们的网络可以学习恢复出原始网络所要学习的特征分布。最后Batch Normalization网络层的前向传导过程公式就是:
这里写图片描述
这里写图片描述
8)BN层是对于每个神经元做归一化处理,甚至只需要对某一个神经元进行归一化,而不是对一整层网络的神经元进行归一化。既然BN是对单个神经元的运算,那么在CNN中卷积层上要怎么搞?假如某一层卷积层有6个特征图,每个特征图的大小是100*100,这样就相当于这一层网络有6*100*100个神经元,如果采用BN,就会有6*100*100个参数γ、β,这样岂不是太恐怖了。因此卷积层上的BN使用,其实也是使用了类似权值共享的策略,把一整张特征图当做一个神经元进行处理。
9)卷积神经网络经过卷积后得到的是一系列的特征图,如果min-batch sizes为m,那么网络某一层输入数据可以表示为四维矩阵(m,f,w,h),m为min-batch sizes,f为特征图个数,w、h分别为特征图的宽高。在CNN中我们可以把每个特征图看成是一个特征处理(一个神经元),因此在使用Batch Normalization,mini-batch size 的大小就是:m*w*h,于是对于每个特征图都只有一对可学习参数:γ、β。说白了吧,这就是相当于求取所有样本所对应的一个特征图的所有神经元的平均值、方差,然后对这个特征图神经元做归一化。
10)在使用BN前,减小学习率、小心的权重初始化的目的是:使其输出的数据分布不要发生太大的变化。
11) BN的作用:
1)改善流经网络的梯度
2)允许更大的学习率,大幅提高训练速度:
你可以选择比较大的初始学习率,让你的训练速度飙涨。以前还需要慢慢调整学习率,甚至在网络训练到一半的时候,还需要想着学习率进一步调小的比例选择多少比较合适,现在我们可以采用初始很大的学习率,然后学习率的衰减速度也很大,因为这个算法收敛很快。当然这个算法即使你选择了较小的学习率,也比以前的收敛速度快,因为它具有快速训练收敛的特性;
3)减少对初始化的强烈依赖
4)改善正则化策略:作为正则化的一种形式,轻微减少了对dropout的需求
你再也不用去理会过拟合中drop out、L2正则项参数的选择问题,采用BN算法后,你可以移除这两项了参数,或者可以选择更小的L2正则约束参数了,因为BN具有提高网络泛化能力的特性;
5)再也不需要使用使用局部响应归一化层了(LRN),因为BN本身就是一个归一化;
6)可以把训练数据彻底打乱(防止每批训练的时候,某一个样本都经常被挑选到,文献说这个可以提高1%的精度)。
注:以上为学习过程,在测试时,均值和方差(mean/std)不基于小批量进行计算, 可取训练过程中的激活值的均值。
3.2 BN测试
1)实际测试时,我们依然使用下面的公式:
这里写图片描述
这里的均值和方差已经不是针对某一个Batch了,而是针对整个数据集而言。因此,在训练过程中除了正常的前向传播和反向求导之外,我们还要记录每一个Batch的均值和方差,以便训练完成之后按照下式计算整体的均值和方差:
这里写图片描述
上面简单理解就是:对于均值来说直接计算所有batch uB值的平均值;然后对于标准偏差采用每个batch σB的无偏估计。最后测试阶段,BN的使用公式就是:
这里写图片描述
BN可以应用于一个神经网络的任何神经元上。文献主要是把BN变换,置于网络激活函数层的前面。在没有采用BN的时候,激活函数层是这样的:
z=g(Wu+b)
也就是我们希望一个激活函数,比如s型函数s(x)的自变量x是经过BN处理后的结果。因

此前向传导的计算公式就应该是:
z=g(BN(Wu+b))
其实因为偏置参数b经过BN层后其实是没有用的,最后也会被均值归一化,当然BN层后面还有个β参数作为偏置项,所以b这个参数就可以不用了。因此最后把BN层+激活函数层就变成了:
z=g(BN(Wu))
3.3 批量归一化Batch Normalization(BN)
为了便于训练,我们经常对归一化参数进行初始值,通过mean=0, variance=1的高斯分布来初始化参数。在训练过程中,我们不同程度地更新参数,使用参数失去了归一化,这将降低训练速度且放大变化,网络越深问题越严重。
BN为每一个mini-batch重建归一化参数。使模型结构的部分进行归一化,我们可以使用更高的learning rate,且参数初始化要求没哪么高。
此外,BN还作为一个正则化(Regularizer),可以减少或避免使用Dropout。
正则化(Regularizer):是一个用于解决过拟合(Overfitting)问题的一种技术。具体实现方法是在损失函数中增加惩罚因子(参数向量的范数,1范数(L1)或2范数(L2))lambda*N(w)。

Inception V2网络结构:
这里写图片描述
BN的实现:
1.原理
公式如下:y=γ(x-μ)/σ+β
其中x是输入,y是输出,μ是均值,σ是方差,γ和β是缩放(scale)、偏移(offset)系数。
一般来讲,这些参数都是基于channel来做的,比如输入x是一个16*32*32*128(NWHC格式)的feature map,那么上述参数都是128维的向量。其中γ和β是可有可无的,有的话,就是一个可以学习的参数(参与前向后向),没有的话,就简化成y=(x-μ)/σ。而μ和σ,在训练的时候,使用的是batch内的统计值,测试/预测的时候,采用的是训练时计算出的滑动平均值。
2.tensorflow中使用
tensorflow中batch normalization的实现主要有下面三个:
tf.nn.batch_normalization
tf.layers.batch_normalization
tf.contrib.layers.batch_norm
封装程度逐个递进,建议使用tf.layers.batch_normalization或tf.contrib.layers.batch_norm,因为在tensorflow官网的解释比较详细。


注:博众家之所长,集群英之荟萃。

猜你喜欢

转载自blog.csdn.net/u013841196/article/details/80629922
今日推荐