深度学习&图像处理(8 GoogLeNet思想、Inception v1-v4)

1.GoogLeNet思想

一般来说,提升网络性能最直接的办法就是增加网络深度和宽度,深度指网络层次数量、宽度指神经元数量。但这种方式存在以下问题:

(1)参数太多,如果训练数据集有限,很容易产生过拟合;

(2)网络越大、参数越多,计算复杂度越大,难以应用;

(3)网络越深,容易出现梯度弥散问题(梯度越往后穿越容易消失),难以优化模型。 

解决这些问题的方法当然就是在增加网络深度和宽度的同时减少参数,为了减少参数,自然就想到将全连接变成稀疏连接。但是在实现上,全连接变成稀疏连接后实际计算量并不会有质的提升,因为大部分硬件是针对密集矩阵计算优化的,稀疏矩阵虽然数据量少,但是计算所消耗的时间却很难减少。

那么,有没有一种方法既能保持网络结构的稀疏性,又能利用密集矩阵的高计算性能。通常全连接是为了更好的优化并行计算,而稀疏连接是为了打破对称来改善学习,传统常常利用卷积来利用空间域上的稀疏性,但卷积在网络的早期层中的与patches的连接也是稠密连接,因此考虑到能不能在滤波器层面上利用稀疏性,而不是神经元上。但是在非均匀稀疏数据结构上进行数值计算效率很低,并且查找和缓存未定义的开销很大,而且对计算的基础设施要求过高,因此考虑到将稀疏矩阵聚类成相对稠密子空间来倾向于对稀疏矩阵的计算优化,因此,GoogLeNet团队提出了Inception网络结构,就是构造一种“基础神经元”结构,来搭建一个稀疏性、高计算性能的网络结构。

 Inception架构的两个主要优点:

一是允许显著增加每一步的单元数目,计算复杂性不会不受控制。降维的普遍使用能保护最后一步到下一层的大量输入滤波器,在对它们用大的patch size卷积前首先降维。

二是视觉信息在不同的尺度上进行处理然后聚合,这样下一步可以同时从不同尺度提取特征。 

采用了Inception模块的网络要比没有采用Inception模块的同样架构的网络快2~3倍。

Inception v1-v4变化:

  •  Inception v1的网络,将1x1,3x3,5x5的conv和3x3的pooling,stack在一起,一方面增加了网络的width,另一方面增加了网络对尺度的适应性;
  • v2的网络在v1的基础上,进行了改进,一方面了加入了BN层,减少了Internal Covariate Shift(内部神经元的数据分布发生变化),使每一层的输出都规范化到一个N(0, 1)的高斯,另外一方面学习VGG用2个3x3的conv替代inception模块中的5x5,既降低了参数数量,也加速计算;
  • v3一个最重要的改进是分解(Factorization),将7x7分解成两个一维的卷积(1x7,7x1),3x3也是一样(1x3,3x1),这样的好处,既可以加速计算(多余的计算能力可以用来加深网络),又可以将1个conv拆成2个conv,使得网络深度进一步增加,增加了网络的非线性,还有值得注意的地方是网络输入从224x224变为了299x299,更加精细设计了35x35/17x17/8x8的模块;
  • v4研究了Inception模块结合Residual Connection。发现ResNet的结构可以极大地加速训练,同时性能也有提升,得到一个Inception-ResNet v2网络,同时还设计了一个更深更优化的Inception v4模型,能达到与Inception-ResNet v2相媲美的性能。

2.Inception V1

有22层,比AlexNet的8层和VGGNet的19层还要深.参数量(500万)仅有AlexNet参数量(6000万)的1/12,但准确率远胜于AlexNet的准确率.

Inception V1降低参数量的目的: 参数越多模型越庞大,需要模型学习的数据量就越大,高质量的数据非常昂贵。 参数越多,消耗的计算资源越多。

Inception V1网络的特点: 模型层数更深(22层),表达能力更强。去除最后的全连接层,用全局平均池化层(即将图片尺寸变为1x1)来代替它;使用Inception Module提高了参数利用效率。

最原始Inception的基本结构

(该结构将CNN中常用的卷积(1x1,3x3,5x5)、池化操作(3x3)堆叠在一起(卷积、池化后的尺寸相同,将通道相加),一方面增加了网络的宽度,另一方面也增加了网络对尺度的适应性。)

网络卷积层中的网络能够提取输入的每一个细节信息,同时5x5的滤波器也能够覆盖大部分接受层的的输入。还进行一个池化操作,以减少空间大小,降低过度拟合。在这些层之上,在每一个卷积层后都要做一个ReLU操作,以增加网络的非线性特征。

然而这个Inception原始版本,所有的卷积核都在上一层的所有输出上来做,而那个5x5的卷积核所需的计算量就太大了,造成了特征图的厚度很大,为了避免这种情况,在3x3前、5x5前、max pooling后分别加上了1x1的卷积核,以起到了降低特征图厚度的作用,这也就形成了Inception v1的网络结构。

1x1的卷积核有什么用呢???

1x1卷积的主要目的是为了减少维度,还用于修正线性激活(ReLU)。比如,上一层的输出为100x100x128,经过具有256个通道的5x5卷积层之后(stride=1,pad=2),输出数据为100x100x256,其中,卷积层的参数为128x5x5x256= 819200。而假如上一层输出先经过具有32个通道的1x1卷积层,再经过具有256个输出的5x5卷积层,那么输出数据仍为为100x100x256,但卷积参数量已经减少为128x1x1x32 + 32x5x5x256= 204800,大约减少了4倍。

GoogLeNet的网络框图理解:

0、输入input

原始输入图像为224x224x3,且都进行了零均值化的预处理操作(图像每个像素减去均值)。

1、第一层(卷积层)

使用7x7的卷积核(滑动步长2,padding为3),64通道,输出为112x112x64,卷积后进行ReLU操作;经过3x3的max pooling(步长为2),输出为((112 - 3+1)/2)+1=56,即56x56x64,再进行ReLU操作

卷积操作存在两个问题:1、图像越来越小;2、图像边界信息丢失,即有些图像角落和边界的信息发挥作用较少。因此需要padding(填充像素)

LRN(Local Response Normalization)就是局部响应归一化:这个技术主要是深度学习训练时的一种提高准确度的技术方法。其中caffe、tensorflow等里面是很常见的方法,其跟激活函数是有区别的,LRN一般是在激活、池化后进行的一中处理方法。局部归一的动机:在神经生物学有一个概念叫做侧抑制,指的是被激活的神经元抑制相邻神经元。归一化的目的是“抑制”,局部响应归一化就是借鉴侧抑制的思想来实现局部抑制,尤其当我们使用ReLu的时候,这种“侧抑制”很管用。好处:有利于增加泛化能力,做了平滑处理,识别率提高1~2%。

2、第二层(卷积层)

使用3x3的卷积核(滑动步长为1,padding为1),192通道,输出为56x56x192,卷积后进行ReLU操作;经过3x3的max pooling(步长为2),输出为((56 - 3+1)/2)+1=28,即28x28x192,再进行ReLU操作

3a、第三层(Inception 3a层)

分为四个分支,采用不同尺度的卷积核来进行处理

(1)64个1x1的卷积核,然后RuLU,输出28x28x64(2)96个1x1的卷积核,作为3x3卷积核之前的降维,变成28x28x96,然后进行ReLU计算,再进行128个3x3的卷积(padding为1),输出28x28x128(3)16个1x1的卷积核,作为5x5卷积核之前的降维,变成28x28x16,进行ReLU计算后,再进行32个5x5的卷积(padding为2),输出28x28x32(4)pool层,使用3x3的核(padding为1),输出28x28x192,然后进行32个1x1的卷积,输出28x28x32。将四个结果进行连接,对这四部分输出结果的第三维并联,即64+128+32+32=256,最终输出28x28x256

3b、第三层(Inception 3b层)

(1)128个1x1的卷积核,然后RuLU,输出28x28x128(2)128个1x1的卷积核,作为3x3卷积核之前的降维,变成28x28x128,进行ReLU,再进行192个3x3的卷积(padding为1),输出28x28x192(3)32个1x1的卷积核,作为5x5卷积核之前的降维,变成28x28x32,进行ReLU计算后,再进行96个5x5的卷积(padding为2),输出28x28x96(4)pool层,使用3x3的核(padding为1),输出28x28x256,然后进行64个1x1的卷积,输出28x28x64。将四个结果进行连接,对这四部分输出结果的第三维并联,即128+192+96+64=480,最终输出输出为28x28x480

第四层(4a,4b,4c,4d,4e)、第五层...,与3a、3b类似,在此就不再重复。

用到了辅助分类器(充当正则化器),Inception Net有22层深,除了最后一层的输出,其中间节点的分类效果也很好。因此在Inception Net中,还使用到了辅助分类节点,即将中间某一层的输出用作分类,并按一个较小的权重(0.3)加到最终分类结果中。这样相当于做了模型融合,同时给网络增加了反向传播的梯度信号,也提供了额外的正则化,对于整个Inception Net的训练很有裨益。 pooling的结果是使得特征减少,参数减少,目的是为了保持某种不变性(旋转、平移、伸缩等)

辅助分类器的具体细节: 
1.均值pooling层滤波器大小为5x5,步长为3,(4a)的输出为4x4x512,(4d)的输出为4x4x528; 
2.1x1的卷积有用于降维的128个滤波器和修正线性激活; 
3.全连接层有1024个单元和修正线性激活; 
4.dropout层的dropped的输出比率为70%; 
5.线性层将softmax损失作为分类器(和主分类器一样预测1000个类,但在inference时移除)。

ILSVRC 2014的分类任务有1000个子类,120万训练图像,5万验证图像,10万测试图像,每个图像中有一个ground truth,性能测量是基于得分最高的分类器预测,常用指标为top-1准确率和top-5错误率。 
测试时的一些小技巧: 
1.训练了7个网络,初始化和权重都相同,只是采样方法和随机输入图像不同; 
2.将图像的短边分别缩放成256、288、320、352这4种尺度。取图像的左中右块,每块取四个角和中间的224x224的裁剪, 和将这个块缩放到224x224,以及它们的镜像。这样每个图像有4x3x6x2=144个,但可能实际中不需要这么多; 
3.softmax概率在多个裁剪和在所有分类器上取平均来获得最后的预测,简单的平均结果最好。 

3.Inception V2:

GoogLeNet设计的初衷就是要又准又快,而不只是单纯的堆叠网络,所以如何在不增加过多计算量的同时提高网络的表达能力就成为了一个问题。Inception V2版本的解决方案就是修改Inception的内部计算逻辑,提出了比较特殊的“卷积”计算结构,同时还提出了Batch Normalization(简称BN)方法。

1、卷积分解(Factorizing Convolutions)

大尺寸的卷积核可以带来更大的感受野,但也意味着会产生更多的参数,比如5x5卷积核的参数有25个,3x3卷积核的参数有9个,前者是后者的25/9=2.78倍。因此,GoogLeNet团队提出可以用2个连续的3x3卷积层组成的小网络来代替单个的5x5卷积层,即在保持感受野范围的同时又减少了参数量。 而且后面有大量实验可以表明不会造成表达能力的下降;作者也做了对比试验,表明3x3卷积之后添加非线性激活会提高性能。

由此看来,大卷积核完全可以由一系列的3x3卷积核来替代,那能不能分解的更小一点呢?文章考虑了 nx1 卷积核,用3个3x1取代3x3卷积,因此,任意nxn的卷积都可以通过1xn卷积后接nx1卷积来替代。GoogLeNet团队发现在网络的前期使用这种分解效果并不好,在中度大小的特征图(feature map)上使用效果才会更好(特征图大小建议在12到20之间)。

2、降低特征图大小

一般情况下,如果想让图像缩小,可以有如下两种方式:先池化再作Inception卷积,或者先作Inception卷积再作池化。但是方法一先作pooling(池化)会导致特征表示遇到瓶颈(特征缺失),方法二是正常的缩小,但计算量很大。为了同时保持特征表示且降低计算量,将网络结构改为下图,使用两个并行化的模块来降低计算量(卷积、池化并行执行,再进行合并)

3、BN(归一化)

在训练神经网络的过程中,因为前一层的参数变化而导致每层的输入分布都在不断变化。这使得我们需要更低的学习率和更小心地进行参数初始化,导致我们难以充分构建一个具有饱满地非线性结构的模型,而这个现象就被称作Internal Covariate Shift。为了解决这个问题,Google提出了Batch Normalization(批规范化)。

实际上,在tensorflow的源码里,inception V1也已经使用了Batch Normalization,只是给了一个参数用来选择是否使用,而从inceptionV2开始去掉了这个参数,都使用BN算法了。

Batch Normalization带来了哪些好处:

加快训练速度;对网络中信息的流动带来好处,使得网络参数的依赖相关性减弱;可以使用更大的学习率;BN相当于正则化,从而可以减弱Dropout的作用,或者去掉dropout操作;BN使得使用哪些带有饱和性质的激活函数构建网络,如sigmoid,tanh等

BN本质上也是其中一种目前被大量使用的解决方法。BN是一个深度神经网络的训练技巧,它不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中“梯度弥散”的问题,从而使得深层网络模型的训练更加容易和稳定。

BN的作用就是在深度神经网络训练过程中使得每一层神经网络的输入均保持相同分布。BN是一个非常有效的正则化方法,可以让大型卷积网络的训练速度加快很多倍,同时收敛后的分类准确率可以的到大幅度提高。

BN在用于神经网络某层时,会对每一个mini-batch数据的内部进行标准化处理,使输出规范化到(0,1)的正态分布,减少了Internal Covariate Shift(内部神经元分布的改变)。BN论文指出,传统的深度神经网络在训练时,每一层的输入的分布都在变化,导致训练变得困难,我们只能使用一个很小的学习速率解决这个问题。而对每一层使用BN之后,我们可以有效的解决这个问题,学习速率可以增大很多倍,达到之间的准确率需要的迭代次数有需要1/14,训练时间大大缩短,并且在达到之间准确率后,可以继续训练。以为BN某种意义上还起到了正则化的作用,所有可以减少或取消Dropout,简化网络结构。

当然,在使用BN时,需要一些调整:增大学习率并加快学习衰减速度以适应BN规范化后的数据;去除Dropout并减轻L2正则(BN已起到正则化的作用);去除LRN;更彻底地对训练样本进行shuffle;减少数据增强过程中对数据的光学畸变(BN训练更快,每个样本被训练的次数更少,因此真实的样本对训练更有帮助)

4.Inception V3

Inception v3整体上采用了Inception v2的网络结构,并在优化算法、正则化等方面做了改进,总结如下:

1.使用(LSR)方法

提出了Label-smoothing regularation(LSR),平滑标签,比hard的标签更合理一点。。LSR是一种通过在输出y中加噪声,实现对模型进行约束,降低模型过拟合的方法。

2. 将第一个nxn卷积层分解为nx1和1xn两个卷积层。

Inception V3引入了Factorization into small convolutions的思想(Factorization into small convolutions很有效,可以降低参数量、减轻过拟合,增加网络非线性的表达能力。),将一个较大的二维卷积拆成两个较小的一维卷积,比如将7*7卷积拆成1*7卷积和7*1卷积。一方面节约了大量参数,加速运算并减去过拟合,同时增加了一层非线性扩展模型表达能力。论文中指出,这样非对称的卷积结构拆分,结果比对称地拆分为几个相同的小卷积核效果更明显,可以处理更多、更丰富的空间特征、增加特征多样性。这样的好处,既可以加速计算,又可以将1个卷积拆成2个卷积,使得网络深度进一步增加,增加了网络的非线性(每增加一层都要进行ReLU)。

3. 辅助分类器(auxiliary classifier)的全连接层也进行了BN操作

侧枝的辅助分类器,并不会帮助更快收敛,但是能起到正则化的作用,中间加个监督信号,能稍微好一点,可以理解。然后两个辅助分类器扔掉底层那个没什么影响,可以去掉。而使用了BN的辅助分类器,能让主分支更加好一点。

4.常用的三种结构:

Inception Module(Inception Module用多个分支提取不同抽象程序的高阶特征的思路很有效,可以丰富网络的表达能力。)网络输入从224x224变为了299x299,更加精细设计了35*35、17*17和8*8三种不同的结构。

Inception V3的网络结构:

首先是5个卷积层和2个池化层交替的普通结构,然后是3个Inception模块组,每个模块组内包含多个结构类似的Inception Module。设计Inception Net的一个重要原则是,图片尺寸是不断缩小的,从299x299通过5个步长为2的卷积层或池化层后,缩小为8x8;同时,输出通道数持续增加,从一开始的3(RGB三色)到2048。从这里可以看出,每一层卷积、池化或Inception模块组的目的都是将空间结构简化,同时将空间信息转化为高阶抽象的特征信息,即将空间的维度转为通道的维度。这一过程同时也使每层输出tensor的总size持续下降,降低了计算量。(卷积网络从输入到输出,应该让图片尺寸逐渐减少,输出通道数逐渐增加,即让空间结构简化,将空间信息转化为高阶抽象的特征信息。)

一般情况下有4个分支,第1个分支一般是1x1卷积,第2个分支一般是1x1卷积再接分角后(factorized)的1xn和nx1卷积,第3个分支和第2分支类似,但是一般更深一些,第4个分支一般具有最大池化或平均池化。因此,Inception Module是通过组合比较简单的特征抽象(分支1)、比较复杂的特征抽象(分支2和分支3)和一个简化结构的池化层(分支4),一共4种不同程序的特征抽象和变换来有选择地保留不同层次的高阶特征,这样可以最大程序地丰富网络的表达能力。

Inceptio V3网络的最后一部分---全局平均池化,Softmax和Auxiliary Logits。先看函数Inception_v3的输入参数,num_classes即最后需要分类的数量,这里默认的1000是ILSVRC比赛数据集的种类数;is_training标志是否是训练过程,对Batch Normalization和Dropout有影响,只有在训练时Batch Normalization和Dropout才会被启用;dropout_keep_prob即训练时Dropout所需要保留节点的比例,默认为0.8;prediction_fn是最后用来进行分类的函数,这里默认是使用slim.softmax;spatial_squeeze参数标志是否对输出进行squeeze操作(即去除维数为1的维度,比如5x3x1转为5x3);reuse标志是否会对网络和Variable进行重复使用;最后,scope为包含了函数默认参数的环境。首先,使用tf.variable_scope定义网络的name和reuse等参数的默认值,然后使用slim.arg_scope定义Batch Normalization和Dropout的is_training标志的默认值。最后,使用前面定义好的inception_v3_base构筑整个网络的卷积部分,拿到最后一层的输出net和重要节点的字典表end_points。

Auxiliary Logits作为辅助分类的节点,对分类结果预测有很大帮助。先使用slim.arg_scope将卷积、最大池化、平均池化的默认步长设为1,默认padding模式设为SAME。然后通过end_points取到Mixed_6e,并在Mixed_6e之后再接一个5x5的平均池化,步长为3,padding设为VALID,这样输出的尺寸就从17x17x768变为5x5x768。接着连接一个128输出通道的1x1卷积和一个768输出通道的5x5卷积,这里权重初始化方式重设为标准差为0.01的正态分布,padding模式设为VALID,输出尺寸变为1x1x768。然后再连接一个输出通道数为num_classes的1x1卷积,不设激活函数和规范化函数,权重初始化方式重设为标准差为0.001的正态分布,这样输出变为了1x1x1000。接下来,使用tf.squeeze函数消除输出tensor中前两个为1的维度。最后将辅助分类节点的输出aux_logits储存到字典表end_points中。

5.Inception V4

Inception V4研究了Inception模块与残差连接的结合。ResNet结构大大地加深了网络深度,还极大地提升了训练速度,同时性能也有提升。Inception V4主要利用残差连接(Residual Connection)来改进V3结构,得到Inception-ResNet-v1,Inception-ResNet-v2,Inception-v4网络。

Inception V4 模型结构:只有Inception模块,如果模块中含有”V”,表示采用”VALID”的Padding,否则为”SAME”;深度达到了75层(卷积);共用模块Reduction-A: k=192,l=224,m=256,n=384k=192,l=224,m=256,n=384;Inception V4与V3相比,高层的结构相同,但底层的特征提取不同;Inception V4相比Inception-ResNet模型,更强调宽度,尤其是在高层上

Inception-ResNet-v1 :包含残差模块;相比原始的残差模块,论文采用的更加cheaper的Inception block;每一个Inception block后面都会跟着一个1x1卷积进行维度扩张;只在基础的卷积操作中,采用Batch-Normalization操作 。这样节省下来的空间,可以使得网络更深,也能使得模型在一个GPU机器上进行训练;深度可以达到92层(卷积);共用模块Reduction-A: k=192,l=192,m=256,n=384k=192,l=192,m=256,n=384;相比较Inception V3底层提取相同,但添加了残差连接的同时,在高层上,宽度稍微减弱

Inception-ResNet-v2:同Inception-ResNet-v1;深度达到了95层(卷积);共用模块Reduction-A: k=256,l=256,m=384,n=384k=256,l=256,m=384,n=384;与Inception -V4的底层提取相同,与Inception-ResNet-V1高层结构相同,但参数更多

发布了40 篇原创文章 · 获赞 3 · 访问量 7600

猜你喜欢

转载自blog.csdn.net/OpenSceneGraph/article/details/100676759