VGG——Very Deep Convolutional Networks for Large-Scale Image Recognition
http://noahsnail.com/2017/08/17/2017-8-17-VGG%E8%AE%BA%E6%96%87%E7%BF%BB%E8%AF%91%E2%80%94%E2%80%94%E4%B8%AD%E6%96%87%E7%89%88/
http://blog.csdn.net/sinat_34474705/article/details/72892318
http://blog.csdn.net/whiteinblue/article/details/43560491
http://blog.csdn.net/u011440696/article/details/77756776
http://www.jianshu.com/p/9c6d90e4f20e
http://blog.csdn.net/qq_31531635/article/details/71170861
摘要
在这项工作中,我们研究了卷积网络深度在大规模的图像识别环境下对准确性的影响。我们的主要贡献是使用非常小的(3×3)卷积滤波器架构对网络深度的增加进行了全面评估,这表明通过将深度推到16-19加权层可以实现对现有技术配置的显著改进。这些发现是我们的ImageNet Challenge 2014提交的基础,我们的团队在定位和分类过程中分别获得了第一名和第二名。我们还表明,我们的表示对于其他数据集泛化的很好,在其它数据集上取得了最好的结果。我们使我们的两个性能最好的ConvNet模型可公开获得,以便进一步研究计算机视觉中深度视觉表示的使用。
1 引言
卷积网络(ConvNets)近来在大规模图像和视频识别方面取得了巨大成功(Krizhevsky等,2012;Zeiler&Fergus,2013;Sermanet等,2014;Simonyan&Zisserman,2014)由于大的公开图像存储库,例如ImageNet,以及高性能计算系统的出现,例如GPU或大规模分布式集群(Dean等,2012),使这成为可能。特别是,在深度视觉识别架构的进步中,ImageNet大型视觉识别挑战(ILSVRC)(Russakovsky等,2014)发挥了重要作用,它已经成为几代大规模图像分类系统的测试台,从高维度浅层特征编码(Perronnin等,2010)(ILSVRC-2011的获胜者)到深层ConvNets(Krizhevsky等,2012)(ILSVRC-2012的获奖者)。
随着ConvNets在计算机视觉领域越来越商品化,为了达到更好的准确性,已经进行了许多尝试来改进Krizhevsky等人(2012)最初的架构。例如,ILSVRC-2013(Zeiler&Fergus,2013;Sermanet等,2014)表现最佳的提交使用了更小的感受窗口尺寸和更小的第一卷积层步长。另一条改进措施在整个图像和多个尺度上对网络进行密集地训练和测试(Sermanet等,2014;Howard,2014)。在本文中,我们解决了ConvNet架构设计的另一个重要方面——其深度。为此,我们修正了架构的其它参数,并通过添加更多的卷积层来稳定地增加网络的深度,这是可行的,因为在所有层中使用非常小的(3×3)卷积滤波器。
因此,我们提出了更为精确的ConvNet架构,不仅可以在ILSVRC分类和定位任务上取得的最佳的准确性,而且还适用于其它的图像识别数据集,它们可以获得优异的性能,即使使用相对简单流程的一部分(例如,通过线性SVM分类深度特征而不进行微调)。我们发布了两款表现最好的模型1,以便进一步研究。
本文的其余部分组织如下。在第2节,我们描述了我们的ConvNet配置。图像分类训练和评估的细节在第3节,并在第4节中在ILSVRC分类任务上对配置进行了比较。第5节总结了论文。为了完整起见,我们还将在附录A中描述和评估我们的ILSVRC-2014目标定位系统,并在附录B中讨论了非常深的特征在其它数据集上的泛化。最后,附录C包含了主要的论文修订列表。
2. ConvNet配置
为了衡量ConvNet深度在公平环境中所带来的改进,我们所有的ConvNet层配置都使用相同的规则,灵感来自Ciresan等(2011);Krizhevsky等人(2012年)。在本节中,我们首先描述我们的ConvNet配置的通用设计(第2.1节),然后详细说明评估中使用的具体配置(第2.2节)。最后,我们的设计选择将在2.3节进行讨论并与现有技术进行比较。
在训练期间,我们的ConvNet的输入是固定大小的224×224 RGB图像。我们唯一的预处理是从每个像素中减去在训练集上计算的RGB均值。图像通过一堆卷积(conv.)层,我们使用感受野很小的滤波器:3×3(这是捕获左/右,上/下,中心概念的最小尺寸)。在其中一种配置中,我们还使用了1×1卷积滤波器,可以看作输入通道的线性变换(后面是非线性)。卷积步长固定为1个像素;卷积层输入的空间填充要满足卷积之后保留空间分辨率,即3×3卷积层的填充为1个像素。空间池化由五个最大池化层进行,这些层在一些卷积层之后(不是所有的卷积层之后都是最大池化)。在2×2像素窗口上进行最大池化,步长为2。
一堆卷积层(在不同架构中具有不同深度)之后是三个全连接(FC)层:前两个每个都有4096个通道,第三个执行1000维ILSVRC分类,因此包含1000个通道(一个通道对应一个类别)。最后一层是soft-max层。所有网络中全连接层的配置是相同的。
所有隐藏层都配备了修正(ReLU(Krizhevsky等,2012))非线性。我们注意到,我们的网络(除了一个)都不包含局部响应规范化(LRN)(Krizhevsky等,2012):将在第4节看到,这种规范化并不能提高在ILSVRC数据集上的性能,但增加了内存消耗和计算时间。在应用的地方,LRN层的参数是(Krizhevsky等,2012)的参数。
2.2 配置
本文中评估的ConvNet配置在表1中列出,每列一个。接下来我们将按网站名称(A-E)来提及网络。所有配置都遵循2.1节提出的通用设计,并且仅是深度不同:从网络A中的11个加权层(8个卷积层和3个FC层)到网络E中的19个加权层(16个卷积层和3个FC层)。卷积层的宽度(通道数)相当小,从第一层中的64开始,然后在每个最大池化层之后增加2倍,直到达到512。
表1:ConvNet配置(以列显示)。随着更多的层被添加,配置的深度从左(A)增加到右(E)(添加的层以粗体显示)。卷积层参数表示为“conv⟨感受野大小⟩-通道数⟩”。为了简洁起见,不显示ReLU激活功能。
在表2中,我们报告了每个配置的参数数量。尽管深度很大,我们的网络中权重数量并不大于具有更大卷积层宽度和感受野的较浅网络中的权重数量(144M的权重在(Sermanet等人,2014)中)。
表2:参数数量(百万级别)
2.3 讨论
我们的ConvNet配置与ILSVRC-2012(Krizhevsky等,2012)和ILSVRC-2013比赛(Zeiler&Fergus,2013;Sermanet等,2014)表现最佳的参赛提交中使用的ConvNet配置有很大不同。不是在第一卷积层中使用相对较大的感受野(例如,在(Krizhevsky等人,2012)中的11×11,步长为4,或在(Zeiler&Fergus,2013;Sermanet等,2014)中的7×7,步长为2),我们在整个网络使用非常小的3×3感受野,与输入的每个像素(步长为1)进行卷积。很容易看到两个3×3卷积层堆叠(没有空间池化)有5×5的有效感受野;三个这样的层具有7×7的有效感受野。那么我们获得了什么?例如通过使用三个3×3卷积层的堆叠来替换单个7×7层。首先,我们结合了三个非线性修正层,而不是单一的,这使得决策函数更具判别性。其次,我们减少参数的数量:假设三层3×3卷积堆叠的输入和输出有CC个通道,堆叠卷积层的参数为3(32C2)=27C23(32C2)=27C2个权重;同时,单个7×7卷积层将需要72C2=49C272C2=49C2个参数,即参数多81%。这可以看作是对7×7卷积滤波器进行正则化,迫使它们通过3×3滤波器(在它们之间注入非线性)进行分解。
结合1×1卷积层(配置C,表1)是增加决策函数非线性而不影响卷积层感受野的一种方式。即使在我们的案例下,1×1卷积基本上是在相同维度空间上的线性投影(输入和输出通道的数量相同),由修正函数引入附加的非线性。应该注意的是1×1卷积层最近在Lin等人(2014)的“Network in Network”架构中已经得到了使用。
Ciresan等人(2011)以前使用小尺寸的卷积滤波器,但是他们的网络深度远远低于我们的网络,他们并没有在大规模的ILSVRC数据集上进行评估。Goodfellow等人(2014)在街道号识别任务中采用深层ConvNets(11个权重层),显示出增加的深度导致了更好的性能。GooLeNet(Szegedy等,2014),ILSVRC-2014分类任务的表现最好的项目,是独立于我们工作之外的开发的,但是类似的是它是基于非常深的ConvNets(22个权重层)和小卷积滤波器(除了3×3,它们也使用了1×1和5×5卷积)。然而,它们的网络拓扑结构比我们的更复杂,并且在第一层中特征图的空间分辨率被更积极地减少,以减少计算量。正如将在第4.5节显示的那样,我们的模型在单网络分类精度方面胜过Szegedy等人(2014)。
3 分类框架
在上一节中,我们介绍了我们的网络配置的细节。在本节中,我们将介绍分类ConvNet训练和评估的细节。
3.1 训练
ConvNet训练过程通常遵循Krizhevsky等人(2012)(除了从多尺度训练图像中对输入裁剪图像进行采样外,如下文所述)。也就是说,通过使用具有动量的小批量梯度下降(基于反向传播(LeCun等人,1989))优化多项式逻辑回归目标函数来进行训练。批量大小设为256,动量为0.9。训练通过权重衰减(L2惩罚乘子设定为5·10−45·10−4)进行正则化,前两个全连接层执行丢弃正则化(丢弃率设定为0.5)。学习率初始设定为10−210−2,然后当验证集准确率停止改善时,减少10倍。学习率总共降低3次,学习在37万次迭代后停止(74个epochs)。我们推测,尽管与(Krizhevsky等,2012)相比我们的网络参数更多,网络的深度更大,但网络需要更小的epoch就可以收敛,这是由于(a)由更大的深度和更小的卷积滤波器尺寸引起的隐式正则化,(b)某些层的预初始化。
网络权重的初始化是重要的,因为由于深度网络中梯度的不稳定,不好的初始化可能会阻碍学习。为了规避这个问题,我们开始训练配置A(表1),足够浅以随机初始化进行训练。然后,当训练更深的架构时,我们用网络A的层初始化前四个卷积层和最后三个全连接层(中间层被随机初始化)。我们没有减少预初始化层的学习率,允许他们在学习过程中改变。对于随机初始化(如果应用),我们从均值为0和方差为10−210−2的正态分布中采样权重。偏置初始化为零。值得注意的是,在提交论文之后,我们发现可以通过使用Glorot&Bengio(2010)的随机初始化程序来初始化权重而不进行预训练。
训练图像大小。令S是等轴归一化的训练图像的最小边,ConvNet输入从S中裁剪(我们也将S称为训练尺度)。虽然裁剪尺寸固定为224×224,但原则上S可以是不小于224的任何值:对于S=224S=224,裁剪图像将捕获整个图像的统计数据,完全扩展训练图像的最小边;对于S»224S»224,裁剪图像将对应于图像的一小部分,包含小对象或对象的一部分。
我们考虑两种方法来设置训练尺度S。第一种是修正对应单尺度训练的S(注意,采样裁剪图像中的图像内容仍然可以表示多尺度图像统计)。在我们的实验中,我们评估了以两个固定尺度训练的模型:S=256S=256(已经在现有技术中广泛使用(Krizhevsky等人,2012;Zeiler&Fergus,2013;Sermanet等,2014))和S=384S=384。给定ConvNet配置,我们首先使用S=256S=256来训练网络。为了加速S=384S=384网络的训练,用S=256S=256预训练的权重来进行初始化,我们使用较小的初始学习率10−310−3。
设置S的第二种方法是多尺度训练,其中每个训练图像通过从一定范围[Smin,Smax][Smin,Smax](我们使用Smin=256Smin=256和Smax=512Smax=512)随机采样S来单独进行归一化。由于图像中的目标可能具有不同的大小,因此在训练期间考虑到这一点是有益的。这也可以看作是通过尺度抖动进行训练集增强,其中单个模型被训练在一定尺度范围内识别对象。为了速度的原因,我们通过对具有相同配置的单尺度模型的所有层进行微调,训练了多尺度模型,并用固定的S=384S=384进行预训练。
3.2 测试
在测试时,给出训练的ConvNet和输入图像,它按以下方式分类。首先,将其等轴地归一化到预定义的最小图像边,表示为Q(我们也将其称为测试尺度)。我们注意到,Q不一定等于训练尺度S(正如我们在第4节中所示,每个S使用Q的几个值会导致性能改进)。然后,网络以类似于(Sermanet等人,2014)的方式密集地应用于归一化的测试图像上。即,全连接层首先被转换成卷积层(第一FC层转换到7×7卷积层,最后两个FC层转换到1×1卷积层)。然后将所得到的全卷积网络应用于整个(未裁剪)图像上。结果是类得分图的通道数等于类别的数量,以及取决于输入图像大小的可变空间分辨率。最后,为了获得图像的类别分数的固定大小的向量,类得分图在空间上平均(和池化)。我们还通过水平翻转图像来增强测试集;将原始图像和翻转图像的soft-max类后验进行平均,以获得图像的最终分数。
由于全卷积网络被应用在整个图像上,所以不需要在测试时对采样多个裁剪图像(Krizhevsky等,2012),因为它需要网络重新计算每个裁剪图像,这样效率较低。同时,如Szegedy等人(2014)所做的那样,使用大量的裁剪图像可以提高准确度,因为与全卷积网络相比,它使输入图像的采样更精细。此外,由于不同的卷积边界条件,多裁剪图像评估是密集评估的补充:当将ConvNet应用于裁剪图像时,卷积特征图用零填充,而在密集评估的情况下,相同裁剪图像的填充自然会来自于图像的相邻部分(由于卷积和空间池化),这大大增加了整个网络的感受野,因此捕获了更多的上下文。虽然我们认为在实践中,多裁剪图像的计算时间增加并不足以证明准确性的潜在收益,但作为参考,我们还在每个尺度使用50个裁剪图像(5×5规则网格,2次翻转)评估了我们的网络,在3个尺度上总共150个裁剪图像,与Szegedy等人(2014)在4个尺度上使用的144个裁剪图像。
3.3 实现细节
我们的实现来源于公开的C++ Caffe工具箱(Jia,2013)(2013年12月推出),但包含了一些重大的修改,使我们能够对安装在单个系统中的多个GPU进行训练和评估,也能训练和评估在多个尺度上(如上所述)的全尺寸(未裁剪)图像。多GPU训练利用数据并行性,通过将每批训练图像分成几个GPU批次,每个GPU并行处理。在计算GPU批次梯度之后,将其平均以获得完整批次的梯度。梯度计算在GPU之间是同步的,所以结果与在单个GPU上训练完全一样。
最近提出了更加复杂的加速ConvNet训练的方法(Krizhevsky,2014),它们对网络的不同层之间采用模型和数据并行,我们发现我们概念上更简单的方案与使用单个GPU相比,在现有的4-GPU系统上已经提供了3.75倍的加速。在配备四个NVIDIA Titan Black GPU的系统上,根据架构训练单个网络需要2-3周时间。
4 分类实验
数据集。在本节中,我们介绍了描述的ConvNet架构(用于ILSVRC 2012-2014挑战)在ILSVRC-2012数据集上实现的图像分类结果。数据集包括1000个类别的图像,并分为三组:训练(130万张图像),验证(5万张图像)和测试(留有类标签的10万张图像)。使用两个措施评估分类性能:top-1和top-5错误率。前者是多类分类误差,即不正确分类图像的比例;后者是ILSVRC中使用的主要评估标准,并且计算为图像真实类别在前5个预测类别之外的图像比例。
对于大多数实验,我们使用验证集作为测试集。在测试集上也进行了一些实验,并将其作为ILSVRC-2014竞赛(Russakovsky等,2014)“VGG”小组的输入提交到了官方的ILSVRC服务器。
4.1 单尺度评估
我们首先评估单个ConvNet模型在单尺度上的性能,其层结构配置如2.2节中描述。测试图像大小设置如下:对于固定S的Q=SQ=S,对于抖动S∈[Smin,Smax]S∈[Smin,Smax],Q=0.5(Smin+Smax)Q=0.5(Smin+Smax)。结果如表3所示。
表3:在单测试尺度的ConvNet性能
首先,我们注意到,使用局部响应归一化(A-LRN网络)在没有任何归一化层的情况下,对模型A没有改善。因此,我们在较深的架构(B-E)中不采用归一化。
第二,我们观察到分类误差随着ConvNet深度的增加而减小:从A中的11层到E中的19层。值得注意的是,尽管深度相同,配置C(包含三个1×1卷积层)比在整个网络层中使用3×3卷积的配置D更差。这表明,虽然额外的非线性确实有帮助(C优于B),但也可以通过使用具有非平凡感受野(D比C好)的卷积滤波器来捕获空间上下文。当深度达到19层时,我们架构的错误率饱和,但更深的模型可能有益于较大的数据集。我们还将网络B与具有5×5卷积层的浅层网络进行了比较,浅层网络可以通过用单个5×5卷积层替换B中每对3×3卷积层得到(其具有相同的感受野如第2.3节所述)。测量的浅层网络top-1错误率比网络B的top-1错误率(在中心裁剪图像上)高7%,这证实了具有小滤波器的深层网络优于具有较大滤波器的浅层网络。
最后,训练时的尺度抖动(S∈[256;512]S∈[256;512])得到了与固定最小边(S=256S=256或S=384S=384)的图像训练相比更好的结果,即使在测试时使用单尺度。这证实了通过尺度抖动进行的训练集增强确实有助于捕获多尺度图像统计。
4.2 多尺度评估
在单尺度上评估ConvNet模型后,我们现在评估测试时尺度抖动的影响。它包括在一张测试图像的几个归一化版本上运行模型(对应于不同的Q值),然后对所得到的类别后验进行平均。考虑到训练和测试尺度之间的巨大差异会导致性能下降,用固定S训练的模型在三个测试图像尺度上进行了评估,接近于训练一次:Q=S−32,S,S+32Q=S−32,S,S+32。同时,训练时的尺度抖动允许网络在测试时应用于更广的尺度范围,所以用变量S∈[Smin;Smax]S∈[Smin;Smax]训练的模型在更大的尺寸范围Q = {S_{min}, 0.5(S_{min} + S_{max}), S_{max}Q = {S_{min}, 0.5(S_{min} + S_{max}), S_{max}上进行评估。
表4中给出的结果表明,测试时的尺度抖动导致了更好的性能(与在单一尺度上相同模型的评估相比,如表3所示)。如前所述,最深的配置(D和E)执行最佳,并且尺度抖动优于使用固定最小边S的训练。我们在验证集上的最佳单网络性能为24.8%/7.5% top-1/top-5的错误率(在表4中用粗体突出显示)。在测试集上,配置E实现了7.3% top-5的错误率。
表4:在多个测试尺度上的ConvNet性能
4.3 多裁剪图像评估
在表5中,我们将稠密ConvNet评估与多裁剪图像评估进行比较(细节参见第3.2节)。我们还通过平均其soft-max输出来评估两种评估技术的互补性。可以看出,使用多裁剪图像表现比密集评估略好,而且这两种方法确实是互补的,因为它们的组合优于其中的每一种。如上所述,我们假设这是由于卷积边界条件的不同处理。
表5:ConvNet评估技术比较。在所有的实验中训练尺度S从[256;512]采样,三个测试适度Q考虑:{256, 384, 512}。
4.4 卷积网络融合
到目前为止,我们评估了ConvNet模型的性能。在这部分实验中,我们通过对soft-max类别后验进行平均,结合了几种模型的输出。由于模型的互补性,这提高了性能,并且在了2012年(Krizhevsky等,2012)和2013年(Zeiler&Fergus,2013;Sermanet等,2014)ILSVRC的顶级提交中使用。
结果如表6所示。在ILSVRC提交的时候,我们只训练了单规模网络,以及一个多尺度模型D(仅在全连接层进行微调而不是所有层)。由此产生的7个网络组合具有7.3%的ILSVRC测试误差。在提交之后,我们考虑了只有两个表现最好的多尺度模型(配置D和E)的组合,它使用密集评估将测试误差降低到7.0%,使用密集评估和多裁剪图像评估将测试误差降低到6.8%。作为参考,我们表现最佳的单模型达到7.1%的误差(模型E,表5)。
表6:多个卷积网络融合结果
4.5 与最新技术比较
最后,我们在表7中与最新技术比较我们的结果。在ILSVRC-2014挑战的分类任务(Russakovsky等,2014)中,我们的“VGG”团队获得了第二名,
使用7个模型的组合取得了7.3%测试误差。提交后,我们使用2个模型的组合将错误率降低到6.8%。
表7:在ILSVRC分类中与最新技术比较。我们的方法表示为“VGG”。报告的结果没有使用外部数据。
从表7可以看出,我们非常深的ConvNets显著优于前一代模型,在ILSVRC-2012和ILSVRC-2013竞赛中取得了最好的结果。我们的结果对于分类任务获胜者(GoogLeNet具有6.7%的错误率)也具有竞争力,并且大大优于ILSVRC-2013获胜者Clarifai的提交,其使用外部训练数据取得了11.2%的错误率,没有外部数据则为11.7%。这是非常显著的,考虑到我们最好的结果是仅通过组合两个模型实现的——明显少于大多数ILSVRC提交。在单网络性能方面,我们的架构取得了最好节果(7.0%测试误差),超过单个GoogLeNet 0.9%。值得注意的是,我们并没有偏离LeCun(1989)等人经典的ConvNet架构,但通过大幅增加深度改善了它。
5 结论
在这项工作中,我们评估了非常深的卷积网络(最多19个权重层)用于大规模图像分类。已经证明,表示深度有利于分类精度,并且深度大大增加的传统ConvNet架构(LeCun等,1989;Krizhevsky等,2012)可以实现ImageNet挑战数据集上的最佳性能。在附录中,我们还显示了我们的模型很好地泛化到各种各样的任务和数据集上,可以匹敌或超越更复杂的识别流程,其构建围绕不深的图像表示。我们的结果再次证实了深度在视觉表示中的重要性。
致谢
这项工作得到ERC授权的VisRec编号228180的支持.我们非常感谢NVIDIA公司捐赠GPU为此研究使用。
==============================================================================================================================================
网络结构
模型结构中的一些细节说明:
- 输入均是裁剪过的224*224大小的RGB图片,并经过去均值处理。
- 卷积层中卷积核大小均是3*3,步长为1(stride = 1),补1圈0 (pad = 1)。
- 池化层均采用最大池化(max pooling),但不是所有的卷积层都有池化层,池化窗口为2*2,步长为2,即采用的是不重叠池化。
- 所有隐含层后都配有有ReLU层
- 参数数量(见下表):
选用3*3卷积核代替大卷积核的好处:
2个3*3的卷积核串联和用一个5*5的卷积核有相同的感知野,3个3*3的卷积核串联和用一个7*7的卷积核有相同的感知野。但前者相比于后者有更少的参数。
举个简单的例子,假设输入特征图(feature map)的大小为32*32*3(宽 * 高 * 通道数):
case 1: 采用1个5*5的卷积核,stride = 1, pad=2, 输出特征图的大小等于: (32+2∗pad−5)/1+1=32,参数的数量为3∗(5∗5)=75个(每个通道25个,共3个通道);
case 2: 采用2个3*3的卷积核,stride = 1, pad=1, 第一次卷积后特征图大小等于:(32+2∗pad−3)/1+1=32,第二次卷积输出特征图的大小等于: (32+2∗pad−3)/1+1=32,总参数的数量为2∗3∗(3∗3)=54个(每个通道9个,共3个通道,2个卷积层),比单独使用一个5*5的卷积核少了21个。
模型训练
除了从多尺度的训练图像中进行采样,其他基本和AlexNet模型的训练方法一致:
- 数据集扩充(data aumentation): 随机裁剪(crop)、水平翻转(horizontal flips)、RGB颜色变化(color shift)
- 训练采用小批量梯度下降法加上动量(mini-batch stochastic gradient descent + momentum),batch size = 256, momentum = 0.9;
- 正则化方法采用weight decay(L2罚函数乘子设为0.0005)和dropout(丢弃率设为0.5);
- 初始学习率(learning rate)为0.001,当在验证集上的准确率不再提高是学习率变为原来的0.1倍,一共降低了3次;
- 总迭代次数为370k (74 epochs), epochs指训练集完整遍历的次数
- 采用2种设置训练图像大小方法: (1)固定训练集图片大小,如256*256和384*384;(2)多尺度训练,让训练集的大小在一个范围内随机变化,如S∈[Smin,Smax]=[256,512],具体可以看论文。
模型测试
在测试阶段,首先选定一个测试集图片大小Q,然后在这个图片上应用训练好的卷积网络,在最后一个卷积阶段产生未经池化的特征图,然后利用滑动窗口的方法,每种池化窗口产生一个分类输出,然后融合各个结果,得到最终分类。这样做相对于取10个图片块的好处是更加高效,因为只需计算一次卷积过程。
=========================================================================================================================
一些理解和困惑
感觉本文在网络探讨阶段和博文9中探索最优网络比较类似;都是首先提出一个结果不错的基础网络A,然后在网络A上进行一些列的修改,一步一步地提高网络性能,进而探索好的网络设计应该是什么样的;博文9平衡网络各个因素探讨的方式比本文比计较复杂度情况下增加深度,更加精细。而且两篇文章的关于深度的结论相同,深度可以提升结果,但是深度会饱和。
这里最大的疑问就是他们的网络A是怎么提来的。
博文9中的A结构:
Input(224,224,3)→64F(7,7,3,s=2) →max-p(3,3,3)→128F(5,5,64) →max-p(2,2,2) →256F(3,3,128)→256F(3,3,256)→256F(3,3,256)→spp(6*6,3*3,2*2,1*1)→4096fc→4096fc→softmax
感觉博文9的结构借鉴了Alex-net,ZF-net和本文的VGG,例如这种三段式结构是从瘦身版的Alex-net和ZF-net中来的,第一个卷积层有64个filter而不是96个,感觉是借鉴了本文第一卷积层的结构;还有就是可能依据本文或OverFeat中剔除了LRN。
但是本文的结构就找不到关系了, 5阶段,filter的个数尺寸,网络结构等64-128-256-512-512;使用3*3小filter作者已经解释了原因,但是这个关键的网络结构作者并没有给出具体的设计依据,而是直接给出了结果;感觉一个是凭借经验,再有就是凭借实验;结合博文9中的观点,感觉VGG网络还可以利用其中层析替换思想来提高分类结果。
里一个困惑,就是“PCR比SCR结果好,这个和OverFeat的结果相反”;OverFeat中在三scale下 SCR-vs-PCR为31.3-vs-44.1;SCR要明显好于PCR,OverFeat作者的解释是PCR顶层有更多的回归函数,继而有更多的参数,而每个类别的训练样本有限,导致每个类别的回归函数不能够很好的训练;但是本文作者的网络中PCR明显好于SCR,训练样本并没有增多,现在感觉OverFeat这种每类训练样本少的解释合理性有待商榷;此外网络结构不同感觉是两个结果区别的关键,除卷积提取阶段不同外;全连接层的结构也不同OverFeat网络是4096-1024-regression;本文的网络是4096-4096-regression;从对比来看造成这种差距的原因估计是网络结果上的问题;但是这个可以解释为什么本文的结果比OverFeat的结果好,如果用网络结构来解释PCR比SCR好,感觉有些牵强。所以感觉PCR和SCR两种预测bounding box方法的影响因素,还是有些不明白。“还有一个不同的地方就是在上面的测试中,本文给出了图片真正的分类,然后更具真是的类比,预测bounding box;而不是采用先预测分类,在预测bounding box的方法” 。
==============================================================================================================================
这是卷积神经网络发展的一些主要网络
LeNet(3个卷积层+2个降采样层+1个全连接层)CNN雏形
AlexNet (5个卷积层+3个全连接层+1个softmax层
本文所讨论的VGG就是基于LeNet、AlexNet提出的更深的卷积神经网络
VGG主要采用增加卷积层的方法来加深网络,结果发现深度越深,网络学习能力越好,分类能力越强。当深度增加到16-19层时,识别效果有较大提升,即VGG-16,VGG-19。
在ILSVRC2014竞赛中定位第一,分类第二(第一是GoogleNet)。
将卷积层的概念提升到了卷积group概念上,每个卷积group中含有几层卷积层,不再像AlexNet中5个卷积层,而是5个卷积group组合,将AlexNet的8层深度推到了16-19层。
网络A是怎么提出来的并不知道?
文章中只是详细说明了使用3*3filter的原因,至于层数,阶段数,特征数的设计缘由,并没有说明?
=========================================================================================================================================
VGG结构

我们就看D(VGG16)和E(VGG19)好了。因为前面的网络效果没有D和E的效果好,而且比起D和E来讲不够简洁。
此处有一个和AlexNet的对比。我是连接
相同点
1.最后三层FC层(Fully Connected全连接层)结构相同。
2.都分成五层(组)。
3.每层和每层之间用pooling层分开。
不同点
1.AlexNet每层仅仅含有一个Convolution层,filter的大小7x7(很大);而VGG每层含有多个(2~4)个Convolution层,filter的大小是3x3(最小)。很明显,VGG是在模仿Alex的结构,然而它通过降低filter的大小,增加层数来达到同样的效果。我提出我的一个对这种模仿的一种我自己的理解。因为不是论文中讲到,仅仅是我自己的理解,仅供大家参考。
作者在论文中说了一句
"This can be seen as imposing a regularisation on the 7 × 7 conv. filters, forcing them to have a decomposition through the 3 × 3 filters"
他说7x7 filter可以被分解成若干个3x3的filter的叠加。
类比一下n维空间的向量x,x的正交分解
x = x1(1, 0, 0, ....) + x2(0, 1, 0, ...) + x3(0, 0, 1,...) + ... + xn(0, 0, 0, ..., 1)
每一组的每一层的filter被类比成n维欧几里得空间的基底。
若VGG的一组含有3层3x3的filter,则我们则假设一个7x7的filter可以被分解成3种“正交”的3x3的filter。
作者原文:First, we incorporate three non-linearrectification layers instead of a single one, which makes the decision function more discriminative.Second, we decrease the number of parameters: assuming that both the input and the output of athree-layer 3 × 3 convolution stack has C channels, the stack is parametrised by 3 32C^2 = 27C^2weights; at the same time, a single 7 × 7 conv. layer would require 72C^2 = 49C^2
2.AlexNet的Channel明显小于VGG。猜测VGG的之所以能够达到更高的精准性,源自于更多的Channel数。而由于filter size的减小,channel可以大幅度增加,更多的信息可以被提取。
训练过程
此部分没有很多时间来看,据说训练这个网络需要很多的trick和很长的时间。此部分待我日后遇到再仔细看。毕竟自己没时间出来的东西写出来也不太确定。
作者:voidrank
链接:http://www.jianshu.com/p/9c6d90e4f20e
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
==============================================================================================================================================================================
为了在公平的原则下探究网络深度对模型精确度的影响,所有卷积层有相同的配置,即卷积核大小为3x3,步长为1,填充为1;共有5个最大池化层,大小都为2x2,步长为2;共有三个全连接层,前两层都有4096通道,第三层共1000路及代表1000个标签类别;最后一层为softmax层;所有隐藏层后都带有ReLU非线性激活函数;经过实验证明,AlexNet中提出的局部响应归一化(LRN)对性能提升并没有什么帮助,而且还浪费了内存的计算的损耗。
VGGNet网络框图,从左至右每一列代表着深度增加的不同的模型,从上至下代表模型的深度,其中conv<滤波器大小>-<通道数>,至于为什么用3x3的滤波器尺寸,是因为这是能捕捉到各个方向的最小尺寸了,如ZFNet中所说,由于第一层中往往有大量的高频和低频信息,却没有覆盖到中间的频率信息,且步长过大,容易引起大量的混叠,因此滤波器尺寸和步长要尽量小;这里使用1x1的卷积模版是因为1x1就相当于可以看作是一种对输入通道进行线性变换的操作(增加决策函数的非线性且不会影响到感受野的大小)。
上面第二个图为各个模型中用到的参数分析图,可以看到随着层数的增加A-E,参数增加的并不是很多,因此也分析出层数的增加可以提升性能的同时,也不会在参数量的计算存储损耗上,有非常多的增加。
之前的网络都用7x7,11x11等比较大的卷积核,现在全用3x3不会有什么影响吗?
实际上,一个5x5可以用两个3x3来近似代替,一个7x7可以用三个3x3的卷积核来代替,不仅提升了判别函数的识别能力,而且还减少了参数;如3个3x3的卷积核,通道数为C,则参数为3x(3x3xCxC)=27C2,而一个7x7的卷积核,通道数也为C,则参数为(7x7xCxC)=49C2。
而1x1卷积层的合并是一种增加决策函数的非线性的方式,而且还没有影响到卷积层的感受野。
训练:
训练使用加动量的小批基于反向传播的梯度下降法来优化多项逻辑回归目标。批数量为256,动量为0.9,权值衰减参数为5x10−4,在前两个全连接层使用dropout为0.5,学习率为0.01,且当验证集停止提升时以10的倍数衰减,同时,初始化权重取样于高斯分布N(0,0.01),偏置项初始化为0。
为了获得初始化的224x224大小的图片,通过在每张图片在每次随机梯度下降SGB时进行一次裁减,为了更进一步的增加训练集,对每张图片进行水平翻转以及进行随机RGB色差调整。
初始对原始图片进行裁剪时,原始图片的最小边不宜过小,这样的话,裁剪到224x224的时候,就相当于几乎覆盖了整个图片,这样对原始图片进行不同的随机裁剪得到的图片就基本上没差别,就失去了增加数据集的意义,但同时也不宜过大,这样的话,裁剪到的图片只含有目标的一小部分,也不是很好。
针对上述裁剪的问题,提出的两种解决办法:
(1) 固定最小遍的尺寸为256
(2) 随机从[256,512]的确定范围内进行抽样,这样原始图片尺寸不一,有利于训练,这个方法叫做尺度抖动scal jittering,有利于训练集增强。 训练时运用大量的裁剪图片有利于提升识别精确率。
测试:
测试图片的尺寸不一定要与训练图片的尺寸相同,且不需要裁剪。
测试的时候,首先将全连接层转换到卷积层,第一个全连接层转换到一个7x7的卷积层,后面两个转换到1x1的卷积层,这不仅让全连接网应用到整个未裁剪的整个原始图像上,而且得到一个类别的得分图,其通道数等于类别数,还有一个决定与输入图片尺寸的可变空间分辨率。为了获得固定尺寸的图片的得分图,运用原始图片的softmax的后验概率以及其水平翻转的平均来获得。
下图为各个模型运用在ILSVRC-2012数据集上的结果(测试图片尺寸固定为一个值时)。
更直接地看即
若设置测试图片的尺寸不一,利用尺度抖动scale jittering的方法取三个值,然后取结果的平均值。
可以看到结果稍好于前者测试图片采用单一尺寸的效果。
当取训练图片S利用尺度抖动的方法范围为[256;512],测试图片也利用尺度抖动取256,384,512三个值进行分类结果平均值,然后探究对测试图片进行多裁剪估计的方法,即对三个尺度上每个尺度进行50次裁剪(5x5大小的正常网格,并进行两次翻转)即总共150次裁剪的效果图,如下。
可以看到这个效果比之前两个效果更进一步,说明多尺度裁剪也起了一定好的作用。
最后将多个模型进行合并进一步得到了更好的效果,并在ILSVRC比赛上拿到了第二的成绩。
==============================================================================================================================================================================
http://blog.csdn.net/sunbaigui/article/details/39938097
[caffe]深度学习之图像分类模型AlexNet解读
在imagenet上的图像分类challenge上Alex提出的alexnet网络结构模型赢得了2012届的冠军。要研究CNN类型DL网络模型在图像分类上的应用,就逃不开研究alexnet,这是CNN在图像分类上的经典模型(DL火起来之后)。
在DL开源实现caffe的model样例中,它也给出了alexnet的复现,具体网络配置文件如下https://github.com/BVLC/caffe/blob/master/models/bvlc_reference_caffenet/train_val.prototxt:
接下来本文将一步步对该网络配置结构中各个层进行详细的解读(训练阶段):
1. conv1阶段DFD(data flow diagram):
2. conv2阶段DFD(data flow diagram):
3. conv3阶段DFD(data flow diagram):
4. conv4阶段DFD(data flow diagram):
5. conv5阶段DFD(data flow diagram):
6. fc6阶段DFD(data flow diagram):
7. fc7阶段DFD(data flow diagram):
8. fc8阶段DFD(data flow diagram):
各种layer的operation更多解释可以参考http://caffe.berkeleyvision.org/tutorial/layers.html
从计算该模型的数据流过程中,该模型参数大概5kw+。
caffe的输出中也有包含这块的内容日志,详情如下:
- I0721 10:38:15.326920 4692 net.cpp:125] Top shape: 256 3 227 227 (39574272)
- I0721 10:38:15.326971 4692 net.cpp:125] Top shape: 256 1 1 1 (256)
- I0721 10:38:15.326982 4692 net.cpp:156] data does not need backward computation.
- I0721 10:38:15.327003 4692 net.cpp:74] Creating Layer conv1
- I0721 10:38:15.327011 4692 net.cpp:84] conv1 <- data
- I0721 10:38:15.327033 4692 net.cpp:110] conv1 -> conv1
- I0721 10:38:16.721956 4692 net.cpp:125] Top shape: 256 96 55 55 (74342400)
- I0721 10:38:16.722030 4692 net.cpp:151] conv1 needs backward computation.
- I0721 10:38:16.722059 4692 net.cpp:74] Creating Layer relu1
- I0721 10:38:16.722070 4692 net.cpp:84] relu1 <- conv1
- I0721 10:38:16.722082 4692 net.cpp:98] relu1 -> conv1 (in-place)
- I0721 10:38:16.722096 4692 net.cpp:125] Top shape: 256 96 55 55 (74342400)
- I0721 10:38:16.722105 4692 net.cpp:151] relu1 needs backward computation.
- I0721 10:38:16.722116 4692 net.cpp:74] Creating Layer pool1
- I0721 10:38:16.722125 4692 net.cpp:84] pool1 <- conv1
- I0721 10:38:16.722133 4692 net.cpp:110] pool1 -> pool1
- I0721 10:38:16.722167 4692 net.cpp:125] Top shape: 256 96 27 27 (17915904)
- I0721 10:38:16.722187 4692 net.cpp:151] pool1 needs backward computation.
- I0721 10:38:16.722205 4692 net.cpp:74] Creating Layer norm1
- I0721 10:38:16.722221 4692 net.cpp:84] norm1 <- pool1
- I0721 10:38:16.722234 4692 net.cpp:110] norm1 -> norm1
- I0721 10:38:16.722251 4692 net.cpp:125] Top shape: 256 96 27 27 (17915904)
- I0721 10:38:16.722260 4692 net.cpp:151] norm1 needs backward computation.
- I0721 10:38:16.722272 4692 net.cpp:74] Creating Layer conv2
- I0721 10:38:16.722280 4692 net.cpp:84] conv2 <- norm1
- I0721 10:38:16.722290 4692 net.cpp:110] conv2 -> conv2
- I0721 10:38:16.725225 4692 net.cpp:125] Top shape: 256 256 27 27 (47775744)
- I0721 10:38:16.725242 4692 net.cpp:151] conv2 needs backward computation.
- I0721 10:38:16.725253 4692 net.cpp:74] Creating Layer relu2
- I0721 10:38:16.725261 4692 net.cpp:84] relu2 <- conv2
- I0721 10:38:16.725270 4692 net.cpp:98] relu2 -> conv2 (in-place)
- I0721 10:38:16.725280 4692 net.cpp:125] Top shape: 256 256 27 27 (47775744)
- I0721 10:38:16.725288 4692 net.cpp:151] relu2 needs backward computation.
- I0721 10:38:16.725298 4692 net.cpp:74] Creating Layer pool2
- I0721 10:38:16.725307 4692 net.cpp:84] pool2 <- conv2
- I0721 10:38:16.725317 4692 net.cpp:110] pool2 -> pool2
- I0721 10:38:16.725329 4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)
- I0721 10:38:16.725338 4692 net.cpp:151] pool2 needs backward computation.
- I0721 10:38:16.725358 4692 net.cpp:74] Creating Layer norm2
- I0721 10:38:16.725368 4692 net.cpp:84] norm2 <- pool2
- I0721 10:38:16.725378 4692 net.cpp:110] norm2 -> norm2
- I0721 10:38:16.725389 4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)
- I0721 10:38:16.725399 4692 net.cpp:151] norm2 needs backward computation.
- I0721 10:38:16.725409 4692 net.cpp:74] Creating Layer conv3
- I0721 10:38:16.725419 4692 net.cpp:84] conv3 <- norm2
- I0721 10:38:16.725427 4692 net.cpp:110] conv3 -> conv3
- I0721 10:38:16.735193 4692 net.cpp:125] Top shape: 256 384 13 13 (16613376)
- I0721 10:38:16.735213 4692 net.cpp:151] conv3 needs backward computation.
- I0721 10:38:16.735224 4692 net.cpp:74] Creating Layer relu3
- I0721 10:38:16.735234 4692 net.cpp:84] relu3 <- conv3
- I0721 10:38:16.735242 4692 net.cpp:98] relu3 -> conv3 (in-place)
- I0721 10:38:16.735250 4692 net.cpp:125] Top shape: 256 384 13 13 (16613376)
- I0721 10:38:16.735258 4692 net.cpp:151] relu3 needs backward computation.
- I0721 10:38:16.735302 4692 net.cpp:74] Creating Layer conv4
- I0721 10:38:16.735312 4692 net.cpp:84] conv4 <- conv3
- I0721 10:38:16.735321 4692 net.cpp:110] conv4 -> conv4
- I0721 10:38:16.743952 4692 net.cpp:125] Top shape: 256 384 13 13 (16613376)
- I0721 10:38:16.743988 4692 net.cpp:151] conv4 needs backward computation.
- I0721 10:38:16.744000 4692 net.cpp:74] Creating Layer relu4
- I0721 10:38:16.744010 4692 net.cpp:84] relu4 <- conv4
- I0721 10:38:16.744020 4692 net.cpp:98] relu4 -> conv4 (in-place)
- I0721 10:38:16.744030 4692 net.cpp:125] Top shape: 256 384 13 13 (16613376)
- I0721 10:38:16.744038 4692 net.cpp:151] relu4 needs backward computation.
- I0721 10:38:16.744050 4692 net.cpp:74] Creating Layer conv5
- I0721 10:38:16.744057 4692 net.cpp:84] conv5 <- conv4
- I0721 10:38:16.744067 4692 net.cpp:110] conv5 -> conv5
- I0721 10:38:16.748935 4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)
- I0721 10:38:16.748955 4692 net.cpp:151] conv5 needs backward computation.
- I0721 10:38:16.748965 4692 net.cpp:74] Creating Layer relu5
- I0721 10:38:16.748975 4692 net.cpp:84] relu5 <- conv5
- I0721 10:38:16.748983 4692 net.cpp:98] relu5 -> conv5 (in-place)
- I0721 10:38:16.748998 4692 net.cpp:125] Top shape: 256 256 13 13 (11075584)
- I0721 10:38:16.749011 4692 net.cpp:151] relu5 needs backward computation.
- I0721 10:38:16.749022 4692 net.cpp:74] Creating Layer pool5
- I0721 10:38:16.749030 4692 net.cpp:84] pool5 <- conv5
- I0721 10:38:16.749039 4692 net.cpp:110] pool5 -> pool5
- I0721 10:38:16.749050 4692 net.cpp:125] Top shape: 256 256 6 6 (2359296)
- I0721 10:38:16.749058 4692 net.cpp:151] pool5 needs backward computation.
- I0721 10:38:16.749074 4692 net.cpp:74] Creating Layer fc6
- I0721 10:38:16.749083 4692 net.cpp:84] fc6 <- pool5
- I0721 10:38:16.749091 4692 net.cpp:110] fc6 -> fc6
- I0721 10:38:17.160079 4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)
- I0721 10:38:17.160148 4692 net.cpp:151] fc6 needs backward computation.
- I0721 10:38:17.160166 4692 net.cpp:74] Creating Layer relu6
- I0721 10:38:17.160177 4692 net.cpp:84] relu6 <- fc6
- I0721 10:38:17.160190 4692 net.cpp:98] relu6 -> fc6 (in-place)
- I0721 10:38:17.160202 4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)
- I0721 10:38:17.160212 4692 net.cpp:151] relu6 needs backward computation.
- I0721 10:38:17.160222 4692 net.cpp:74] Creating Layer drop6
- I0721 10:38:17.160230 4692 net.cpp:84] drop6 <- fc6
- I0721 10:38:17.160238 4692 net.cpp:98] drop6 -> fc6 (in-place)
- I0721 10:38:17.160258 4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)
- I0721 10:38:17.160265 4692 net.cpp:151] drop6 needs backward computation.
- I0721 10:38:17.160277 4692 net.cpp:74] Creating Layer fc7
- I0721 10:38:17.160286 4692 net.cpp:84] fc7 <- fc6
- I0721 10:38:17.160295 4692 net.cpp:110] fc7 -> fc7
- I0721 10:38:17.342094 4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)
- I0721 10:38:17.342157 4692 net.cpp:151] fc7 needs backward computation.
- I0721 10:38:17.342175 4692 net.cpp:74] Creating Layer relu7
- I0721 10:38:17.342185 4692 net.cpp:84] relu7 <- fc7
- I0721 10:38:17.342198 4692 net.cpp:98] relu7 -> fc7 (in-place)
- I0721 10:38:17.342208 4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)
- I0721 10:38:17.342217 4692 net.cpp:151] relu7 needs backward computation.
- I0721 10:38:17.342228 4692 net.cpp:74] Creating Layer drop7
- I0721 10:38:17.342236 4692 net.cpp:84] drop7 <- fc7
- I0721 10:38:17.342245 4692 net.cpp:98] drop7 -> fc7 (in-place)
- I0721 10:38:17.342254 4692 net.cpp:125] Top shape: 256 4096 1 1 (1048576)
- I0721 10:38:17.342262 4692 net.cpp:151] drop7 needs backward computation.
- I0721 10:38:17.342274 4692 net.cpp:74] Creating Layer fc8
- I0721 10:38:17.342283 4692 net.cpp:84] fc8 <- fc7
- I0721 10:38:17.342291 4692 net.cpp:110] fc8 -> fc8
- I0721 10:38:17.343199 4692 net.cpp:125] Top shape: 256 22 1 1 (5632)
- I0721 10:38:17.343214 4692 net.cpp:151] fc8 needs backward computation.
- I0721 10:38:17.343231 4692 net.cpp:74] Creating Layer loss
- I0721 10:38:17.343240 4692 net.cpp:84] loss <- fc8
- I0721 10:38:17.343250 4692 net.cpp:84] loss <- label
- I0721 10:38:17.343264 4692 net.cpp:151] loss needs backward computation.
- I0721 10:38:17.343305 4692 net.cpp:173] Collecting Learning Rate and Weight Decay.
- I0721 10:38:17.343327 4692 net.cpp:166] Network initialization done.
- I0721 10:38:17.343335 4692 net.cpp:167] Memory required for Data 1073760256







浙公网安备 33010602011771号