在CNN网络结构的进化过程中,出现过许多优秀的CNN网络,如:LeNet,AlexNet,VGG-Net,GoogLeNet,ResNet,DesNet.
提出年份
LeNet诞生于1998年,网络结构比较完整,包括卷积层、pooling层、全连接层。被认为是CNN的鼻祖。
输入32*32*1
卷积层3个:卷积的主要目的是使原始信号特征增强,并且降低噪音 卷积核 5*5
下采样层2个(池化):池化层的作用是降低网络训练参数及模型的过拟合程度。
全连接1个
输出层1个 10个类别 softmax /
2012年提出AlexNet网络8层网络结构 5conv +5pooling +3fc+1000output class
输入:224x224x3
各层神经元的数量:253,440=>186,624=>64,896=>64,896=>43,264=>4096=>4096=>1000(ImageNet有1000个类
主要优势包括:
传统的激活函数一般是sigmoid和tanh两种饱和非线性函数,就训练时间来说,使用这些饱和的非线性函数会比使用非饱和的非线性函数ReLU,模型收敛需要更长的时间。而对于大型的数据集来说,更快的学习过程意味着可以节省更多的时间。除此之外,ReLU也引入了一定的稀疏性,在特征表示的范畴内,数据有一定的稀疏性,也就是说,有一部分的数据其实是冗余的。通过引入ReLU,可以模拟这种稀疏性,以最大近似的方式来保留数据的特征。
减轻过拟合:数据增强,dropout ,learning rate decay
(2) 改变rgb的通道 的强度:给图像增加一些随机的光照,彩色变化,颜色抖动
这里的p和λ是RGB值3x3协方差矩阵的特征向量和特征值。α是均值为1标准差为0.1的高斯随机变量。
这么做的原因是利用了自然图片的一条重要性质:物体的鉴别特征并不会因为图片强度和颜色的变化而变化,也就是说,一定程度上改变图片的对比度、亮度、物体的颜色,并不会影响我们对物体的识别。在ImageNet上使用这个方法,降低了1%的top-1 error
Bagging定义k个不同的模型,从training set采样出k个不同的数据集,在第i个模型上用第i个数据集进行训练,最后综合k个模型的结果,获得最终的模型。但是需要的空间、时间都很大,在DNN中并不现实。
Dropout的目的是在指数级子网络的深度神经网络中近似Bagging。也就是说,在训练时,每次Dropout后,训练的网络是整个深度神经网络的其中一个子网络。在测试时,将dropout层取消,这样得到的前向传播结果其实就是若干个子网络前向传播综合结果的一种近似。
dropout,以0.5的概率将每个隐藏神经元的输出设置为0,以这种方式被抑制的神经元既不参与前向也不参与反向传播。每次输入一个样本,相当于该神经网络尝试一个新结构,但是这些结构之间的共享权值,因为神经元不能依赖其他的神经元而存在,所以这种技术降低了神经元复杂的互适应性,因此,网络需要被迫学习更加健壮的特征,这些特征结合其他神经元的一些不同随机子集时很有用,如果没有dropout网络会出现大量的过拟合,dropout使收敛所需的迭代次数增加一倍。
2012年,Imagenet比赛冠军的model——Alexnet [2](以第一作者alex命名)。caffe的model文件在这里。说实话,这个model的意义比后面那些model都大很多,首先它证明了CNN在复杂模型下的有效性,然后GPU实现使得训练在可接受的时间范围内得到结果,确实让CNN和GPU都大火了一把,顺便推动了有监督DL的发展。
模型结构见下图,别看只有寥寥八层(不算input层),但是它有60M以上的参数总量,事实上在参数量上比后面的网络都大
224*224*3 (rgb)
253,440=>186,624=>64,896=>64,896=>43,264=>4096=>4096=>1000(ImageNet有1000个类)
计算186624是怎么来的?27*27*256
一个feature map 计算
这个图有点点特殊的地方是卷积部分都是画成上下两块,意思是说吧这一层计算出来的feature map分开,但是前一层用到的数据要看连接的虚线,如图中input层之后的第一层第二层之间的虚线是分开的,是说二层上面的128map是由一层上面的48map计算的,下面同理;而第三层前面的虚线是完全交叉的,就是说每一个192map都是由前面的128+128=256map同时计算得到的。
Alexnet有一个特殊的计算层,LRN层,做的事是对当前层的输出结果做平滑处理。下面是我画的示意图:
前后几层(对应位置的点)对中间这一层做一下平滑约束,计算方法是:
具体打开Alexnet的每一阶段(含一次卷积主要计算)来看[2][3]:
(1)con - relu - pooling - LRN
具体计算都在图里面写了,要注意的是input层是227*227,而不是paper里面·······························的224*224,这里可以算一下,主要是227可以整除后面的conv1计算,224不整除。如果一定要用224可以通过自动补边实现,不过在input就补边感觉没有意义,补得也是0。
(2)conv - relu - pool - LRN
和上面基本一样,唯独需要注意的是group=2,这个属性强行把前面结果的feature map分开,卷积部分分成两部分做。
(3)conv - relu
(4)conv-relu
(5)conv - relu - pool
(6)fc - relu - dropout
这里有一层特殊的dropout层,在alexnet中是说在训练的以1/2概率使得隐藏层的某些neuron的输出为0,这样就丢到了一半节点的输出,BP的时候也不更新这些节点。
(7)
fc - relu - dropout
(8)fc - softmax
2014年提出VGG-Net网络,。
主要优势包括:
网络更深,使用更多的层,通常有16-19层; kernel大小,卷积stride,
所有 卷积层用同样大小(3 x 3)的 卷积核(减少参数),核步长统一为1,padding 统一为1 。 。证明更小的卷积核并且增加卷积神经网络的深度可以有效的提高模型的性能。
直观上我们会觉得大的卷积核更好,因为它可以提取到更大区域内的信息,但是实际上,大卷积核可以用多个小卷积核进行代替。例如,一个 的卷积核就可以用两个串联的 卷积核来代替,一个 的卷积核就可以用三个串联的 卷积核来代替。这样的替代方式有两点好处:
- 减少参数,两个串联小卷积 3*3*2 =18 5*5=25 串联三个小卷积 3*3*3=27 7*7=49
- 引入更多的非线性:多少个串联的小卷积核就对应着多少次激活(activation)的过程,而一个大的卷积核就只有一次激活的过程。引入了更多的非线性变换,也就意味着模型的表达能力会更强,可以去拟合更高维的分布。
- VGGNet结构的C里面还用到了 的卷积核。但是这里对这种卷积核的使用并不是像Inception里面拿来对通道进行整合,模拟升维和降维,这里并没有改变通道数,所以可以理解为是进一步的引入非线性
提出Inception结构,这是NIN(Network In Network)的结构,即原来的结点也是一个网络。
googlenet[4][5],14年比赛冠军的model,这个model证明了一件事:用更多的卷积,更深的层次可以得到更好的结构。(当然,它并没有证明浅的层次不能达到这样的效果)
GoogLeNet的核心思想是:将全连接,甚至卷积中的局部连接,全部替换为稀疏连接。
既能保持网络结构的稀疏性,又能利用密集计算的高效性的方法。inception产生。
改进:
- 将原来线性卷积层改为多层感知卷积层
- 将全连接层改为全局平均池化
- 网络中有三个softmax,这是为了减轻在深层网络反向传播时梯度消失的影响,也就是说,整个网络的loss是由三个softmax共同组成的,这样在反向传播的时候,即使最后一个softmax传播回来的梯度消失了,还有前两个softmax传播回来的梯度进行辅助
主要思想:
- 深度:22层,为了避免梯度消失,巧妙在不同深度的地方增加两个损失函数避免反向传播时梯度消失的问题
- 宽度:1*1 3*3 5*5 结合起来的特征映射厚度将会更大,1*1卷积核降维,起降低特征映射厚度的作用。
naive inception
这个model基本上构成部件和alexnet差不多,不过中间有好几个inception的结构:
NIN(network in network) 1*1卷积层的意义和作用:改变通道数,参数减少,提高模型的性能
是说一分四,然后做一些不同大小的卷积,之后再堆叠feature map。
计算量如下图,可以看到参数总量并不大,但是计算次数是非常大的。
VGG有很多个版本,也算是比较稳定和经典的model。它的特点也是连续conv多,计算量巨大(比前面几个都大很多)。具体的model结构可以参考[6],这里给一个简图。基本上组成构建就是前面alexnet用到的。
下面是几个model的具体结构,可以查阅,很容易看懂。
问题
增加网络深度后,网络可以进行更加复杂的特征提取,因此更深的模型可以取得更好的结果。但是,网络加深后不仅测试误差变高了,它的训练误差竟然也变高了。作者提出,这可能是因为更深的网络会伴随梯度消失/爆炸问题,从而阻碍网络的收敛。作者将这种加深网络深度但网络性能却下降的现象称为退化问题,degradation problem. 反向传导的过程中有两条线,一条如果梯度消失,另一条不消失。
解决问题
随着网络加深,网络退化的问题, 提出batch normalization 一定程度上缓解这个问题,但是仍然不足以满足需求。
提出构建恒等映射。问题解决的标志是:增加网络层数,但训练误差不增加。为什么是恒等映射呢,我是这样子想的:20层的网络是56层网络的一个子集,如果我们将56层网络的最后36层全部短接,这些层进来是什么出来也是什么(也就是做一个恒等映射),那这个56层网络不就等效于20层网络了吗,至少效果不会相比原先的20层网络差吧。那不引入恒等映射的56层网络为什么不行呢?因为梯度消失现象使得网络难以训练,虽然网络的深度加深了,但是实际上无法有效训练网络,训练不充分的网络不但无法提升性能,甚至降低了性能。
残差:观测值与估计值之间的差距 x是原来,h(x) 预测 那么f(x)=h(X)-x 残差
resnet,其实是如果能用,几层网络去逼近一个复杂的非线性映射h(x)来预测图片的分类,同样可以用这几层网络去逼近它的残差函数 F(x)=H(X)-X,并且认为优化残差映射要比直接优化H(X)简单。原来输入x 希望输出h(X) ,我们令H(x)=F(x)+x,那么我们的网络就只需要学习输出一个残差F(x)=H(x)-x。 希望用两层的weight layer的传播来拟合残差,那么我们想要得到的理想映射H(x)=F(x)+x。这就是残差网络的基本理念,网络学习的是去拟合残差,而不是直接拟合输入和输出直接的映射。
resnet网络 主要的5种变形: resnet18,res34,res50,res101,res152.
block的构成见下图:
刚刚我们调用的resnet18( )函数中有一句 ResNet(BasicBlock, [2, 2, 2, 2], **kwargs),这里的[2, 2, 2, 2]与图中红框是一致的,如果你将这行代码改为 ResNet(BasicBlock, [3, 4, 6, 3], **kwargs), 那你就会得到一个res34网络。
ResNet50起,就采用Bottleneck结构,主要是引入1x1卷积。我们来看一下这里的1x1卷积有什么作用:
对通道数进行升维和降维(跨通道信息整合),实现了多个特征图的线性组合,同时保持了原有的特征图大小;
相比于其他尺寸的卷积核,可以极大地降低运算复杂度;
如果使用两个3x3卷积堆叠,只有一个relu,但使用1x1卷积就会有两个relu,引入了更多的非线性映射;
Basicblock和Bottleneck结构
我们来计算一下1*1卷积的计算量优势:首先看上图右边的bottleneck结构,对于256维的输入特征,参数数目:1x1x256x64+3x3x64x64+1x1x64x256=69632,如果同样的输入输出维度但不使用1x1卷积,而使用两个3x3卷积的话,参数数目为(3x3x256x256)x2=1179648。简单计算下就知道了,使用了1x1卷积的bottleneck将计算量简化为原有的5.9%,收益超高。
先降 后升 1*1
整个ResNet不使用dropout,全部使用BN。此外,回到最初的这张细节图,我们不难发现一些规律和特点:
受VGG的启发,卷积层主要是3×3卷积;
对于相同的输出特征图大小的层,即同一stage,具有相同数量的3x3滤波器;
如果特征地图大小减半,滤波器的数量加倍以保持每层的时间复度。
每个stage通过步长为2的卷积层执行下采样,而却这个下采样只会在每一个satge的第一个卷积完成,有且仅有一次。
网络以全局平均池化层和softmax的1000路全连接层结束。
改进一:改进downsample部分,减少信息流失。前面说过了,每个stage的第一个conv都有下采样的步骤,我们看左边第一张图左侧的通路,input数据进入后在会经历一个stride=2的1*1卷积,将特征图尺寸减小为原先的一半,请注意1x1卷积和stride=2会导致输入特征图3/4的信息不被利用,因此ResNet-B的改进就是就是将下采样移到后面的3x3卷积里面去做,避免了信息的大量流失。ResNet-C则是另一种思路。ResNet-D则是在ResNet-B的基础上将identity部分的下采样交给avgpool去做,避免出现1x1卷积和stride同时出现造成信息流失。
改进二:ResNet V2。这是由ResNet原班人马打造的,主要是对ResNet部分组件的顺序进行了调整。各种魔改中常见的预激活ResNet就是出自这里。
原始的resnet是上图中的a的模式,我们可以看到相加后需要进入ReLU做一个非线性激活,这里一个改进就是砍掉了这个非线性激活,不难理解,如果将ReLU放在原先的位置,那么残差块输出永远是非负的,这制约了模型的表达能力,因此我们需要做一些调整,我们将这个ReLU移入了残差块内部,也就是图e的模式。
ResNet 中其实是存在着很多路径的集合,整个ResNet类似于多个网络的集成学习,证据是删除部分ResNet的网络结点,不影响整个网络的性能,但是在VGG上做同样的事请网络立刻崩溃,由此可见相比其他网络ResNet对于部分路径的缺失不敏感
残差结构使得梯度反向传播时,更不易出现梯度消失等问题,由于Skip Connection的存在,梯度能畅通无阻地通过各个Res blocks,下面我们来推导一下 ResNet v2 的反向传播过程。
我们从这个表达式可以看出来:第l层的梯度里,包含了第L层的梯度,通俗的说就是第L层的梯度直接传递给了第l层。因为梯度消失问题主要是发生在浅层,这种将深层梯度直接传递给浅层的做法,有效缓解了深度神经网络梯度消失的问题。
dense block
如图所示的结构就叫作Dense Block,它包括输入层在内共有5层,H是BN+ReLU+3x3Conv的操作,并不改变feature map的大小。对于每一层来说,前面所有层的feature map都被直接拿来作为这一层的输入。growth rate就是除了输入层之外,每一层feature map的个数。它的目的是,使得block中的任意两层都能够直接”沟通“。
其实在Dense Block输出的地方还有一个bottleneck layer,在bottleneck layer中的操作是一个1x1的卷积,卷积核共有4k个,降低channel维度,也就是减少了模型的参数。
在transition layer中有进一步压缩的操作称为compression,减少百分之θ的feature map数量,论文中使用的θ=0.5。
DenseBlock是包含很多层的模块,每个层的特征图大小相同,层与层之间采用密集连接方式。
Transition模块是连接两个相邻的DenseBlock,并且通过Pooling使特征图大小降低。图4给出了DenseNet的网路结构,它共包含4个DenseBlock,各个DenseBlock之间通过Transition连接在一起。
然后介绍DenseNet的模型:
DenseNet其实是由若干个Dense Block串联起来而得到的,在每个Dense Block之间有一个Convolution+Pooling的操作,也就是图1中的transition layer。transition layer存在的意义是实现池化,作者在论文中承认了pooling的重要性。
分析一下为什么会从ResNet发展到DenseNet:
借用论文里的话,ResNet直接通过"Summation"操作将特征加起来,一定程度上阻碍(impede)了网络中的信息流。DenseNet通过连接(concatenate)操作来结合feature map,并且每一层都与其他层有关系,都有”沟通“,这种方式使得信息流最大化。其实DenseNet中的dense connectivity就是一种升级版的shortcut connection,提升了网络的鲁棒性并且加快了学习速度。
在DenseBlock中,各个层的特征图大小一致,可以在channel维度上连接。DenseBlock中的非线性组合函数 采用的是BN+ReLU+3x3 Conv的结构。
另外值得注意的一点是,与ResNet不同,所有DenseBlock中各个层卷积之后均输出 个特征图,即得到的特征图的channel数为 ,或者说采用 个卷积核。 在DenseNet称为growth rate,这是一个超参数。一般情况下使用较小的 (比如12),就可以得到较佳的性能。假定输入层的特征图的channel数为 ,那么 层输入的channel数为 ,因此随着层数增加,尽管 设定得较小,DenseBlock的输入会非常多,不过这是由于特征重用所造成的,每个层仅有 个特征是自己独有的。
由于后面层的输入会非常大,DenseBlock内部可以采用bottleneck层来减少计算量,主要是原有的结构中增加1x1 Conv,如图7所示,即BN+ReLU+1x1 Conv+BN+ReLU+3x3 Conv,称为DenseNet-B结构。其中1x1 Conv得到 个特征图它起到的作用是降低特征数量,从而提升计算效率。
它主要是连接两个相邻的DenseBlock,并且降低特征图大小。Transition层包括一个1x1的卷积和2x2的AvgPooling,结构为BN+ReLU+1x1 Conv+2x2 AvgPooling。另外,Transition层可以起到压缩模型的作用。假定Transition的上接DenseBlock得到的特征图channels数为 ,Transition层可以产生 个特征(通过卷积层),其中 是压缩系数(compression rate)。当 时,特征个数经过Transition层没有变化,即无压缩,而当压缩系数小于1时,这种结构称为DenseNet-C,文中使用 。对于使用bottleneck层的DenseBlock结构和压缩系数小于1的Transition组合结构称为DenseNet-BC
DenseNet共在三个图像分类数据集(CIFAR,SVHN和ImageNet)上进行测试。对于前两个数据集,其输入图片大小为 ,所使用的DenseNet在进入第一个DenseBlock之前,首先进行进行一次3x3卷积(stride=1),卷积核数为16(对于DenseNet-BC为 )。DenseNet共包含三个DenseBlock,各个模块的特征图大小分别为 , 和 ,每个DenseBlock里面的层数相同。最后的DenseBlock之后是一个global AvgPooling层,然后送入一个softmax分类器。注意,在DenseNet中,所有的3x3卷积均采用padding=1的方式以保证特征图大小维持不变。对于基本的DenseNet,使用如下三种网络配置: , , 。而对于DenseNet-BC结构,使用如下三种网络配置: , , 。这里的 指的是网络总层数(网络深度),一般情况下,我们只把带有训练参数的层算入其中,而像Pooling这样的无参数层不纳入统计中,此外BN层尽管包含参数但是也不单独统计,而是可以计入它所附属的卷积层。对于普通的 网络,除去第一个卷积层、2个Transition中卷积层以及最后的Linear层,共剩余36层,均分到三个DenseBlock可知每个DenseBlock包含12层。其它的网络配置同样可以算出各个DenseBlock所含层数。
对于ImageNet数据集,图片输入大小为 ,网络结构采用包含4个DenseBlock的DenseNet-BC,其首先是一个stride=2的7x7卷积层(卷积核数为 ),然后是一个stride=2的3x3 MaxPooling层,后面才进入DenseBlock。ImageNet数据集所采用的网络配置如表1所示:
图中的每个conv代表的都是BN+ReLU+Conv的一连贯操作。