深度学习网络 | GoogleNet v1-v3解析(1)

时间:2024-03-29 16:13:21

一.CNN发展纵览

   我们先来看一张图片:

深度学习网络 | GoogleNet v1-v3解析(1)

  

1985年,Rumelhart和Hinton等人提出了后向传播(Back Propagation,BP)算法(也有说1986年的,指的是他们另一篇paper:Learning representations by back-propagating errors),使得神经网络的训练变得简单可行,这篇文章在Google Scholar上的引用次数达到了19000多次,目前还是比Cortes和Vapnic的Support-Vector Networks稍落后一点,不过以Deep Learning最近的发展劲头来看,超越指日可待。

几年后,LeCun利用BP算法来训练多层神经网络用于识别手写邮政编码,这个工作就是CNN的开山之作,多处用到了5*5的卷积核,但在这篇文章中LeCun只是说把5*5的相邻区域作为感受野,并未提及卷积或卷积神经网络。

1998年的LeNet5标注着CNN的真正面世,但是这个模型在后来的一段时间并未能火起来,主要原因是要求机器性能较好,而且其他的算法像SVM也能达到类似的效果甚至超过。

AlexNet是在2012年被发表的一个经典之作,并在当年取得了ImageNet最好的成绩,也是在那年之后,更多的更深的神经网络被提出,其官方提供的数据模型,他的top-1误差率为37.5%,以及top-5的误差率为17%,这是相当好的一个成绩。

2014年,VGG-Net 在ILSVRC localization and classification 两个问题上分别取得了第一名和第二名,VGG-Net不同于AlexNet的地方是:VGG-Net使用更多的层,通常有16-19层,而AlexNet只有8层。另外一个不同的地方是:VGG-Net的所有 convolutional layer 使用同样大小的 convolutional filter,大小为 3 x 3。

同年,GoogLeNet, 在2014年ILSVRC挑战赛获得冠军,将Top5 的错误率降低到6.67%. 一个22层的深度网络,论文在http://arxiv.org/pdf/1409.4842v1.pdf,题目为:Going deeper with convolutions。GoogLeNet这个名字也是挺有意思的,为了像开山鼻祖的LeNet网络致敬,他们选择了这样的名字。

下图为GooLeNet的网络结构图:

深度学习网络 | GoogleNet v1-v3解析(1)

令人感兴趣的是,在GoogLeNet出来之前,主流的网络结构突破大致是网络更深(即层数增加),网络更宽(即神经元数目增多),但这样做存在一些缺点:

  1. 当训练集有限时,参数过多,模型会出现过拟合;
  2. 网络越大,计算复杂度越大,设计起来越困难;
  3. 当层数增多时,梯度越往后越容易消失;

针对上述缺点,我们考虑到一味的追求准确率而增加网络规模有一部分原因就是特征提取模块的设计没有能很好提取出图像的特征,如果能在基本的特征提取单元上做一些优化,然后用优化后的特征提取模块去构建网络,可能会有利于最后的识别效果。由此,Inception 模型孕育而生。

二.Inception v1模型

一般的卷积层只是一味增加卷积层的深度,但是在单层上卷积核却只有一种,比如对于VGG,单层卷积核只有3x3大小的,这样特征提取的功能可能就比较弱。GoogLenet想的就是能不能增加单层卷积层的宽度,即在单层卷积层上使用不同尺度的卷积核,GoogLenet构建了Inception module这个基本单元,基本的Inception module中有1x1卷积核,3x3卷积核,5x5卷积核还有一个3x3下采样,从而产生了Inception v1模型,如下图所示,

深度学习网络 | GoogleNet v1-v3解析(1)
深度学习网络 | GoogleNet v1-v3解析(1)

这样尺寸不同的卷积核就可以提取不同尺寸的特征,单层的特征提取能力增强了,但是我在读的过程中想到的问题是,对于像VGG这种网络,我同样可以通过卷积-下采样-卷积这种方式提取不同尺寸的信息,所以为何Inception module这种网络会有很好的效果的,我想到的原因是卷积-下采样-卷积虽然能够提取不同尺寸的信息,但是由于是通过下采样这种方式实现的,所以必会带来信息的丢失,和Inception module这种方式相比,显然丢失的信息更多。

上面Inception module结构会存在一个问题,就是前一层的输出不经任何处理直接输入到下一层的卷积层中,这样如果前一层的特征图数量很多,有经过5x5这种大尺寸的卷积,带来的计算量也是非常大。从而产生了Inception v2模型。

三.Inception v2模型

Inception v2的网络在v1的基础上,进行了改进,一方面了加入了BN层,减少了Internal Covariate Shift(内部neuron的数据分布发生变化),使每一层的输出都规范化到一个N(0, 1)的高斯,另外一方面学习VGG用2个3x3的conv替代inception模块中的5x5,既降低了参数数量,也加速计算;

一个5*5的网络等于两个3*3的降级:

深度学习网络 | GoogleNet v1-v3解析(1)

所以在修正过后的Inception module在输出到下一层卷积之前,会对数据进行一次降维,怎么降维,就是采用1x1卷积核实现,比如原来有256个输入特征图,先用1x1的卷积核对特征图进行线性组合,使得输出只有96的特征图,这样不会带来信息损失,又减小了下一层卷积的计算量,修正后的Inception module如下图所示:

深度学习网络 | GoogleNet v1-v3解析(1)

这种Inception module既能大大提升卷积提取特征的能力,又不会使计算量提升很多。它的网络结构如下:

深度学习网络 | GoogleNet v1-v3解析(1)

四.Inception v3模型
Inception v3的网络设计准则:

1.避免表示瓶颈,即特征图大小应缓慢下降,特别是在网络靠前的地方;信息流前向传播过程中显然不能经过高度压缩的层,即表达瓶颈。从input到output,feature map的宽和高基本都会逐渐变小,但是不能一下子就变得很小。比如你上来就来个kernel = 7, stride = 5 ,这样显然不合适。 另外输出的维度channel,一般来说会逐渐增多(每层的num_output),否则网络会很难训练。(特征维度并不代表信息的多少,只是作为一种估计的手段) 

2.高维表示可以用网络代替;高维特征更易处理。 高维特征更易区分,会加快训练。

3. 可以在低维嵌入上进行空间汇聚而无需担心丢失很多信息。 比如在进行3x3卷积之前,可以对输入先进行降维而不会产生严重的后果。假设信息可以被简单压缩,那么训练就会加快。

4.平衡网络的宽度和深度。

使用大尺寸滤波器卷机分解:

GoogleNet的精度增益主要来自维度降低,这可以认为是卷积分解的特例。考虑到网络临近的**高度相关,因此集成之前可以降维。Inception模块是全卷积的,每个权值对应一个乘法运算,进行卷积分解后可以减少参数数目进行快速训练,这样就可以增加滤波器组的大小提升精度。

将大卷积分解成小卷积:

5×5的卷积可以使用两层3×3卷积代替,如图4为原始Inception模块,图5为替换后的模块,节约的计算时间可以用来增加滤波器数目。对于一个5x5卷积核卷积的区域,可以先使用一个3x3对5x5的区域进行卷积,然后再使用一个3x3核对刚刚的卷积结果再进行一次卷积,最终也是得出一个数据,在效果上和5x5卷积是等效的。这样就减少了一次卷积计算的次数,原来5x5卷积需要做25次乘加,现在两次3x3只需要做9+9=18次乘加,如果卷积核更大,减小的计算量也更大。

是基于什么考虑才做这种分解呢?我们可以看到分解导致卷积核的参数变小,这就说明原来5x5卷积核其实是有部分参数冗余的,即我们其实并不需要25个参数提取特征,而可能需要18个参数就可以了,这时因为由于提取区域像素都是紧邻的,像素之间的关联性很强,这都到时5x5卷积核各个参数之间其实也是有很强关联的,即参数存在冗余可以进一步压缩;进一步想,其实这是一种紧密网络到稀疏网络的转换。上面所说的是大的卷积核分解成小的卷积核,Inception v3中还提出了另一种分解方式从图中可以看出,3x3的卷积,可以先用一个1x3的卷积,紧接着跟着一个3x1的卷积也是可以实现相同的输出的,同样对于5x5和7x7也是可以处理的,这样也可以明显降低卷积核参数和计算量。

深度学习网络 | GoogleNet v1-v3解析(1)



深度学习网络 | GoogleNet v1-v3解析(1)

需要注意的是:3×3的卷积使用3×1卷积和1×3卷积代替,这种结构在前几层效果不太好,但对特征图大小为12~20的中间层效果明显。

附加分类器

附加分类器有batch norm层效果更好,得出其扮演规格化的角色。GoogLenet中就做过相似的工作,常规网络都是在最后一层计算loss,然后进行梯度方向传播,但是如果网络层很多,这就导致梯度消失的现象,使用Auxiliary Classifiers,在网络中间层加上分类器,计算辅助失真和梯度,然后把这个梯度加到常规网络的梯度上,有效解决了梯度消失的现象,其实这样做的方式,呼应了ResNet中解决梯度消失的问题得方法,虽然ResNet表面上看起来loss是在最后一层计算的,但是其实本质上最后一层的loss其实在R esNet的子网络中都有计算,也就相当于GoogLenet中把loss层加上网络中间层的方式。

  在GoogLeNet中,使用了多余的在底层的分类器,直觉上可以认为这样做可以使底层能够在梯度下降中学的比较充分,但在实践中发现两条:

  1. 多余的分类器在训练开始的时候并不能起到作用,在训练快结束的时候,使用它可以有所提升
  2. 最底层的那个多余的分类器去掉以后也不会有损失。

以为多余的分类器起到的是梯度传播下去的重要作用,但通过实验认为实际上起到的是regularizer的作用,因为在多余的分类器前添加dropout或者batch normalization后效果更佳。

降低特征图大小

池化用来降低特征图大小,为避免表示瓶颈,即更有效的保存图像信息,应在池化之前增加滤波器数目,以前的网络都是在卷积层后面加上一个pooling层来降低特征图的尺寸,但是这种降低尺寸的方式不可避免地有信息的损失,在《Rethinking Inception》论文中提出了另一种降低特征图尺寸的方式如下图所示:

深度学习网络 | GoogleNet v1-v3解析(1)

右图是正常的缩小,但计算量很大。左图先pooling会导致特征表征遇到瓶颈,违反上面所说的第一个规则,为了同时达到不违反规则且降低计算量的作用,将网络改为下图

深度学习网络 | GoogleNet v1-v3解析(1)


这种方法是同时进行步长为2的卷积和池化,然后串联,从图中可以看出降低尺寸是用过卷积加上合适的stride实现的,当然也有一个支路是通过pooling的方式实现,这种方式可以有效避免信息的损失。
实验结果

实验结果与GoogleNet相比有较大提升,如下表所示:

深度学习网络 | GoogleNet v1-v3解析(1)

五.Inception v4模型
先给出Inception v4的模型图:
深度学习网络 | GoogleNet v1-v3解析(1)


Inception-v3到inception-v4网络变得更深了,在GAP前Inception-v3包括了4个卷积模块运算(1个常规卷积块+3个inception结构),Inception-v4变成了6个卷积模块。对比两者的卷积核的个数,Inception-v4比Inception-v3也增多了许多。对比[原论文](https://arxiv.org/abs/1602.07261)中提出的Inception-ResNet-v1和Inception-ResNet-v2,Inception-v4没有residual连接,但取得了Inception-ResNet-v2相近的结果。


参考
文献