【DL-图像分类】

图像分类

  • 一、卷积神经网络基础
    • 1、卷积神经网络
    • 2、全连接层
    • 3、卷积层
    • 4、池化层
  • 二、LeNet-5
  • 三、AlexNet
  • 四、VggNet
  • 五、GoogLeNet
    • 5.1 GoogLeNet Inception V1——22层
    • 5.2 GoogLeNet Inception V2
    • 5.3 GoogLeNet Inception V3
    • 5.4 GoogLeNet(V1)
  • 六、ResNet

一、卷积神经网络基础

1、卷积神经网络

卷积神经网络是一种带有卷积结构的深度神经网络,卷积结构可以减少深层网络占用的内存量,其三个关键的操作,其一是局部感受野,其二是权值共享,其三是pooling层,有效的减少了网络的参数个数,缓解了模型的过拟合问题。

卷积神经网络结构包括:卷积层,下采样层,全连接层。以此来达到简化网络参数并使得网络具有一定程度的位移、尺度、缩放、非线性形变稳定性。
每一层有多个特征图,每个特征图通过一种卷积滤波器提取输入的一种特征,每个特征图有多个神经元。

通常将输入层到隐藏层的映射称为一个特征映射,也就是通过卷积层得到特征提取层,经过pooling之后得到特征映射层。

2、全连接层

全连接层:采用softmax全连接,得到的激活值即卷积神经网络提取到的图片特征。

3、卷积层

卷积层:因为通过卷积运算我们可以提取出图像的特征,通过卷积运算可以使得原始信号的某些特征增强,并且降低噪声。

用一个可训练的滤波器fx去卷积一个输入的图像(第一阶段是输入的图像,后面的阶段就是卷积特征map了),然后加一个偏置bx,得到卷积层Cx。

目的:进行图像特征提取

卷积及特性:
1.拥有局部感知机制
2.权值共享

1.卷积核的channel(深度)与输入特征层的channel相同
2.输出的特征矩阵的channel与卷积核个数相同

【DL-图像分类】_第1张图片

4、池化层

池化:取区域平均或最大

下采样层:因为对图像进行下采样,可以减少数据处理量同时保留有用信息,采样可以混淆特征的具体位置,因为某个特征找出来之后,其它的位置已经不重要了,我们只需要这个特征和其他特征的相对位置,可以应对形变和扭曲带来的同类物体的变化。

每邻域四个像素求和变为一个像素,然后通过标量Wx+1加权,再增加偏置bx+1,然后通过一个sigmoid激活函数,产生一个大概缩小四倍的特征映射图Sx+1。

目的:对特征图进行稀疏处理,减少数据运算量。

1.没有训练参数
2.只改变特征矩阵的w和h,不改变channel
3.一般poolsize和stride相同

参考博客:
参考一
参考二


【DL-图像分类】_第2张图片

二、LeNet-5

【DL-图像分类】_第3张图片
LeNet-5共包含8层

  • C1层是一个卷积层,由6个特征图Feature
    Map构成。特征图中每个神经元与输入为5×5的邻域相连。特征图的大小为28×28,这样能防止输入的连接掉到边界之外(32-5+1=28)。C1有156个可训练参数(每个滤波器5×5=25个unit参数和一个bias参数,一共6个滤波器,共(5×5+1)6=156个参数),共156(28*28)=122,304个连接。

  • S2层是一个下采样层,有6个14×14的特征图。特征图中的每个单元与C1中相对应特征图的2×2邻域相连接。S2层每个单元的4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。每个单元的2×2感受野并不重叠,因此S2中每个特征图的大小是C1中特征图大小的1/4(行和列各1/2)。S2层有12(6(1+1)=12)个可训练参数和5880(14×14(2*2+1)*6=5880)个连接。

  • C3层也是一个卷积层,它同样通过5x5的卷积核去卷积层S2,然后得到的特征map就只有10x10个神经元,但是它有16种不同的卷积核,所以就存在16个特征map了。C3中每个特征图由S2中所有6个或者几个特征map组合而成。为什么不把S2中的每个特征图连接到每个C3的特征图呢?原因有2点。第一,不完全的连接机制将连接的数量保持在合理的范围内。第二,也是最重要的,其破坏了网络的对称性。由于不同的特征图有不同的输入,所以迫使他们抽取不同的特征(希望是互补的)。

例如,存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。这样C3层有1516(6*(325+1)+6(425+1)+3(425+1)+(256+1)=1516)个可训练参数和151600(10101516=151600)个连接。

  • S4层是一个下采样层,由16个5×5大小的特征图构成。特征图中的每个单元与C3中相应特征图的2×2邻域相连接,跟C1和S2之间的连接一样。S4层有32个可训练参数(每个特征图1个因子和一个偏置16*(1+1)=32)和2000(16*(2*2+1)5×5=2000)个连接。

  • C5层是一个卷积层,有120个特征图。每个单元与S4层的全部16个单元的5×5邻域相连。由于S4层特征图的大小也为5×5(同滤波器一样),故C5特征图的大小为1×1(5-5+1=1):这构成了S4和C5之间的全连接。之所以仍将C5标示为卷积层而非全相联层,是因为如果LeNet-5的输入变大,而其他的保持不变,那么此时特征图的维数就会比1×1大。C5层有48120(120*(1655+1)=48120由于与全部16个单元相连,故只加一个偏置)个可训练连接。

  • F6层有84个单元(之所以选这个数字的原因来自于输出层的设计),与C5层全相连。有10164(84*(120*(1*1)+1)=10164)个可训练参数。如同经典神经网络,F6层计算输入向量和权重向量之间的点积,再加上一个偏置。然后将其传递给sigmoid函数产生单元i的一个状态。

  • 最后,输出层由欧式径向基函数(Euclidean Radial Basis Function)单元组成,每类一个单元,每个有84个输入。

1、输入层:N个32x32的训练样本
输入图像大小为32x32,比MNIST数据库中的字母大,这样做的原因是希望潜在的明显特征,如笔画断点或角点能够出现在最高层特征监测子感受野的中心。

2、C1层
输入图像大小:32x32
卷积核大小:5x5
卷积核个数:6
输出特征图数量:6
输出特征图大小:28x28(32-5+1)
神经元数量:4707(28x28x6)
连接数:122304((28x28x5x5x6)+(28x28x6))
可训练参数:156(5x5x6+6,权值+偏置)

3、S2层
输入图像大小:(28x28x6)
卷积核大小:2x2
卷积核个数:6
输出特征图数量:6
输出特征图大小:14x14(28/2,28/2)
神经元数量:1176(14x14x6)
连接数:5880((2x2x14x14x6)+(14x14x6))
可训练参数:12(1x6+6,权值+偏置)

备注:S2层每个单元的4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid函数计算。可训练系数和偏置控制着sigmoid函数的非线性程度。
如果系数比较小,那么运算近似于线性运算,下采样相当于模糊图像。
如果系数比较大,根据偏置的大小下采样可以被看成是有噪声的“或”运算或者有噪声的“与”运算。
每个单元的2*2感受野并不重叠,因此S2中每个特征图的大小是C1中特征图大小的1/4(行和列各1/2)。

4、C3层

输入图像大小:(14x14x6)
卷积核大小:5x5
卷积核个数:16
输出特征图数量:16
输出特征图大小:10x10(14-5+1)
神经元数量:1600(10x10x16)
连接数:151600(1516x10x10)
可训练参数:1516
备注:C3层也是一个卷积层,通过5x5的卷积核去卷积S2层,然后得到的特征图map就有10x10个神经元,但是有16种不同的卷积核,就存在16个不同的特征map。

C3中每个特征图由S2中的所有6个或几个特征图组合而成,为什么不把S2中的所有特征图都连接到C3的特征图呢:
第一,不完全的连接机制将连接的数量保持在合理的范围内
第二,也是最重要的,这样一来就可以破坏网络的对称性,由于不同的特征图有不同的输入,所以迫使他们抽取不同的特征。

5、S4层
输入图像大小:(10x10x16)
卷积核大小:2x2
卷积核个数:16
输出特征图数量:16
输出特征图大小:5x5x16
神经元数量:400(5x5x16)
连接数:2000((2x2x5x5x16)+(5x5x16))
可训练参数:32((1+1)x16)
备注:S4是一个下采样层,由16个5x5大小的特征图构成,特征图的每个单元与C3中相应的特征图的2x2邻域相连,S4层有32个可训练参数(每个特征图1个因子和一个偏置)和2000个连接。

6、C5层
输入图像大小:5x5x16
卷积核大小:5x5
卷积核个数:120
输出特征图数量:120
输出特征图大小:1X1(5-5+1)
神经元数量:120(1x120)
连接数:48120(5x5x16x120x1+120x1)
可训练参数:48120(5x5x16x120+120)
备注:C5层是一个卷积层,有120个特征图,每个单元与S4层的全部16个单元的5x5邻域相连,构成了S4和C5的全连接,之所以仍将C5标识为卷积层而非全连接层是因为如果LeNet-5的输入变大,而其他的保持不变,那么此时特征图的维数就会比1x1大。

7、F6层
输入图像大小:(1x1x120)
卷积核大小:1x1
卷积核个数:84
输出特征图数量:1
输出特征图大小:84
神经元数量:84
连接数:10164(120x84+84)
可训练参数:10164(120x84+84)
备注:F6有84个单元(之所以选择84是源于输出层的设计),与C5层相连,有10164个可训练参数,类似经典的全连接神经网络,F6层计算输入向量和权重向量之间的点积,再加上一个偏置,之后将其传递给sigmoid函数产生一个单元i的状态。

8、output层
输入图像大小:1x84
输出特征图数量:1x10


python代码实现


代码中需要理解的函数

一、torch.nn.Conv2d( in_channels , out_channels , kernel_size , stride = 1 , padding = 0 , dilation = 1 , groups = 1 ,
                 bias = True , padding_mode = 'zeros' , device = None , dtype = None )

参数:
in_channels ( int ) – 输入图像中的通道数

out_channels ( int ) – 卷积产生的通道数

kernel_size ( int or tuple ) – 卷积核的大小

stride ( int or tuple , optional ) -- 卷积的步幅。默认值:1

padding ( int , tuple或str , optional ) – 添加到输入的所有四个边的填充。默认值:0

padding_mode (字符串,可选)'zeros', 'reflect', 'replicate''circular'. 默认:'zeros'

dilation ( int or tuple , optional ) -- 内核元素之间的间距。默认值:1

groups ( int , optional ) -- 从输入通道到输出通道的阻塞连接数。默认值:1

bias ( bool , optional ) – If True,向输出添加可学习的偏差。默认:True

二、torch.nn.MaxPool2d( kernel_size , stride = None , padding = 0 , dilation = 1 , return_indices = False , ceil_mode = False )

参数:
kernel_size – 最大的窗口大小

stride:步幅——窗口的步幅。默认值为kernel_size

padding – 要在两边添加隐式零填充

dilation – 控制窗口中元素步幅的参数

return_indices - 如果True,将返回最大索引以及输出。torch.nn.MaxUnpool2d以后有用

ceil_mode – 如果为 True,将使用ceil而不是floor来计算输出形状

三、AlexNet

【DL-图像分类】_第4张图片
【DL-图像分类】_第5张图片
【DL-图像分类】_第6张图片

卷积结果计算公式
输入图像的大小为nxn,卷积核的大小为mxm,步长为s, 为输入图像两端填补p个零(zero padding),那么卷积操作之后输出的大小为(n-m+2p)/s + 1

网络包含8个带权重的层;前5层是卷积层,剩下的3层是全连接层。最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布。

卷积层C1:该层的处理流程是: 卷积–>ReLU–>池化–>归一化。

  • 卷积,输入是227×227×3 227×227×3,使用96个11×11×3 11×11×3的卷积核,得到的FeatureMap为55×55×96 55×55×96。
  • ReLU,将卷积层输出的FeatureMap输入到ReLU函数中。
  • 池化,使用3×3 3×3步长为2的池化单元(重叠池化,步长小于池化单元的宽度),输出为27×27×96 27×27×96((55−3)/2+1=27(55−3)/2+1=27)
  • 局部响应归一化,使用k=2,n=5,α=10−4,β=0.75k=2,n=5,α=10−4,β=0.75进行局部归一化,输出的仍然为27×27×96 27×27×96,输出分为两组,每组的大小为27×27×48 27×27×48

卷积层C2:该层的处理流程是:卷积–>ReLU–>池化–>归一化

  • 卷积,输入是2组27×27×48 27×27×48。使用2组,每组128个尺寸为5×5×48 5×5×48的卷积核,并作了边缘填充padding=2,卷积的步长为1. 则输出的FeatureMap为2组,每组的大小为27×27×128 27×27×128. ((27+2∗2−5)/1+1=27(27+2∗2−5)/1+1=27)
  • ReLU,将卷积层输出的FeatureMap输入到ReLU函数中
  • 池化运算的尺寸为3×3 3×3,步长为2,池化后图像的尺寸为(27−3)/2+1=13(27−3)/2+1=13,输出为13×13×256 13×13×256
  • 局部响应归一化,使用k=2,n=5,α=10−4,β=0.75k=2,n=5,α=10−4,β=0.75进行局部归一化,输出的仍然为13×13×256 13×13×256,输出分为2组,每组的大小为13×13×128 13×13×128

卷积层C3:该层的处理流程是: 卷积–>ReLU

  • 卷积,输入是13×13×256 13×13×256,使用2组共384尺寸为3×3×256 3×3×256的卷积核,做了边缘填充padding=1,卷积的步长为1.则输出的FeatureMap为13×13×384 13×13×384
  • ReLU,将卷积层输出的FeatureMap输入到ReLU函数中

卷积层C4:该层的处理流程是: 卷积–>ReLU。该层和C3类似。

  • 卷积,输入是13×13×384 13×13×384,分为两组,每组为13×13×192 13×13×192.使用2组,每组192个尺寸为3×3×192 3×3×192的卷积核,做了边缘填充padding=1,卷积的步长为1.则输出的FeatureMap为13×13×384 13×13×384,分为两组,每组为13×13×192 13×13×192
  • ReLU,将卷积层输出的FeatureMap输入到ReLU函数中

卷积层C5:该层处理流程为:卷积–>ReLU–>池化

  • 卷积,输入为13×13×384 13×13×384,分为两组,每组为13×13×192 13×13×192。使用2组,每组为128尺寸为3×3×192 3×3×192的卷积核,做了边缘填充padding=1,卷积的步长为1.则输出的FeatureMap为13×13×256 13×13×256
  • ReLU,将卷积层输出的FeatureMap输入到ReLU函数中
  • 池化,池化运算的尺寸为3×3,步长为2,池化后图像的尺寸为 (13−3)/2+1=6(13−3)/2+1=6,即池化后的输出为6×6×256 6×6×256

全连接层FC6:该层的流程为:(卷积)全连接 -->ReLU -->Dropout

  • 卷积->全连接: 输入为6×6×256 6×6×256,该层有4096个卷积核,每个卷积核的大小为6×6×256 6×6×256。由于卷积核的尺寸刚好与待处理特征图(输入)的尺寸相同,即卷积核中的每个系数只与特征图(输入)尺寸的一个像素值相乘,一一对应,因此,该层被称为全连接层。由于卷积核与特征图的尺寸相同,卷积运算后只有一个值,因此,卷积后的像素层尺寸为4096×1×1 4096×1×1,即有4096个神经元。
  • ReLU,这4096个运算结果通过ReLU激活函数生成4096个值
  • Dropout,抑制过拟合,随机的断开某些神经元的连接或者是不激活某些神经元

全连接层FC7:流程为:全连接–>ReLU–>Dropout

  • 全连接,输入为4096的向量
  • ReLU,这4096个运算结果通过ReLU激活函数生成4096个值
  • Dropout,抑制过拟合,随机的断开某些神经元的连接或者是不激活某些神经元

输出层

  • 第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出1000个float型的值,这就是预测结果。

Alexnet网络中各个层发挥的作用如下表所述

算法 作用
ReLu、多个CPU 提高训练速度
重叠pool池化 提高精度、不容易产生过拟合
局部响应归一化 提高精度
数据增益、Droupout 减少过拟合

超详解AlexNet见此博文


python代码实现


四、VggNet

论文参考:https://arxiv.org/pdf/1409.1556.pdf

python代码实现


VGGNet探索了CNN的深度及其性能之间的关系,通过反复堆叠33的小型卷积核和22的最大池化层,VGGNet成功的构筑了16-19层深的CNN。

创新点

VGGNet全部使用33的卷积核和22的池化核,通过不断加深网络结构来提升性能。网络层数的增长并不会带来参数量上的爆炸,因为参数量主要集中在最后三个全连接层中。同时,两个33卷积层的串联相当于1个55的卷积层,3个33的卷积层串联相当于1个77的卷积层,即3个33卷积层的感受野大小相当于1个77的卷积层。但是3个33的卷积层参数量只有77的一半左右,同时前者可以有3个非线性操作,而后者只有1个非线性操作,这样使得前者对于特征的学习能力更强。

使用11的卷积层来增加线性变换,输出的通道数量上并没有发生改变。这里提一下11卷积层的其他用法,11的卷积层常被用来提炼特征,即多通道的特征组合在一起,凝练成较大通道或者较小通道的输出,而每张图片的大小不变。有时11的卷积神经网络还可以用来替代全连接层。

其他小技巧。VGGNet在训练的时候先训级别A的简单网络,再复用A网络的权重来初始化后面的几个复杂模型,这样收敛速度更快。VGGNet作者总结出LRN层作用不大,越深的网络效果越好,11的卷积也是很有效的,但是没有33的卷积效果好,因为3*3的网络可以学习到更大的空间特征。

VGGNet结构

VGGNet有A-E七种结构,从A-E网络逐步变深,但是参数量并没有增长很多,原因为:参数量主要消耗在最后3个全连接层,而前面的卷积层虽然层数多,但消耗的参数量不大。不过,卷积层的训练比较耗时,因为其计算量大。

其中,D和E是常说的VGGNet-16和VGGNet-19。C很有意思,相比于B多了几个11的卷积层,11卷积的意义在于线性变换,而输入的通道数和输出的通道数不变,没有发生降维。

【DL-图像分类】_第7张图片

VGGNet网络特点

  1. VGGNet拥有5段卷积,每段卷积内有2-3个卷积层,同时每段尾部都会连接一个最大池化层(用来缩小图片)。
  2. 每段内的卷积核数量一样,越后边的段内卷积核数量越多,依次为:64-128-256-512-512
  3. 越深的网络效果越好。(图6-9)
  4. LRN层作用不大(作者结论)
  5. 11的卷积也是很有效的,但是没有33的卷积好,大一些的卷积核可以学习更大的空间特征。

为什么一个段内有多个3*3的卷积层堆叠?

这是个非常有用的设计。2个33的卷积层串联相当于1个55的卷积层,即一个像素会跟周围55的像素产生关联,可以说感受野大小为55。而3个33的卷积层相当于1个77的卷积层。并且,两个33的卷积层的参数比1个55的更少,前者为233=18,后者为155=25。

更重要的是,2个33的卷积层比1个55的卷积层有更多的非线性变换(前者可使用2次ReLu函数,后者只有两次),这使得CNN对特征的学习能力更强。

所以3*3的卷积层堆叠的优点为:

(1)参数量更小
(2)小的卷积层比大的有更多的非线性变换,使得CNN对特征的学习能力更强。

五、GoogLeNet

ImageNet 2014比赛分类任务的冠军,将错误率降低到了6.656%,突出的特点是大大增加了卷积神经网络的深度。

将最后的全连接层都换成了1x1的卷积层,大大加速了训练速率。

5.1 GoogLeNet Inception V1——22层

有没有一种方法,既能保持网络结构的稀疏性,又能利用密集矩阵的高计算性能。大量的文献表明可以将稀疏矩阵聚类为较为密集的子矩阵来提高计算性能,据此论文提出了名为Inception 的结构来实现此目的。

2012年AlexNet做出历史突破以来,直到GoogLeNet出来之前,主流的网络结构突破大致是网络更深(层数),网络更宽(神经元数)。所以大家调侃深度学习为“深度调参”,但是纯粹的增大网络的缺点:

  1. 参数太多,容易过拟合,若训练数据集有限;
  2. 网络越大计算复杂度越大,难以应用;
  3. 网络越深,梯度越往后越容易消失(梯度弥散),难以优化模型

那么解决上述问题的方法当然就是增加网络深度和宽度的同时减少参数,Inception就是在这样的情况下应运而生。

网络结构

Inception 结构的主要思路是怎样用密集成分来近似最优的局部稀疏结构,基本结构如下:
【DL-图像分类】_第8张图片

上图说明:

  1. 采用不同大小的卷积核意味着不同大小的感受野,最后拼接意味着不同尺度特征的融合
  2. 之所以卷积核采用1x1,3x3和5x5,主要是为了方便对齐,设定卷积步长stride=1,只要分别设定padding=0,1,2,那么卷积之后便可以得到相同维度的特征,然后将这些特征就可以直接拼接在一起了。
  3. 文章中说pooling被证明很有效,所以网络结构中也加入了
  4. 网络越到后面,特征越抽象,而且每个特征所涉及的感受野也变大了,因此随着层数的增加,3x3和5x5的比例也要增加。

但是使用5x5的卷积核仍然会带来巨大的计算量,为此文章借鉴NIN,采用1x1的卷积核来进行降维。

例如:上一层的输出为100x100x128,经过具有256个输出的5x5卷积层之后(stride=1,pad=2),输出数据为100x100x256。其中,卷积层的参数为128x5x5x256。假如上一层输出先经过具有32个输出的1x1卷积层,再经过具有256个输出的5x5卷积层,那么最终的输出数据仍为为100x100x256,但卷积参数量已经减少为128x1x1x32 + 32x5x5x256,大约减少了4倍。

例如:上一层的输出为100x100x128,经过具有256个输出的5x5卷积层之后(stride=1,pad=2),输出数据为100x100x256。其中,卷积层的参数为128x5x5x256。假如上一层输出先经过具有32个输出的1x1卷积层,再经过具有256个输出的5x5卷积层,那么最终的输出数据仍为为100x100x256,但卷积参数量已经减少为128x1x1x32 + 32x5x5x256,大约减少了4倍。

卷积层参数数量计算:

输入通道数为K,输出通道数为L,那么卷积核个数为K*L。因为高维卷积计算是多个通道与多个卷积核分别进行二维计算,
所以K个通道会需要K个卷积核,计算之后,合并也就是相加得到一个通道,又因为输出通道为L,所以需要K*L个卷积核。

然后就是如何求解参数数量?

其实很简单,就是卷积核个数乘以卷积核尺寸,para=I*J*K*L。

具体改进后的Inception Module如下
【DL-图像分类】_第9张图片

GoogLeNet Incepetion V1比AlexNet的8层或者VGGNet的19层还要更深。但其计算量只有15亿次浮点运算,同时只有500万的参数量,仅为AlexNet参数量(6000万)的1/12,却可以达到远胜于AlexNet的准确率,可以说是非常优秀并且非常实用的模型。

Inception V1降低参数量的目的有两点

第一,参数越多模型越庞大,需要供模型学习的数据量就越大,而目前高质量的数据非常昂贵;

第二,参数越多,耗费的计算资源也会更大。

Inception V1参数少但效果好的原因除了模型层数更深、表达能力更强外,还有两点

其一,去除了最后的全连接层,用全局平均池化层(即将图片尺寸变为1*1)来取代它。全连接层几乎占据了AlexNet或VGGNet中90%的参数量,而且会引起过拟合,去除全连接层后模型训练更快并且减轻了过拟合。

其二,Inception V1中精心设计的Inception Module提高了参数的利用效率,其结构如上图所示。这一部分也借鉴了Network In Network的思想,形象的解释就是Inception Module本身如同大网络中的一个小网络,其结构可以反复堆叠在一起形成大网络。

Inception Module的基本结构:其中有4个分支:

第一个分支,对输入进行1×1的卷积,这其实也是NIN中提出的一个重要结构。1×1的卷积是一个非常优秀的结构,它可以跨通道组织信息,提高网络的表达能力,同时可以对输出通道升维和降维。
Inception Module的4个分支都用到了1x1的卷积,来进行低成本(计算量比3x3小很多)的跨通道的特征变换

第二个分支,先使用了1x1卷积,然后连接3x3卷积,相当于进行了两次特征变换

第三个分支,先使用1x1卷积,然后连接5x5卷积

第四个分支,3x3最大池化后直接使用1x1卷积

四个分支在最后通过一个聚合操作合并,在输出通道这个维度上聚合。

5.2 GoogLeNet Inception V2

V2和V1的最大的不同就是,V2增加了Batch Normalization。《Batch Normalization:Accelerating Deep Network Training by Reducing Internal CovariateShift》

Inception V2学习了VGGNet,用两个3x3的卷积代替5x5的卷积,用以降低参数量并减轻过拟合,还提出了著名的Batch Normalization方法,该方法是一个很有效的正则化的方法,可以让大型卷积网络的训练速度加快很多倍,同时收敛后的分类准确率也可以得到大幅度的提高。

BN在用于神经网络某层时,会对每一个mini-batch数据的内部进行标准化(normalization)处理,使输出规范化到N(0,1)的正态分布,减少了Internal Covariate Shift(内部神经元分布的改变)。

BN的论文指出,传统的深度神经网络在训练时,每一层的输入的分布都在变化,导致训练变得困难,我们只能使用一个很小的学习速率解决这个问题。而对每一层使用BN之后,我们就可以有效地解决这个问题,学习速率可以增大很多倍,达到之前的准确率所需要的迭代次数只有1/14,训练时间大大缩短。

一般在训练网络时会对数据进行预处理,包括去掉均值、白化操作等,目的是为了加快训练

去均值化
去均值是一种常用的数据处理方式,它是将各个特征值减去其均值,几何上的展现是可以将数据的中心移到坐标原点,python代码为X=X-np.mean(X,axis=0),对于图像来说,就是对每个像素的值都要减去平均值。

白化
白化的方式有很多种,常用的有PCA白化(PCA主成分分析),就是对数据进行PCA操作之后,再进行方差归一化,这样数据基本满足0均值、单位方差、弱相关性。

BN算法:Batch Normalization:批量归一化详解

BN的意义:解决的问题是梯度消失和梯度爆炸的问题

5.3 GoogLeNet Inception V3

学习Factorization into small convolutions的思想,在Inception V2的基础上,将一个二维卷积拆分成两个较小卷积,例如将7×7卷积拆成1×7卷积和7×1卷积,这样做的好处是降低参数量。该paper中指出,通过这种非对称的卷积拆分比对称的拆分为几个相同的小卷积效果更好,可以处理更多,更丰富的空间特征,这就是Inception V3网络结构。
【DL-图像分类】_第10张图片

5.4 GoogLeNet(V1)

论文链接:https://arxiv.org/abs/1409.4842

python代码实现


网络主要结构

GoogLeNet网络有22层深(包括pool层,有27层深),在分类器之前,采用Network in Network中用Averagepool(平均池化)来代替全连接层的思想,而在avg pool之后,还是添加了一个全连接层,是为了大家做finetune(微调)。而无论是VGG还是LeNet、AlexNet,在输出层方面均是采用连续三个全连接层,全连接层的输入是前面卷积层的输出经过reshape得到。据发现,GoogLeNet将fully-connected layer用avg pooling layer代替后,top-1 accuracy 提高了大约0.6%;然而即使在去除了fully-connected layer后,依然必须dropout。

由于全连接网络参数多,计算量大,容易过拟合,所以GoogLeNet没有采用VGG、LeNet、AlexNet三层全连接结构,直接在Inception模块之后使用Average Pool和Dropout方法,不仅起到降维作用,还在一定程度上防止过拟合。

在Dropout层之前添加了一个7×7的Average Pool,一方面是降维,另一方面也是对低层特征的组合。我们希望网络在高层可以抽象出图像全局的特征,那么应该在网络的高层增加卷积核的大小或者增加池化区域的大小,GoogLeNet将这种操作放到了最后的池化过程,前面的Inception模块中卷积核大小都是固定的,而且比较小,主要是为了卷积时的计算方便。

用表格的形式表示GoogLeNet的网络结构如下所示
【DL-图像分类】_第11张图片
上述就是GoogLeNet的结构,可以看出,和AlexNet统一使用5个卷积层、VGG统一使用5个卷积块不同,GoogLeNet在主体卷积部分是卷积层与Inception块混合使用。另外,需要注意一下,在输出层GoogleNet采用全局平均池化,得到的是高和宽均为1的卷积层,而不是通过reshape得到的全连接层。

需要注意的是,上图中 “#3×3reduce” 和 “#5×5reduce” 表示在3×3和5×5卷积之前,使用的降维层中的1×1滤波器的数量。pool proj代表max-pooling后的投影数量(即先max-pooling,再PW降维),所有的reductions(降维)和projections(投影)也都使用激活函数ReLU。

下面就来详细介绍一下GoogLeNet的模型结构

输入

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

第一模块

第一模块采用的是一个单纯的卷积层紧跟一个最大池化层。

卷积层:卷积核大小7×7,步长为2,padding为3,输出通道数64,输出特征图尺寸为(224-7+3*2)/2+1=112.5(向下取整)=112,输出特征图维度为112x112x64,卷积后进行ReLU操作。

池化层:窗口大小3×3,步长为2,输出特征图尺寸为((112 -3)/2)+1=55.5(向上取整)=56,输出特征图维度为56x56x64。

关于卷积和池化中的特征图大小计算方式,可以参考神经网络之多维卷积的那些事

第二模块

第二模块采用2个卷积层,后面跟一个最大池化层。
【DL-图像分类】_第12张图片
卷积层:

  1. 先用64个1x1的卷积核(3x3卷积核之前的降维)将输入的特征图(56x56x64)变为56x56x64,然后进行ReLU操作。参数量是1×1×64*64=4096
  2. 再用卷积核大小3×3,步长为1,padding为1,输出通道数192,进行卷积运算,输出特征图尺寸为(56-3+1*2)/1+1=56,输出特征图维度为56x56x192,然后进行ReLU操作。参数量是3×3×64×192=110592
    第二模块卷积运算总的参数量是110592+4096=114688,即114688/1024=112K。

池化层: 窗口大小3×3,步长为2,输出通道数192,输出为((56 - 3)/2)+1=27.5(向上取整)=28,输出特征图维度为28x28x192。

第三模块(Inception 3a层)

Inception 3a层,分为四个分支,采用不同尺度,图示如下:
【DL-图像分类】_第13张图片
再看下表格结构,来分析和计算吧:
【DL-图像分类】_第14张图片

  1. 使用64个1x1的卷积核,运算后特征图输出为28x28x64,然后RuLU操作。参数量1*1*192*64=12288
  2. 96个1x1的卷积核(3x3卷积核之前的降维)运算后特征图输出为28x28x96,进行ReLU计算,再进行128个3x3的卷积,输出28x28x128。参数量1*1*192*96+3*3*96*128=129024
  3. 16个1x1的卷积核(5x5卷积核之前的降维)将特征图变成28x28x16,进行ReLU计算,再进行32个5x5的卷积,输出28x28x32。参数量1*1*192*16+5*5*16*32=15872
  4. pool层,使用3x3的核,输出28x28x192,然后进行32个1x1的卷积,输出28x28x32.。总参数量1*1*192*32=6144

将四个结果进行连接,对这四部分输出结果的第三维并联,即64+128+32+32=256,最终输出28x28x256。总的参数量是12288+129024+15872+6144=163328,即163328/1024=159.5K,约等于159K。

第三模块(Inception 3b层)

Inception 3b层,分为四个分支,采用不同尺度。

  1. 128个1x1的卷积核,然后RuLU,输出28x28x128
  2. 128个1x1的卷积核(3x3卷积核之前的降维)变成28x28x128,进行ReLU,再进行192个3x3的卷积,输出28x28x192
  3. 32个1x1的卷积核(5x5卷积核之前的降维)变成28x28x32,进行ReLU,再进行96个5x5的卷积,输出28x28x96
  4. pool层,使用3x3的核,输出28x28x256,然后进行64个1x1的卷积,输出28x28x64

将四个结果进行连接,对这四部分输出结果的第三维并联,即128+192+96+64=480,最终输出输出为28x28x480。

第四模块(Inception 4a、4b、4c、4e)

与Inception3a,3b类似
【DL-图像分类】_第15张图片
第五模块(Inception 5a、5b)

与Inception3a,3b类似
在这里插入图片描述
输出层
前面已经多次提到,在输出层GoogLeNet与AlexNet、VGG采用3个连续的全连接层不同,GoogLeNet采用的是全局平均池化层,得到的是高和宽均为1的卷积层,然后添加丢弃概率为40%的Dropout,输出层激活函数采用的是softmax。
在这里插入图片描述
激活函数
GoogLeNet每层使用的激活函数为ReLU激活函数。

辅助分类器
根据实验数据,发现神经网络的中间层也具有很强的识别能力,为了利用中间层抽象的特征,在某些中间层中添加含有多层的分类器。如下图所示,红色边框内部代表添加的辅助分类器。GoogLeNet中共增加了两个辅助的softmax分支,作用有两点,一是为了避免梯度消失,用于向前传导梯度。反向传播时如果有一层求导为0,链式求导结果则为0。二是将中间某一层输出用作分类,起到模型融合作用。最后的loss=loss_2 + 0.3 * loss_1 + 0.3 * loss_0实际测试时,这两个辅助softmax分支会被去掉
【DL-图像分类】_第16张图片
参考:
参考一

六、ResNet

论文见:https://arxiv.org/pdf/1512.03385.pdf

python代码实现


在ResNet网络中有如下几个亮点

  • 提出residual结构(残差结构),并搭建超深的网络结构(突破1000层)
  • 使用Batch Normalization加速训练(丢弃dropout)

在ResNet网络提出之前,传统的卷积神经网络都是通过将一系列卷积层与下采样层进行堆叠得到的。但是当堆叠到一定网络深度时,就会出现两个问题。

  1. 梯度消失或梯度爆炸。
  2. 退化问题(degradation problem)。

在ResNet论文中说通过数据的预处理以及在网络中使用BN(Batch Normalization)层能够解决梯度消失或者梯度爆炸问题。如果不了解BN层可参考这个链接。但是对于退化问题(随着网络层数的加深,效果还会变差,如下图所示)并没有很好的解决办法。
【DL-图像分类】_第17张图片

所以ResNet论文提出了residual结构(残差结构)来减轻退化问题。下图是使用residual结构的卷积网络,可以看到随着网络的不断加深,效果并没有变差,反而变的更好了。
【DL-图像分类】_第18张图片
残差结构(residual)

残差指的是什么?
其中ResNet提出了两种mapping:一种是identity mapping,指的就是下图中”弯弯的曲线”,另一种residual mapping,指的就是除了”弯弯的曲线“那部分,所以最后的输出是 y=F(x)+x

  • identity mapping顾名思义,就是指本身,也就是公式中的x,
  • 而residual mapping指的是“差”,也就是y−x,所以残差指的就是F(x)部分。

下图是论文中给出的两种残差结构。
左边的残差结构是针对层数较少网络,例如ResNet18层和ResNet34层网络。
右边是针对网络层数较多的网络,例如ResNet101,ResNet152等。

为什么深层网络要使用右侧的残差结构呢。
因为,右侧的残差结构能够减少网络参数与运算量。同样输入一个channel为256的特征矩阵,如果使用左侧的残差结构需要大约1170648个参数,但如果使用右侧的残差结构只需要69632个参数。明显搭建深层网络时,使用右侧的残差结构更合适。
【DL-图像分类】_第19张图片
对左侧的残差结构(针对ResNet18/34)进行分析。

如下图所示,该残差结构的主分支是由两层3x3的卷积层组成,而残差结构右侧的连接线是shortcut分支也称捷径分支(注意为了让主分支上的输出矩阵能够与我们捷径分支上的输出矩阵进行相加,必须保证这两个输出特征矩阵有相同的shape)。仔细观察了ResNet34网络结构图,应该能够发现图中会有一些虚线的残差结构。在原论文中作者只是简单说了这些虚线残差结构有降维的作用,并在捷径分支上通过1x1的卷积核进行降维处理。而下图右侧给出了详细的虚线残差结构,注意下每个卷积层的步距stride,以及捷径分支上的卷积核的个数(与主分支上的卷积核个数相同)。
【DL-图像分类】_第20张图片
下面这幅图是原论文给出的不同深度的ResNet网络结构配置,注意表中的残差结构给出了主分支上卷积核的大小与卷积核个数,表中的×N表示将该残差结构重复N次。

可见,ResNet-18/34是进行两层卷积的残差,ResNet-50/101/152是进行三层卷积的残差。ResNet-18/34对应的每个残差块的卷积kernel大小依次是33、33,ResNet-50/101/152对应的每个残差块的卷积kernel大小依次是11、33、1*1。

【DL-图像分类】_第21张图片

18、34层等数字是如何计算出来的:以34层为例,1个卷积(conv1)+3残差块×2个卷积(conv2_x)+4个残差块×2个卷积(conv3_x)+6个残差块×2个卷积(conv4_x)+3个残差块×2个卷积(conv5_x)+最后的1个全连接层=34。这里的层仅指卷积层和全连接层,其它类型的层并没有计算在内。

论文中给出了层数为34的ResNet网络结构,论文截图如下所示:
左侧为VGG-19网络结构;中间为34层的普通网络结构;在此基础上,在层与层之间加入shortcut connections,就将普通网络转换为对应的ResNet网络,即右侧网络结构。与上表中ResNet-34一致。
【DL-图像分类】_第22张图片
右侧ResNet网络,曲线有实线和虚线两种。虚线表示恒等映射x输出的feature map数、width、height与残差F(x)的输出不一致时,x需要进行卷积kernel大小为1*1的运算操作,因为最终F(x)与x要执行”+”操作,即Eltwise操作。GoogLeNet中使用Concat操作。

你可能感兴趣的:(深度学习,深度学习,卷积神经网络,分类,pytorch,python)