经典CNN网络结构

时间:2024-03-31 11:56:29

参考博客1
参考博客2
参考博客3
参考博客4
参考博客5
参考博客6
参考博客7
参考博客8
最近在准备找实习,对于面试中出现的常见问题(经典分类网络有哪些,它们的特点与发展过程)打算进行整理,也方便之后找实习的过程中复习。
算网络层数的时候不包括pooling,dropout,**函数。只包括conv,fc。

1. LeNet

(LeNet5诞生于1994年,是最早的卷积神经网络之一, 由Yann LeCun完成,推动了深度学习领域的发展)

经典CNN网络结构
下图为LeNet5的结构参数图:
经典CNN网络结构

2. AlexNet

(2012年深度学习之父Hinton和他的学生Alex Krizhevshy提出,在竞赛中以超过第二名10.9个百分点的绝对优势一举夺冠,从此深度学习和卷积神经网络名声鹊起)
在这之后的分类网络都采用小的卷积核。
8层。
经典CNN网络结构
图中明确显示了两个GPU 之间的职责划分:一个GPU 运行图中顶部的层次部分,另一个GPU 运行图中底部的层次部分。GPU 之间仅在某些层互相通信。

数据预处理:
图像尺寸:论文在训练模型的时候,将图像固定到256x256大小。首先给定一张图像,将图像的最小边缩放到256,然后在图像的中心位置裁剪出224x224大小的图像,训练时会经过预处理变为227×227×3。
颜色变换:减去整个数据集的均值。

其他处理细节:
ReLU Nonlinearity
以前的标准做法都是采用sigmoid或者tanh非线性函数对网络输出进行非线性处理。
Training on Multiple GPUs
由于单张GTX 580 GPU只有3GB的显存,从而大大限制了网络的最大尺寸。从而作者采用了两块GPU卡进行模型训练。并且在模型训练的时候,存在数据交叉共享的操作。作者也指出,GPU在数据共享过程中是直接访问对方的内存,没有通过主机CPU内存,使得多张显卡进行同时训练变得非常合适。
数据共享只发生在第3层的结构上,2张显卡的模型训练结果相对于单张显卡在性能上有一定提升,top1和top5的错误率提高了1.7%和1.2%,多张显卡在时间上也比单张显卡要少。
Local Response Normalization
尽管ReLUs操作能够使得数据出现饱和性,从而避免对数据进行normalization操作的依赖。但是作者发现local normalization操作能然能够提升一定的性能。
作者在每一个点的周围进行了一次局部归一化,但是通过变量α,βα,β来控制局部数据的归一化情况。论文中作者采用K=2,n=5,α=10−4,β=0.75K=2,n=5,α=10−4,β=0.75,相当于把图像进行了增强。
作者发现,使用local normalization操作能够使的top1和top5的错误率降低1.4%和1.2%。
Overlapping Pooling
作者采用的是带有重叠区域的池化操作,并指出:如果pooling层kernel大小为z∗z,步长为s,那么:
当s=z 时候,则为普通的池化操作
当s<z 时候,则为overlapping Pooling池化
论文中作者选取s=2,z=3并指出该操作可以将top1和top5的错误率降低0.4%和0.3%
Dropout
作者在所有的神经元的结构上都使用了dropout操作,factor=0.5。
经典CNN网络结构
.AlexNet的贡献
(1)Relu做**函数,代替Sigmoid来加快SGD的收敛速度。
(2)dropout避免过拟合 。
(3)重叠最大池化 overlapping Max Pooling。
(4)LRN(局部响应归一化),利用临近的数据做归一化,加速训练。
(5)GPU加速。
(6)数据增强,增加模型泛化能力。

3. VGG

( 2014年ImageNet比赛的基础, 作者是Karen Simonyan 和 Andrew Zisserman)
经典CNN网络结构
经典CNN网络结构
VGG总结:

  1. 网络更深,参数量大,共包含参数约为550M,是AlexNet参数量的三倍,这些参数的大部分都可以归因于第一个全连接层。
  2. 堆叠多个小的卷积核而不使用池化操作可以增加网络的表征深度,同时限制参数的数量,而感受野不变。全部使用3x3的卷积核和2x2的最大池化核。
  3. 简化了卷积神经网络的结构。

4.GoogLeNet系列介绍

GoogLeNet(Inception v1)

(2014年,GoogLeNet和VGG是当年ImageNet挑战赛(ILSVRC14)的双雄,GoogLeNet获得了第一名、VGG获得了第二名)
(小知识:GoogLeNet是谷歌(Google)研究出来的深度网络结构,为什么不叫“GoogleNet”,而叫“GoogLeNet”,据说是为了向“LeNet”致敬,因此取名为“GoogLeNet”)

Inception 结构的主要思路是怎样用密集成分来近似最优的局部稀疏结构。
有一个特点是他有三个输出,论文中解释这样做的好处是避免梯度的消失,使得方向传播能够进行,但是还有一个作用就是,这样有三个输出的好处是,相当于可以做一个Ensemble,模型的一个集成,我们知道Kaggle中这个技巧是必用的。而且我们知道,越靠前的层卷积提取的特征越低层次的特征,越靠后的卷积层的特征越高层次,如果只有最有一层的输出,也就是相当于只用了最后的高层次的特征分类,但不一定这样就好,所以GoogleNet使用三个输出,也是使用了不同层次的特征的输出作为分类,这样考虑更加周全。
GoogleNet还有一个减少参数量的方法是,他去掉了FC层,用average Pooling来代替,相比VGG网络和AlexNet网络,几乎所有的参数有耗费在FC层上。
经典CNN网络结构
对上图做以下说明:
1 . 采用不同大小的卷积核意味着不同大小的感受野,最后拼接意味着不同尺度特征的融合;
2 . 之所以卷积核大小采用1、3和5,主要是为了方便对齐。设定卷积步长stride=1之后,只要分别设定pad=0、1、2,那么卷积之后便可以得到相同维度的特征,然后这些特征就可以直接拼接在一起了;
3 . 文章说很多地方都表明pooling挺有效,所以Inception里面也嵌入了。
4 . 网络越到后面,特征越抽象,而且每个特征所涉及的感受野也更大了,因此随着层数的增加,3x3和5x5卷积的比例也要增加。

但是,使用5x5的卷积核仍然会带来巨大的计算量。 为此,文章借鉴NIN2,采用1x1卷积核来进行降维。
例如:上一层的输出为100x100x128,经过具有256个输出的5x5卷积层之后(stride=1,pad=2),输出数据为100x100x256。其中,卷积层的参数为128x5x5x256。假如上一层输出先经过具有32个输出的1x1卷积层,再经过具有256个输出的5x5卷积层,那么最终的输出数据仍为为100x100x256,但卷积参数量已经减少为128x1x1x32 + 32x5x5x256,大约减少了4倍。

具体改进后的Inception Module如下图:
经典CNN网络结构
基于Inception构建了GoogLeNet的网络结构如下(共22层):
经典CNN网络结构
对上图说明如下:
(1)GoogLeNet采用了模块化的结构(Inception结构),方便增添和修改;
(2)网络最后采用了average pooling(平均池化)来代替全连接层,该想法来自NIN(Network in Network),事实证明这样可以将准确率提高0.6%。但是,实际在最后还是加了一个全连接层,主要是为了方便对输出进行灵活调整;
(3)虽然移除了全连接,但是网络中依然使用了Dropout ;
(4)为了避免梯度消失,网络额外增加了2个辅助的softmax用于向前传导梯度(辅助分类器)。辅助分类器是将中间某一层的输出用作分类,并按一个较小的权重(0.3)加到最终分类结果中,这样相当于做了模型融合,同时给网络增加了反向传播的梯度信号,也提供了额外的正则化,对于整个网络的训练很有裨益。而在实际测试的时候,这两个额外的softmax会被去掉。

GoogLeNet的网络结构图细节如下:
经典CNN网络结构
注:上表中的“#3x3 reduce”,“#5x5 reduce”表示在3x3,5x5卷积操作之前使用了1x1卷积的数量。
0、输入
原始输入图像为224x224x3,且都进行了零均值化的预处理操作(图像每个像素减去均值)。
1、第一层(卷积层)
使用7x7的卷积核(滑动步长2,padding为3),64通道,输出为112x112x64,卷积后进行ReLU操作
经过3x3的max pooling(步长为2),输出为((112 - 3+1)/2)+1=56,即56x56x64,再进行ReLU操作
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)、第五层(5a,5b)……,与3a、3b类似,在此就不再重复。

Inception V2

(2015年)
1、卷积分解(Factorizing Convolutions)
大尺寸的卷积核可以带来更大的感受野,但也意味着会产生更多的参数,比如5x5卷积核的参数有25个,3x3卷积核的参数有9个,前者是后者的25/9=2.78倍。因此,GoogLeNet团队提出可以用2个连续的3x3卷积层组成的小网络来代替单个的5x5卷积层,即在保持感受野范围的同时又减少了参数量。
经典CNN网络结构
2. 提出了著名的BN,可以使用较大的学习率,起正则化的作用,减少或取消dropout,简化网络结构。

Inception v3

(2015年12月)
1.将二维卷积拆成两个较小的一维卷积。
可以看出,大卷积核完全可以由一系列的3x3卷积核来替代,那能不能再分解得更小一点呢?GoogLeNet团队考虑了nx1的卷积核,如下图所示,用3个3x1取代3x3卷积:
经典CNN网络结构
任意nxn的卷积都可以通过1xn卷积后接nx1卷积来替代,分解后就能节省33%的计算量。GoogLeNet团队发现在网络的前期使用这种分解效果并不好,在中度大小的特征图(feature map)上使用效果才会更好(特征图大小建议在12到20之间)。
经典CNN网络结构
2、可以使用并行结构来优化Pooling。
一般情况下,如果想让图像缩小,可以有如下两种方式:
经典CNN网络结构
先池化再作Inception卷积,或者先作Inception卷积再作池化。但是方法一(左图)先作pooling(池化)会导致特征表示遇到瓶颈(特征缺失),方法二(右图)是正常的缩小,但计算量很大。为了同时保持特征表示且降低计算量,将网络结构改为下图,使用两个并行化的模块来降低计算量(卷积、池化并行执行,再进行合并)
经典CNN网络结构
经典CNN网络结构
3.使用Label Smoothing来对网络输出进行正则化
LSR可以防止模型把预测值过度集中在概率较大类别上,把一些概率分到其他概率较小类别上。

Inception v4

(2016年)
作者Christian Szegedy设计了inception v4的网络,将原来卷积、池化的顺次连接(网络的前几层)替换为stem模块,来获得更深的网络结构。stem模块结构如下
Inception V4其实就是使用了不同的 Inception Block:

经典CNN网络结构

ResNet

(2015年何恺明推出的ResNet在ISLVRC和COCO上横扫所有选手,获得冠军。ResNet在网络结构上做了大创新,而不再是简单的堆积层数,ResNet在卷积神经网络的新思路,绝对是深度学习发展历程上里程碑式的事件。)

闪光点:
层数非常深,已经超过百层
引入残差单元来解决退化问题

从前面可以看到,随着网络深度增加,网络的准确度应该同步增加,当然要注意过拟合问题。但是网络深度增加的一个问题在于这些增加的层是参数更新的信号,因为梯度是从后向前传播的,增加网络深度后,比较靠前的层梯度会很小。这意味着这些层基本上学习停滞了,这就是梯度消失问题。深度网络的第二个问题在于训练,当网络更深时意味着参数空间更大,优化问题变得更难,因此简单地去增加网络深度反而出现更高的训练误差,深层网络虽然收敛了,但网络却开始退化了,即增加网络层数却导致更大的误差,比如下图,一个56层的网络的性能却不如20层的性能好,这不是因为过拟合(训练集训练误差依然很高),这就是烦人的退化问题。残差网络ResNet设计一种残差模块让我们可以训练更深的网络。

理论上,对于“随着网络加深,准确率下降”的问题,Resnet提供了两种选择方式,也就是identity mapping和residual mapping,如果网络已经到达最优,继续加深网络,residual mapping将被push为0,只剩下identity mapping,这样理论上网络一直处于最优状态了,网络的性能也就不会随着深度增加而降低了。

ResNet有效的原因:
1.前向计算:低层卷积网络与高层卷积网络信息融合,层数越深,模型的表现力越强。
2.后向计算:导数传递更加直接,越过模型,直达各层。
3.瓶颈结构:在创建更深的网络的时候,为了减轻训练时间的负担,ResNet并没有采取开始提出的隔两层添加一个shortcut connection。而是间隔1 * 1、3 * 3、1 * 1的三层网络,第一层用于降低维度,第三层用于升高维度。这种称为Bottleneck Architectures(瓶颈结构)。
经典CNN网络结构
经典CNN网络结构

DenseNet

(CVPR2017)

先列下DenseNet的几个优点,感受下它的强大:
1、减轻了vanishing-gradient(梯度消失)
2、加强了feature的传递
3、更有效地利用了feature
4、一定程度上较少了参数数量

在保证网络中层与层之间最大程度的信息传输的前提下,直接将所有层连接起来。
经典CNN网络结构
DenseNet的一个优点是网络更窄,参数更少,很大一部分原因得益于这种dense block的设计,后面有提到在dense block中每个卷积层的输出feature map的数量都很小(小于100),而不是像其他网络一样动不动就几百上千的宽度。同时这种连接方式使得特征和梯度的传递更加有效,网络也就更加容易训练。原文的一句话非常喜欢:Each layer has direct access to the gradients from the loss function and the original input signal, leading to an implicit deep supervision.直接解释了为什么这个网络的效果会很好。前面提到过梯度消失问题在网络深度越深的时候越容易出现,原因就是输入信息和梯度信息在很多层之间传递导致的,而现在这种dense connection相当于每一层都直接连接input和loss,因此就可以减轻梯度消失现象,这样更深网络不是问题。另外作者还观察到这种dense connection有正则化的效果,因此对于过拟合有一定的抑制作用。

concatenation是做通道的合并,就像Inception那样。而前面resnet是做值的相加,通道数是不变的。
这个Table1就是整个网络的结构图。这个表中的k=32,k=48中的k是growth rate,表示每个dense block中每层输出的feature map个数。为了避免网络变得很宽,作者都是采用较小的k,比如32这样,作者的实验也表明小的k可以有更好的效果。根据dense block的设计,后面几层可以得到前面所有层的输入,因此concat后的输入channel还是比较大的。另外这里每个dense block的33卷积前面都包含了一个11的卷积操作,就是所谓的bottleneck layer,目的是减少输入的feature map数量,既能降维减少计算量,又能融合各个通道的特征,何乐而不为。另外作者为了进一步压缩参数,在每两个dense block之间又增加了11的卷积操作。因此在后面的实验对比中,如果你看到DenseNet-C这个网络,表示增加了这个Translation layer,该层的11卷积的输出channel默认是输入channel到一半。如果你看到DenseNet-BC这个网络,表示既有bottleneck layer,又有Translation layer。
经典CNN网络结构
再详细说下bottleneck和transition layer操作。在每个Dense Block中都包含很多个子结构,以DenseNet-169的Dense Block(3)为例,包含32个11和33的卷积操作,也就是第32个子结构的输入是前面31层的输出结果,每层输出的channel是32(growth rate),那么如果不做bottleneck操作,第32层的33卷积操作的输入就是3132+(上一个Dense Block的输出channel),近1000了。而加上11的卷积,代码中的11卷积的channel是growth rate4,也就是128,然后再作为33卷积的输入。这就大大减少了计算量,这就是bottleneck。至于transition layer,放在两个Dense Block中间,是因为每个Dense Block结束后的输出channel个数很多,需要用11的卷积核来降维。还是以DenseNet-169的Dense Block(3)为例,虽然第32层的33卷积输出channel只有32个(growth rate),但是紧接着还会像前面几层一样有通道的concat操作,即将第32层的输出和第32层的输入做concat,前面说过第32层的输入是1000左右的channel,所以最后每个Dense Block的输出也是1000多的channel。因此这个transition layer有个参数reduction(范围是0到1),表示将这些输出缩小到原来的多少倍,默认是0.5,这样传给下一个Dense Block的时候channel数量就会减少一半,这就是transition layer的作用。文中还用到dropout操作来随机减少分支,避免过拟合,毕竟这篇文章的连接确实多。

最后,放一张各个网络模型参数对比
经典CNN网络结构