深度卷积模型:案例研究
即使以现在的衡量标准,也是很大的。用256个3×3的过滤器进行卷积,得到13×13×256,进行最大池化,尺寸缩小到6×6×256,把他展平成9216个单元,然后进行一些全连接层,使用Softmax函数输出,看他是1000个可能对象中的哪一个?第一层使用96个11×11,步长为4的过滤器,图像尺寸缩小到55×55×96,随后的最大池化层用了3×3的过滤器,尺寸缩小为27×27×96,然后用256个
目录
1 为什么要进行案例研究?
过去,计算机视觉中的大量研究都集中在如何将卷积层、池化层以及全连接层这些基本组件组合起来,形成有效的卷积神经网络。
找感觉的最好方法之一就是去看一些示例,就像很多人通过看别人的代码来学习编程一样。我认为一个很好的方法去了解关于如何构建卷积神经网络,就是去看别人构建的高效卷积神经网络。事实证明,一个神经网络结构,如果在一个计算机视觉问题中表现的很好,通常也会在别的问题中表现很好。
在接下来,我们将会,学习一些计算机视觉领域的研究论文。
2 经典网络
LeNet-5的网络架构是:
从一幅32×32×1的图像开始,而LeNet-5的任务是识别手写数字,LeNet-5是针对灰度图像训练的,这就是为什么他是32×32×1。
LeNet-5的第一层使用六个5×5的过滤器,步长为1,padding为0,输出结果是28×28×6,图像尺寸从32×32缩小到28×28,然后进行池化操作。在这篇论文发表的那个年代,人们更喜欢用平均池化;而现在,我们可能用最大池化更多一点。但是在这个例子中,我们进行平均池化,过滤器的宽度为二,步长为二,图像的高度和宽度都缩小两倍,输出结果是一个14×14×6的图像。

在LeNet-5论文发表的年代,当时人们并不使用padding或者valid卷积,这就是为什么每进行一次卷积,图像的高度和宽度都会缩小一半。
接下来继续用16个5×5,步长为1的过滤器进行卷积,新的输出结果是10×10×16,再进行平池化,输出5×5×16。

把5×5×16展平成400个神经单元,建立全连接层,120个神经元每个都全连接这400个单元;再建立一层全连接层,用84维特征生成一个最终结果,
可能有10个可能值,对应识别的0-9这10个数字。现在,用Softmax函数输出十种分类结果

尽管LeNet-5原先是用别的分类器做输出层,而这个分类器现在已经不用了。用现在的标准来看,这是个小型神经网络,大概有6万个参数;而如今你经常会见到千万到亿量级参数的神经网络。不管怎样,如果我们从左往右看这个神经网络,会发现随着网络越来越深,图像的高度和宽度都在缩小,从最初的32×32缩小到28×28,再到14×14,10×10,最后只有5×5;与此同时,随着网络层次的加深,通道数量一直在增加,从1个增加到6个,再到16个。这个神经网络中还有一个模式,至今仍然经常用到,那就是先使用一个或者多个卷积层,后面跟着一个池化层,然后又是若干个卷积层,再接一个池化层,然后是全连接层,最后是输出,这种排列方式很常见。
AlexNet的网络架构是:
AlexNet首先用一张227×227×3的图片作为输入,如果你读了这篇论文,论文提及的是224×224×3的图像,但如果你检查数字,你会发现227×227才合理。
第一层使用96个11×11,步长为4的过滤器,图像尺寸缩小到55×55×96,随后的最大池化层用了3×3的过滤器,尺寸缩小为27×27×96,然后用256个5×5的过滤器进行Same卷积,得到27×27×256,再来一次做最大池化,尺寸缩小到13×13×256。


使用384个3×3的过滤器进行两次Same卷积,得到13×13×384;用256个3×3的过滤器进行卷积,得到13×13×256,进行最大池化,尺寸缩小到6×6×256,把他展平成9216个单元,然后进行一些全连接层,使用Softmax函数输出,看他是1000个可能对象中的哪一个?
Alexnet神经网络结构与LeNet有很多相似之处,不过Alexnet要大很多,AlexNet包含约6000万个参数,AlexNet采用与LeNet相似的构造版块,拥有更多隐藏神经元、在更多数据上训练。Alexnet在ImageNet数据库上训练,使它有优秀的性能。
Alexnet神经网络比LeNet更好地原因是:Relu函数的使用。
VGG-16的网络架构是:
按作者所说,关于VGG-16非常值得注意的一点是:VGG-16没有那么多超参数,结构更简单,更能关注卷积层,使用3×3、步长为1的Same过滤器;最大池化的过滤器都是2×2、步长为2。
假设你要识别224×224×3的图像,在最开始的两层,用64个3×3的过滤器对输入的图像进行Same卷积,得到224×224×64的结果,使用最大池化缩小到112×12×64;接着又是使用2层Same卷积层,结果是112×112×128,经过池化层后,维度是56×56×128;再使用三层Same卷积层,使得维度变成56×56×256,接着使用池化层后维度变成28×28×256;再经过三层Same卷积层变成28×28×512,经过最大池化变成14×14×512。再经过卷积、池化,直到最后维度变成7×7×512,把得到的神经单元展平拉直,通过全连接层,经过Softmax函数输出1000类结果。

VGG-16中的16指该网络有16层带权重的层,这是一个相当大的网络,它总共有一亿三千八百万个参数。即使以现在的衡量标准,也是很大的 。VGG-16结构的简洁性也非常吸引人,看得出这个结构相当统一,先是几层卷积层,再是池化层。另一方面,如果你看卷积层中过滤器数,从64到128到256再到512,每次粗略的双倍增加过滤器的方式是设计神经网络时用的另一个简单原则。
3 ResNets
太深的神经网络训练起来很难,因为有梯度消失和梯度爆炸问题,我们将学习跳跃连接,它可以允许从某一网络层得到激活值,并迅速传递给下一层甚至是更深的神经网络层,利用它你就可以训练网络层很深的残差网络。残差网络是使用了残差结构的网络。
这里有两层神经网络,代表第L层的激活函数,然后是
,两层后得到
。

在这个例子的激活函数,作为输入,计算出
,之后应用非线性激活函数Relu得到
;然后在下一层经过线性计算
,再使用一次Relu函数得到
。换句话说,从
流向
的信息需要经过上面的所有步骤,我把这称做这组层的主路径。
在残差网络中,我们需要做个改变,把直接向后连接到深层神经网络的位置。

这条路径是在进行Relu非线性激活函数之前加上的。也就是,
。
我们来看看下面这个网络,它并不是一个残差网络,而是一个普通网络:

把它变成ResNet的方法是加上所有的跳跃连接,就像这样:

事实证明,如果你使用标准的优化算法(如梯度下降法)来训练普通网络,从经验上来说,你会发现当你增加层数时,训练误差会在下降一段时间后回升;

而理论上,随着网络深度的加深,应该训练的越来越好。如果没有残差网络,对于一个普通网络来说,网络越深意味着用优化算法越难训练,训练错误会越来越多;但是有了ResNet就不一样了,即使网络再深,训练表现也不错,训练错误会减少。
4 ResNets 为何有效?
为什么ResNets这么好用呐?
一个网络深度越深,它会使得你用训练集训练神经网络的能力下降,这也是有时候我们不希望加深网络的原因,但当你训练ResNet的时候就不一样了,我们来看一个例子。
如果你有一个大型神经网络,它的输入是x,输出激活值。

如果你想调整神经网络,使其深度更深一点:

把这两层看作是具有跳跃连接的残差块。为了方便说明,假设我们在整个网络中使用Relu激活函数,所有激活值都大于等于零。
我们看一下的值,也就是
,展开这个表达式,也就是:
。注意一点,如果使用L2正则化或者权重衰减,它会压缩
的值,如果对b使用权重衰减也会达到同样的效果。这里的w是关键项,假设
,如果
,那么
,
。因为我们假设使用Relu激活函数,并且所有激活值都是非负的,
是非负的,所以结果是
,这意味着残差块比较容易学习恒等函数,由于这个跳跃连接也很容易得到
,将这两层加入到你的神经网络,与上面这个没有这两层的网络相比,并不会非常影响神经网络的能力,因为对于它来说学习恒等函数非常容易。所以这就是为什么添加两层,不论是把残差块添加到神经网络的中间还是尾部都不会影响神经网络的表现。
当然,我们的目标并不只是维持原有的表现,而是帮助获得更好的表现。你可以想象,如果这些隐藏单元学习到一些有用信息,那么它可能比学习恒等函数表现的更好;而这些不含残差块或跳跃连接的普通神经网络,情况就不一样了。当网络不断加深时,就算是选择用来学习恒等函数的参数也很困难,所以很多层最后的表现,不但没有更好,反而更糟。
我认为残差网络起作用的主要原因是:这些额外层学习恒等函数非常容易,几乎总能保证它不会影响总体的表现,很多时候甚至可以提高效率,或者说至少不会降低网络效率。
除此之外,关于残差网络另一个值得讨论的细节是:对于,我们是假定
和
具有相同的维度。所以你会看到在ResNet中许多Same卷积的使用。如果输入和输出有不同的维度,假如
是128维,而
和
的结果是256维的,我们可以让
与一个256×128维的
矩阵相乘,也就是
。
5 网络中的网络和 1x1 卷积
在设计卷积网络的架构时,其中一种很有用的想法是用1×1的卷积。现在你可能在想1×1的卷积能做些什么,不就是乘以数字吗?事实并非完全如此:

这个1×1过滤器里的数字为2,用6×6×1的图像去和这个大小为1×1×1的过滤器去做卷积,结果相当于把这个图片乘以数字2。所以通过一个1×1的过滤器做卷积,似乎不是特别有用,只是对输入矩阵乘以某个数字,但这仅仅是对于6×6×1的输入图片来说:使用1×1卷积效果不佳。
如果你有一张6×6×32的图片,那么使用1×1过滤器进行卷积效果更好。具体来说,1×1卷积所实现的功能是:逐一扫过这里的36个不同位置,然后进行对应元素间的乘法,将左边的32个数和过滤器中的32个数相乘,然后使用非线性函数Relu。

以这36个位置中的一个为例,用这32个数乘以过滤器,可以得到一个输出值。实际上,你可以这样理解:这个1×1×32的过滤器中的32个数,类似于你有一个神经元,接收一个32个数的输入向量,将一条位于相同位置及相同高度和宽度;但位于32个不同通道的数,和32个权重相乘,得到的结果通过Relu函数,最后再输出相应的结果。
一般来说,如果过滤器不止一个,就好像有多个输入单元,输入内容是一个切片上的所有数字,然后将它们生成为一个6×6×过滤器数数量。所以1×1卷积可以从根本上理解为:这32个单元都应用了一个全连接神经网络,全连接层的作用是输入32个数字,然后输出过滤器数个输出值。
举一个1×1卷积的例子:

假设这是一个28×28×192的输入层,你可以使用池化层压缩它的高度和宽度,但是如果通道数量很大,那么,该如何把它压缩为28×28×32呢?你可以用32个大小为1×1×192维的过滤器。
6 inception网络简介
这是一个28×28×192的输入层,Exception网络层的作用是:与其在卷积神经网络中选择一个你想要使用的过滤器尺寸,或者选择一个卷积层或一个池化层,不如全都选择。

如果你可以使用1×1过滤器,则会输出28×28×通道数,假设有64个1×1的过滤器,则输出是28×28×64。

如果你用128个3×3的过滤器,和28×28×192进行Same卷积,那么仍然输出是28×28×128,然后把这个量并列的堆叠在第一个量旁边。

你也可能会想:我想提升网络的表现,用5×5过滤器或许会更好,再次使用Same卷积,把输出也变成28×28×32。

也许你不想要使用卷积层,那我们就使用池化层,得到一些不同的输出结果,我们把它也堆积起来。这里我们使用Same池化,把输出也变成28×28×32。

对于像这样一个inception模块,你可以输入一些量,并且获得一些输出,如果你把所有数字加起来,32+32+128+64=256。所以你将有一个inception模块,它的输入是28×28×192,输出是28×28×256。这就是inception网络的核心内容,Inception网络的基本思想是:你不用只挑选一个过滤器的大小或者是pooling,你可以所有可能都做,然后把所有的输出结果都连接起来啊,然后让神经网络去学习它想要用到的参数以及想要用到的过滤器大小。
Inception有出现计算成本问题。我们来看一下,使用5×5的过滤器产生的计算成本是多少?
我们现在有一个28×28×192大小的输入,然后使用32个5×5的过滤器进行Same卷积,输出为28×28×32。

所以有28×28×32个数,其中有32个过滤器,每个过滤器大小为5×5×192。乘法总数是28×28×32×5×5×192=1.2亿。虽然可以在现代的计算机里做1.2亿次乘法运算,但是这个运算的次数还是相当大,通过1×1卷积运算,能够把成本降低到大约1/10的次数。
接下来我们讲另一种结构,它同样能够接受28×28×192的输入,并且输出大小为28×28×32。

用1×1的卷积运算,将通道的个数从192减小到16,输出为28×28×16,然后我们用这个相对较小的量,去做5×5卷积运算并得出最终结果为28×28×32。
这两种方法中,输入都是28×28×192,输出28×28×32。但是在第二种方法中,我们先将这个较大的输入,减小成一个较小的中间值,也就是只有16个通道,而不是192个通道,有时把中间的这一层叫做瓶颈层。
现在我们再来看一下这次的计算成本:16个过滤器先进行1×1的卷积运算,每个过滤器是1×1×192。乘法运算的次数是28×28×16×1×1×192=240万。第二个卷积层的计算结果是:28×28×32×5×5×16=1000万, 所以总的计算成本是1240万。
和第一次运算成本相比,你会发现运算成本从1.2亿次运算降低到了1240万次,这大概是第一个方法的1/10。
如果你在建立一个卷积网络层,并且你不想去决定到底是用1×1还是5×5的过滤器或者是否使用pooling,那么就可以使用inception模型,它会做所有的工作,并会将所有的结果都连接起来。
7 迁移学习
如果你要做一个计算机视觉的应用,但是不想从零开始训练权重:比如说从随机初始化开始训练。更快的实现方式通常是下载已经训练好权重的网络结构把这个作为预训练迁移到你感兴趣的新任务上。
假如说你要建立一个猫检测器,用来检测宠物猫的种类。你可能没有很多种类A和B猫的图片,所以你的训练集会很小,那么你该怎么做?
你可以从网上下载一些开源的神经网络应用,不但下载源码,还要下载相应权重。你可以下载许多已经训练好的网络,比如:在有1000类物体的ImageNet数据库上训练,因此这个网络会有一个Softmax单元,它可以输出1000个可能类别之一,你可以去掉这个Softmax层,创建你自己的Softmax层,用来输出A,B,C这三个类别。
就网络而言,我建议你把所有的层都看做是冻结的,冻结网络中所有层的参数,你只需要训练和你的Softmax层有关的参数,这个Softmax层有三个可能的输出。
通过使用其他人预训练的权重,即使只有一个小的数据集,你也很可能得到很好的性能;如果你有一个更大的数据集,在这种情况下,你应该冻结更少的层,然后训练后面的层;如果你有大量的数据,你可以用开源的网络和他的权重,用它们初始化整个网络,然后训练,用自己的Softmax层输出。
有一个规律就是:你有越多的数据,需要冻结的层数越少,能够训练的层数就越多。
8 数据增强
简单的数据增强方法是对图片做垂直镜像对称。

对大部分计算机视觉工作来说,如果左边的图片是一只猫,那镜像后仍然是一只猫。镜像操作保留了你想要识别的图像内容,这是一种很好用的数据增强技术。
另一种常用技术是随机裁剪,通过随机裁剪,你可以获得不同的示例来扩充你的数据集。

我们经常使用镜像和随机裁剪,理论上你也可以使用其他方式,例如旋转,剪切图像,对图像进行扭曲变换等。
第二类常用的数据增强方式是色彩变化。你可以给一张图片在rgb 3通道上加入不同的扰动,来实现不同的色彩变化,让你的学习算法,在应对图像色彩变化时更具健壮性。

更多推荐



所有评论(0)