[v1] Going Deeper with Convolutions, 6.67% test error, http://arxiv.org/abs/1409.4842
[v2] Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift, 4.8% test error, http://arxiv.org/abs/1502.03167
[v3] Rethinking the Inception Architecture for Computer Vision, 3.5% test error, http://arxiv.org/abs/1512.00567
[v4] Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning, 3.08% test error, http://arxiv.org/abs/1602.07261
##1.1 摘要
作者在文中提出了一种新的叫做Inception的结构,取得了ILSVRC-2014的分类和检测任务的冠军。作者设计的网络具有很大的depth和width,但是参数数量却仅为AlexNet的1/12。
近年来,CNN的发展不仅取决于数据集、计算能力,还取决于提出了新的算法和网络结构。作者提出的模型不仅可以用于学术研究,并且由于计算量较小,可以应用于实际业务。受NIN网络的影响,提出了Inception结构,显著提升了图像分类和检测的性能。
从LeNet-5开始,CNN有一套标准化的处理流程,即堆积卷积层(following by max-polling layer),后面再接数个全连接层,最后使用softmax loss。在mnist、cifar和ImageNet数据集上都取得了很好的效果,近期CNN的发展趋势是增大网络的depth和width,石头dropout预防过拟合。
作者借鉴了NIN网络中1*1卷积核的使用,起到了在不影响网络效果的情况下,降低了参数数量,增强了网络的depth和width。
对标了R-CNN,对potential proposal估计和分类两个模块都进行了性能提升,因此提升了目标检测的性能。
最简单的CNN性能提升办法是增大网络的depth和width,这里的width指的是每一层的神经元数量,这种方式要两个缺点:首先是毕竟大规模训练集获取的代价很大,增加网络参数数量会增加过拟合的风险;其次,增加参数数量增加了计算量。
将全连接层和卷积层换成更稀疏的连接方式可以降低参数数量。
作者也是根据理论假设了Inception结构,对输入数据进行1 * 1,3 * 3,5 * 5的卷积,将各自的卷积结构连接构成下一层的输入。同时由于polling操作的必要性,进行了并行的polling操作,结果也合并到3个卷积的输出中构成整体的输出。这就是naive版本的Inception结构。
上述实现方式的问题就是计算量大,即使当前Inception结构的输入数据的channel数大小适中,进行一个大规模卷积核的5 * 5的卷积操作的计算量依然很大,并且池化操作的输出channel和输入相同,这样进行合并操作之后,输出的channel数肯定会增加,这样逐层增加会显著增加计算量,降低模型的使用效率。
根据上述存在的问题,需要对inception结构进行降维操作,办法就是在3 *3 和5 * 5的卷积之前使用1 * 1的卷积操作,这样做一方面减少了参数,同时使用了更多的激活函数,增加了非线性表达能力。
参考自:https://www.zhihu.com/question/56024942/answer/154846007 进行降维和升维引起人们重视的(可能)是在GoogLeNet里。对于每一个Inception模块(如下图),原始模块是左图,右图中是加入了1×1卷积进行降维的。虽然左图的卷积核都比较小,但是当输入和输出的通道数很大时,乘起来也会使得卷积核参数变的很大,而右图加入1×1卷积后可以降低输入的通道数,卷积核参数、运算复杂度也就跟着降下来了。以GoogLeNet的3a模块为例,输入的feature map是28×28×192,3a模块中1×1卷积通道为64,3×3卷积通道为128,5×5卷积通道为32,如果是左图结构,那么卷积核参数为1×1×192×64+3×3×192×128+5×5×192×32,而右图对3×3和5×5卷积层前分别加入了通道数为96和16的1×1卷积层,这样卷积核参数就变成了1×1×192×64+(1×1×192×96+3×3×96×128)+(1×1×192×16+5×5×16×32),参数大约减少到原来的三分之一。同时在并行pooling层后面加入1×1卷积层后也可以降低输出的feature map数量,左图pooling后feature map是不变的,再加卷积层得到的feature map,会使输出的feature map扩大到416,如果每个模块都这样,网络的输出会越来越大。而右图在pooling后面加了通道为32的1×1卷积,使得输出的feature map数降到了256。GoogLeNet利用1×1的卷积降维后,得到了更为紧凑的网络结构,虽然总共有22层,但是参数数量却只是8层的AlexNet的十二分之一(当然也有很大一部分原因是去掉了全连接层)。 ![这里写图片描述](https://img-blog.csdn.net/20180203165317554?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2RrbmlnaHRfaGFwcHk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)建议低层网络依然是传统卷积操作,网络高层才使用Inception结构。这么设计结构能起到比较好的作用的直观理解是,对图像进行多尺度的处理然后聚合到一起作为下一层的输入,使得网络学习到多尺度的图像信息。
22层网络;
使用平均池化层(GAP)代替全连接层,top-1准确率有0.6%的提升,虽然移除了全连接层,但还是在GAP后使用了dropout;
网络的中间部位还输出了一个辅助的softmax,可以增强低层网络的判别能力,增强反向传播的梯度的大小,提供额外的正则化能力;
训练过程中,损失值是最后层的softmax loss加0.3*中间输出的softmax loss,推理时,忽略中间的这个softmax输出。
相同的初始化参数和学习率策略,指示根据对训练集图像采样方式和输入顺序的不同训练了7个不同的网络,对7个网络的识别结果进行了ensemble;
测试集的裁剪策略是先把图像短边缩放到256,288,320,352大小,分别从左,中,右裁剪正方形区域,然后选取四个角、中心位置的224224区域,同时把正方形区域缩放到224224大小,进行镜像操作,一共是获取了43(5+1)*2=144个crops;
单幅图像所有crops的softmax scores取均值作为单幅图像的识别结果。
最好结果top-5 error:6.67%;
多个模型ensemble,测试集图像多个crops都有助于提升准确率;
在检测任务上也取得了非常好的效果。
设计了Inception结构,降低参数,增强非线性能力,很厉害;
精心设计的22层网络以top-5error rate 6.7%取得了ILSVRC-2014分类冠军;
提供了下一步的研究方向,尝试更加稀疏和精细化设计的网络。
作者定义internel covariate shift为每一层的输入数据的分布情况都不一致,这样就需要使用比较小的学习率,网络的收敛速度慢,同时需要比较仔细的进行参数的初始化工作,否则就会造成非线性函数的梯度弥散现象。
作者提出了batch normalization操作,使每一层的输出都归一化到 N ( 0 , 1 ) N(0,1) N(0,1)分布。好处是可以使用比较大的学习率,可以很容易的进行参数初始化,并且还具有类似于dropout的防止过拟合的效果。
使用BN层,实验表明,网络收敛快了14倍,在ImageNet数据集上top-5 error rate降到了4.9%,超过了人类的识别准确率。
使用批随机梯度下降法进行最优化迭代,之所以使用batch,好处是在a mini-batch上计算的梯度可以看作是对整个训练集的梯度的近似;并且,由于近来深度学习框架的并行处理能力,单次在mini-batch上进行梯度计算的效率优于m次单样本的梯度迭代。
虽然梯度下降简单高效,但是需要非常仔细的进行模型超参数的设置,尤其是学习率和模型的初始参数。对每一层输入参数的改变都会对整个网络产生影响,因此更加需要仔细的进行参数设置。
将大的深度学习网络看成是一个个子网络的堆砌,确保每一个子网络的输入数据同分布具有很多的好处。假如使用sigmoid作为激活函数, z = g ( W x + b ) z=g(Wx+b) z=g(Wx+b), g ′ ( x ) = g ( x ) ( 1 − g ( x ) ) g^{'}(x)=g(x)(1-g(x)) g′(x)=g(x)(1−g(x)),|x|增大,则 g ′ ( x ) g^{'}(x) g′(x)更加接近于0,所以梯度值也会更加接近于0,这样就会造成梯度弥散象,使得网络训练过程收敛的很慢。网络层数越多,这种梯度弥散的线性越会严重。提供使用Relu激活函数、仔细的参数初始化和小的学习率可以减小梯度弥散现象的发生几率。
作者将训练过程中深度网络内部子网络的输入数据的分布变化叫做internal covariate shift,通过作者提出的batch normalization方法可以减弱这些变化,使得每一层的输入数据具有相同的均值和方差,增加模型训练的收敛速度。使用BN层,可以使用更大的学习率加速训练过程;可以取得类似于dropout的防止过拟合的作用;可以使用易于饱和的非线性函数(sigmoid)。
******下面部分转载自http://blog.csdn.net/happynear/article/details/44238541
神经网络中的权重初始化与预处理方法的关系
如果做过dnn的实验,大家可能会发现在对数据进行预处理,例如白化或者zscore,甚至是简单的减均值操作都是可以加速收敛的,例如下图所示的一个简单的例子:
图中红点代表2维的数据点,由于图像数据的每一维一般都是0-255之间的数字,因此数据点只会落在第一象限,而且图像数据具有很强的相关性,比如第一个灰度值为30,比较黑,那它旁边的一个像素值一般不会超过100,否则给人的感觉就像噪声一样。由于强相关性,数据点仅会落在第一象限的很小的区域中,形成类似上图所示的狭长分布。
而神经网络模型在初始化的时候,权重W是随机采样生成的,一个常见的神经元表示为:ReLU(Wx+b) = max(Wx+b,0),即在Wx+b=0的两侧,对数据采用不同的操作方法。具体到ReLU就是一侧收缩,一侧保持不变。
随机的Wx+b=0表现为上图中的随机虚线,注意到,两条绿色虚线实际上并没有什么意义,在使用梯度下降时,可能需要很多次迭代才会使这些虚线对数据点进行有效的分割,就像紫色虚线那样,这势必会带来求解速率变慢的问题。更何况,我们这只是个二维的演示,数据占据四个象限中的一个,如果是几百、几千、上万维呢?而且数据在第一象限中也只是占了很小的一部分区域而已,可想而知不对数据进行预处理带来了多少运算资源的浪费,而且大量的数据外分割面在迭代时很可能会在刚进入数据中时就遇到了一个局部最优,导致overfit的问题。
这时,如果我们将数据减去其均值,数据点就不再只分布在第一象限,这时一个随机分界面落入数据分布的概率增加了多少呢?2^n倍!如果我们使用去除相关性的算法,例如PCA和ZCA白化,数据不再是一个狭长的分布,随机分界面有效的概率就又大大增加了。
不过计算协方差矩阵的特征值太耗时也太耗空间,我们一般最多只用到z-score处理,即每一维度减去自身均值,再除以自身标准差,这样能使数据点在每维上具有相似的宽度,可以起到一定的增大数据分布范围,进而使更多随机分界面有意义的作用。
****下面描述转载自http://blog.csdn.net/qq_26898461/article/details/51221166
开始讲解算法前,先来思考一个问题:我们知道在神经网络训练开始前,都要对输入数据做一个归一化处理,那么具体为什么需要归一化呢?归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。
对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。
我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization,这个牛逼算法的诞生。
由于白化的计算量大且不是处处可微的,作者提出了近似的数据处理方法,即对训练数据减均值,除方差进行归一化操作。
简单的对每一层输入数据的归一化操作会改变数据的分布情况,例如使用sigmoid作为激活函数时,简单的对输入数据的归一化会使得数据分布在sigmoid的近线性区域,所以作者添加了一对可训练的参数,对归一化之后的数据进行变换。
实现过程中,是对每一个mini-batch自身进行减均值和除方差的归一化操作。
反向传播求梯度的计算公式:
BN层的训练过程中使用各自mini-batch的数据计算均值和方差进行数据的归一化处理,inference过程中则使用所有训练数据的均值和方差的期望,其中方差使用的是无偏估计。
BN层是应用在Wx+b之后,即在一层网络中,先计算权重和输入数据的内积,加偏置项,进行BN操作,最后进行逐元素的非线性变化得到该层的输出。原始的BN操作应该是 z = g ( B N ( W u + b ) ) z = g(BN(Wu+b)) z=g(BN(Wu+b)),但是对数据进行减均值操作之后,偏移项b也就没什么作用了,并且BN操作还有一个偏移项,所以就忽略了b变成了 z = g ( B N ( W u ) ) z = g(BN(Wu)) z=g(BN(Wu))。
在卷积层中,需要BN层也具有权值共享的特性,所以就不再是对每一个与卷积核局部连接的输入数据块计算一组 γ 和 β \gamma和\beta γ和β,而是将一个输入的feature map看作是一个整体计算一组 γ 和 β \gamma和\beta γ和β。假设训练过程中的mini-batch大小为m,输出的feature map大小为p*q,那么现在的mini-batch大小为 m ′ = m ∗ p ∗ q m^{'}=m*p*q m′=m∗p∗q进行求均值和方差的计算。这样的话,学习到的参数对 ( γ , β ) (\gamma,\beta) (γ,β)数量就是总的卷积核的个数。
传统的神经网络训练过程中,如果使用较大的学习率,会有很大的概率发生梯度爆炸的现象。
BN层使得训练过程可以适应更大范围的w值,避免梯度弥散或者梯度爆炸现象的发生。神经网络中,由于梯度反向传播到当前层时会乘以后面所有层权重的乘积,当网络层数很多时,如果后面层的权重参数大多使用幅值大于1的参数会造成梯度的爆炸现象,如果大多使用幅值小于1的参数会造成梯度弥散现象。但是进行BN操作的时候, B N ( W u ) = B N ( ( a W ) u ) BN(Wu)=BN((aW)u) BN(Wu)=BN((aW)u)。
上式中,a处于分母位置,若a大于1,对于大幅值的w,会减小对w的梯度值;若a小于1,会增大对w的梯度值。因此w的幅值大小不会影响梯度的反向传播,不会造成梯度的爆炸或者弥散,会使得整体w的更新过程比较稳定,因此也就可以使用更大的学习率加速训练过程。
参考:https://www.zhihu.com/question/38102762
个人总结,敬请批评指正:
使用sigmoid做激活函数时,容易发生梯度弥散现象,现在常用的relu系激活函数已解决了激活函数导致的梯度弥散现象;
而对于梯度爆炸和由较小的多层w累乘造成的梯度弥散现象,通过BN层的应用,可以得到解决。
由于对训练数据进行了以batch为单位的归一化操作,那么模型就更多的是关注batch的共性,而不是单个样本的个性特征。实验表明,BN有一定的正则化作用,使用BN层时可以减小dropout和正则化项的强度。
https://github.com/tensorflow/models/tree/master/inception/inception
作者发现辅助分类器在网络训练的早期不起作用,在网络训练的末期可以帮助获取更高的准确率。
作者发现辅助分类器能起到正则化的作用,因为当辅助分类器使用了BN层或者dropout等操作时,最后的分类效果往往更好。
输入数据的尺寸为dd,depth为k,若想得到尺寸为d/2 * d/2,depth为2k的输出,首先需要对输入数据使用2k个滤波器进行11的卷积,然后再进行池化操作,卷积过程中需要使用2k个卷积核,每个卷积核的尺寸是11k,卷积过程中总的计算量是 2 d 2 k 2 2d^2k^2 2d2k2。如果交换下池化和卷积的顺序,那么计算量变成了 2 ( d 2 ) 2 k 2 2(\frac{d}{2})^2k^2 2(2d)2k2,虽然计算量是前面方式的四分之一,但是这样做带来了表示瓶颈,空间尺寸减小的太快了。
作者提出了一种新的处理方式,级联卷积和池化的结果。
把7x7卷积替换为3个3x3卷积。包含3个Inception部分。第一部分是35x35x288,使用了2个3x3卷积代替了传统的5x5;第二部分减小了feature map,增多了filters,为17x17x768,使用了nx1->1xn结构;第三部分增多了filter,使用了卷积池化并行结构。网络有42层,但是计算量只有GoogLeNet的2.5倍。
更改数据true-label的分布,增强模型的泛化能力,避免过拟合。
解决办法:减小前两层网络的stride,并且移除第一个卷积层之后的池化操作,可以在低分辨率数据集上取得和高分辨率数据集上相似的准确率。
ResNet网络在ILSVRC2015上取得了非常好的成绩,最终的分类准确率和Inception-V3很接近,作者就在考虑将resnet中的“shortcut connection”和inception结构结合起来,作者的实验结果表明使用residual connection可以大大加速inception网络的训练过程,并且可以进一步提升网络的分类准确率,最终作者使用emsemble的模型在ImageNet数据集上取得了3.08%的top-5 error。
本文是对resnet思想和inception结构的结合,用residual connection来代替inception结构中的filter concatenation,得到了Inception-ResNet网络。
作者还研究了新的更加deeper和wider的inception结构,设计了Inception-V4。
作者在实验中证明了不使用residual connections训练一个非常深的网络也没有那么难,但使用了残差连接可以加快训练速度。
谷歌的深度学习平台从DistBelief换成tensorflow之后,不需要对网络进行分割就可以直接进行训练过程。
加"V"的卷积表示可变卷积,padding的大小是要输入数据的每个元素都被处理,即如果是3*3的卷积,那么padding的大小就是1;
不加“V”的卷积表示卷积前后输入输出的空间尺寸保持一致。
Reduction-A如Figure 7所示
使用的是figure3,16,7,17,18,19
对残差进行缩放有助于提升训练过程的稳定性。缩放系数一般选择0.1到0.3之间。这个做法同原始ResNet论文中的two-phase training的效果类似。
使用RMSProp优化函数;
inception-v3的计算量和inception-resnet-v1相当;
inception-v4的计算量和inception-resnet-v2相当.
从V1提出inception结构,到v2添加了BN层,到V3使用分形卷积,到V4和残差网络结合使用,取得的分类效果也越来越好。