第二十八周学习笔记

第二十八周学习笔记

CS231n

卷积神经网络(Convolutional Neural Networks(CNNs/ConvNets))

池化层

ConvNet中,通常的操作是在连续的卷积层中定期插入池化层。这是为了逐渐降低表达的空间尺寸,从而减少网络的参数和计算量,进而控制过拟合。池化层使用取最大值的操作,在输入的每个深度切片上操作并在空间上将之resize,最通常的池化层形式是使用2×2的滤波器,并取stride=2,来下采样深度切片,从而舍弃了75%的激活区域。本例举的每个最大化操作接受4个数字(2×2的深度切片)作为输入,深度维经过池化操作后不变,详细概括一下,池化层:

  • 接受 W 1 × H 1 × D 1 W_1 \times H_1 \times D_1 的volume
  • 需要两个超参数:
    • 滤波器大小 F F
    • stride S S
  • 输出 W 2 × H 2 × D 2 W_2 \times H_2 \times D_2 的volume,其中:
    • W 2 = ( W 1 F ) / S + 1 W_2 = (W_1-F)/S+1
    • H 2 = ( H 1 F ) / S + 1 H_2 = (H_1-F)/S+1
    • D 2 = D 1 D_2 = D_1
  • 池化函数引入的参数个数为0(如max)
  • 通常不使用zero-padding

值得注意的是两个实践中常用的最大池化: F = 3 , S = 2 F=3,S=2 (也称为重叠池化(overlapping pooling))以及更常见的 F = 2 , S = 2 F=2,S=2 ,更大的感受野会有不利之处

general pooling,除了最大池化之外,池化单元也可以实现其他函数,比如平均池化(average pooling)或L2范数池化(L2-norm pooling)。平均池化在历史上经常使用,但如今已经不如最大池化操作流行,因为最大池化在实践中效果更好。


在这里插入图片描述
最大池化对volume进行空间下采样,这个过程对于不同的深度切片是独立的。
:在本例中,[224×224×64]的输入使用尺寸为2,stride为2的池化层,输出尺寸为[112×112×64].注意深度不变。
:最常见的下采样操作是取最大值,也就是最大池化,这里展示了一个stride为2的例子。每个取最大值操作输入4个数字(小的2×2方格)。


反向传播,回忆反向传播那章,max(x,y)的反向传播过程很简单,仅仅是将梯度传递给最大的输入值。因此,在池化层的前向传播时,通常我们将最大值的索引记录下来,从而可以高效实现反向传播

不使用池化层,很多人不喜欢池化操作,并认为,我们可以摆脱它。例如,Striving for Simplicity: The All Convolutional Net,提出去掉所有的池化层,仅仅保留卷积层。为了减低表达的维数,它们提出使用stride更大的卷积层。在训练生成模型中,去掉池化层也被证明有好的表现,比如在变分自编码器中(VAEs)或生成对抗网络中(GANs)。可能未来的网络架构会没有池化层。

Normalization Layer

在ConvNet的使用中,有很多种normalization layers被提出,有些是为了实现在生物脑中观测到的抑制机制。然后,这些层也已被淘汰,因为在实际上它们即使有贡献,也微不足道。要了解各种各样的normalization,请看Alex Krizhevsky的讨论cuda-convnet library API

全连接层

全连接层的神经元与前一层激活全连接,正如在常规神经网络中看到的,因此可以通过矩阵乘法和加偏置计算。详情请看神经网络一节

将全连接层转化为卷积层

值得一提的是,全连接层和卷积层的唯一区别就是卷积层仅仅与输入的局部区域相连,且卷积volume中的很多神经元共享参数。然而,两种层中的神经元仍然计算点乘,因此它们的函数形式相同。因此,在全连接层和卷积层中相互转化是可能的:

  • 对于任意卷积层,都有一个全连接层实现了相同的前向过程,其中权重矩阵是一个大的除部分块(由于局部连接)外其他都为0的大矩阵,且很多块的参数是相同的(由于参数共享)。
  • 反过来,任何全连接层可以被转化为卷积层,例如,一个全连接层 K = 4096 K=4096 ,以 7 × 7 × 512 7 \times 7 \times 512 作为输入,可以用一个 F = 7 , P = 0 , S = 1 , K = 4096 F=7,P=0,S=1,K=4096 的卷积层表达。换言之,我们将卷积核的大小设置为与输入volume恰好相同,因此输出将是 1 × 1 × 4096 1×1×4096 ,因为只有一个深度列(depth column),能放入输入volume,给出的结果与全连接层相同

全连接层到卷积层变换,在这两种变换中,将全连接层变换为卷积层是实践中更有用的。考虑一个以224×224×3的图片作为输入的ConvNet,然后使用卷积层和池化层将图片降维到7×7×512(在之后我们将看的看AlexNet架构中,这通过五个尺池化层以2为因子逐渐下采样输入,使得最后输出的尺寸为224/2/2/2/2/2=7).然后,AlexNet使用两层4096的全连接层,最后使用一个1000的全连接层来计算类别得分,我们可以按照之前的方法将这些全连接层转化为卷积层:

  • 使用 F = 7 F=7 将第一个以7×7×512输入的全连接层转化为卷积层,得到输出[1×1×4096]
  • 使用 F = 1 F=1 将第二个全连接层转化为卷积层,输出[1×1×4096]
  • 使用 F = 1 F=1 将最后一个全连接层转化为卷积层,得到最终输出[1×1×1000]

实际中上述的每一步都包括将全连接层的权重矩阵 W W reshape成卷积层中的滤波器。这种转化使得我们在前向传播过程中,可以高效地在一张更大的图片上滑动ConvNet

扫描二维码关注公众号,回复: 5733417 查看本文章

举个例子,如果一张224×224的图片给出volume尺寸为[7×7×512],即除以32的下采样,则将一张384×384的图片传入这个转化后的网络会给出尺寸为[12×12×512]的输出,因为384/32=12。接下来三个卷积层(之前我们从全连接层转化来的)会给出最终的[6×6×1000]的输出,因为(12-7)/1+1=6。注意到我们并没有得到一个[1×1×1000]的类别得分输出,而是对于每张384×384的图片得到一个6×6的类别输出。

使用ConvNet的原型(全连接层版本的)独立地以384×384图片的224×224区域为输入,并取stride为32给出的结果与ConvNet相同,即前一段所说的在更大大图片上滑动

自然,使用ConvNet一次转化比使用原网络在这36个位置分别计算更加高效,因为这36次有重叠的计算消耗。这种技巧经常在实际中使用,以得到更好的表现,例如,通常将图片resize得到更大的图片,然后用转化后的ConvNet来计算各个空间位置的类别得分,然后平均这些得分。

最后,如果我们想要stride小于32,那么如何高效地在原图上应用原网络呢。我们可以通过多层前向来实现它。比如,如果我们想要使用stride=16,我们可以将输入结合两次:第一次在原图片上,第二次在空间上改变16像素的图片上

卷积网络架构

我们已经了解到,卷积网络大多以三种层组成:CONV,POOL(如无特别说明,就是最大池化层)和FC(fully-connected的简写),我们也将RELU列为一种层,它对输入的逐个元素进行非线性操作。本节介绍如何将这些层组成一个卷积网络。

层模式

最常见的ConvNet架构将几层CONV-RELU叠在一起,并在后面加上池化层,重复这个模式直到将图片降维到一个合适的尺寸。到了一定时候,再在后面加上全连接层。最后一个全连接层作为输出,比如类别得分。另一方面,最常见的卷积网络架构是如下的模式:

I N P U T > [ [ C O N V > R E L U ] N > P O O L ? ] M > [ F C > R E L U ] K > F C INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC

其中 * 代表重复,而POOL?代表是可选的池化层,更多的, N > = 0 N>=0 (通常 N < = 3 N<=3 ), M > = 0 M>=0 K > = 0 K>=0 (通常 K < 3 K<3 )。比如,有一些网络可能是如下的结构

  • I N P U T > F C INPUT -> FC ,实现了一个线性分类器, H = M = K = 0 H=M=K=0
  • I N P U T > C O N V > R E L U > F C INPUT -> CONV -> RELU -> FC
  • I N P U T > [ C O N V > R E L U > P O O L ] 2 > F C > R E L U > F C INPUT -> [CONV -> RELU -> POOL]*2 -> FC ->RELU ->FC ,这里在每个POOL层之间有一个卷积层
  • I N P U T > [ C O N V > R E L U > C O N V > R E L U > P O O L ] 3 > [ F C > R E L U ] 2 > F C INPUT -> [CONV->RELU->CONV->RELU->POOL]*3 ->[FC->RELU]*2->FC ,这里每个池化层间有两个卷积层,这是一个更大更深网络的好的结构,因为多层的卷积层可以在有信息损耗的池化操作之前从输入中提取更多特征

小的卷积核比大的卷积核更好,假设你将三个3×3的卷积层叠在一起(其中有非线性层)。这里,第一层的卷积层对原始输入的感受野是3×3,第二层对第一层的感受野是3×3,对原始输入的感受野是5×5,同理,第三层对原始输入的感受野是7×7。如果不使用三层3×3卷积层,而直接使用一层7×7的卷积层,两种实现对于原始的感受野是一样的(7×7),但有一些缺点。首先,后者输出仅仅是输入的线性函数,而前者经过多层非线性使得特征能更好地表达;其次,如果我们假设所有volume有C个通道,则7×7的卷积层会有 C × 7 × 7 × C = 49 C 2 C×(7×7×C)=49C^2 个参数,而三层3×3的卷积层会仅仅有 3 × C × 3 × 3 × C = 27 C 2 3×(C×(3×3×C))=27C^2 个参数。这样看来,将感受野小的卷积层叠起来相比只有一个个大感受野的卷积层来说,可以对输入有更丰富的表达,且参数更少。作为实践上的一个缺点,我们可能需要更多的内存来保存各层的中间结果,因为我们需要进行反向传播。

最近的背离(Recent departures),值得一提的是层的线性结构的卷积范式也在受到挑战,在谷歌的Inception结构和近期(先进的)微软亚洲研究院的Residual Networks。这两个(在后文有提到)能提取更好的特征,且连接的结构与我们提及的不同。

实践:使用在ImageNet上效果最好的网络,如果你对于设计结构感到头疼,那么你应该知道在90%以上的应用中你都不必担心这个问题。我将这一点总结为“不要想当英雄”,你应该看一看什么网络在ImageNet上的效果最好并将它的预训练网络下载下来然后在你的数据上微调,而不是设计自己的网络架构。你几乎不必从头训练一个卷积网络或者从头设计一个,这一点我在Deep Learning school中也有提到。

层的尺寸模式

我们一直对ConvNet中层的超参数避而不提。现在我们首先提出几个经验上的设计尺寸的方法,然后用记号讨论这些方法。

输入层(包含图片),应该被2整除多次,通常的数字是32(例如 CIFAR-10),64,96(例如STL-10)或224(例如通常的ImageNet卷积网络),384和512

卷积层应该使用小的卷积核(3×3或最大5×5),使用stride=1,zero padding的设置应使得卷积层不改变输入的空间尺寸,意思是,当 F = 3 F=3 时,使用 P = 1 P=1 将会保持原始输入的尺寸。当 F = 5 F=5 时, P = 2 P=2 。对一般的 F F ,取 P = ( F 1 ) / 2 P=(F-1)/2 即可。如果你非要使用更大的卷积核(比如7×7),通常只对第一层卷积层进行这个操作

池化层是负责对输入进行空间下采样,最常用的就是使用2×2的最大池化(即 F = 2 F=2 ),且stride=2(即 S = 2 S=2 )。注意这使得输出恰好是输入的75%.另一个不太常用的选择是使用3×3的感受野且stride=2。感受野大于3的情况是少见的,因为池化操作本身就损失很多信息,这样会导致糟糕的表现。

降低调整尺寸的头疼,上述的模式是可喜的,因为所有卷积层保持输入的空间尺寸,仅仅池化层需要起到空间下采样的作用。在当我们需要stride大于1的情况下,则不要在卷积的时候使用zero-padding,我们需要仔细检查整个网络的结构,使得所有的stride和滤波器的参数吻合。

CONV中为什么使用stride=1? 实践中更小的卷积效果更好,其次,这样让我们将所有空间下采样的操作留给了池化层,而卷积层仅仅改变了volume的深度

为什么要使用padding? 除了前述的才卷积时保持输入的空间尺寸,这样做的确提高了表现。如果卷积层不适用zero-padding,在每层卷积操作之后volume都会变小一点,这样边界上的信息会很快被剔除。

对内存的妥协 在一些情况下(尤其是早期的卷积网络架构中),上述的规律会让内存消耗迅速加快。比如,使用64个3×3的卷积核卷积一个224×224×3的图片,且使用padding=1,会得到3个激活volume,尺寸为[224×224×64],这总计是1千万个激活单元,或72MB内存(每张图片,包括激活单元和梯度),因为GPU通常因为内存达到瓶颈,因此有必要妥协。在实践中,人们通常在第一层妥协。比如,一种妥协是在第一层使用7×7,stride=2,另一个例子是,AlexNet中使用11×11的卷积核,stride为4

例子

以下是一些有名的卷积网络架构:

项目 年份 作者 备注
LeNet 1990 Yann LeCun 第一个卷积网络的应用,其中最有名的是LeNet识别数字和邮政编码的结构
AlexNet 2012 Alex Krizhevsky, Ilya Sutskever 和 Geoff Hinton 第一个使卷积神经网络在计算机视觉界流行的架构,AlexNet在2012年的ImageNet ILSVRC challenge中性能远超第二名(16%的top5错误率,第二名是26%的top5错误率)。这个网络架构与LeNet很相似,但更深更大,多个卷积层叠在一起(之前通常是卷积层之后立即跟上一个池化层)
ZF NET 2013 Matthew Zeiler.Rob Fergus ILSVRC 2013年的赢家,它在AlexNet的基础上调整了一些超参数,尤其是扩大了中间卷积层的尺寸,让第一层的stride和滤波器尺寸更小
GoogLeNet 2014 Szegedy et al from Google 它主要的贡献就是提出了Inception Module,大大减少了网络中的超参数(4M,而AlexNet中有60M)。此外,这儿么论文使用了平均池化而不是在最后使用全连接层,减少了很多不必要的参数。GoogLeNet也有很多后续版本,最近的是Inception-v4
VGGNet 2014 Karen Simonyan and Andrew Zisserman ILSVRC 2014的亚军,它主要的贡献是展示了深度不是好的表现的必要元素,它们最终的网络包括16层CONV/FC层,而且网络结构极其一致,仅仅使用了3×3的卷积和2×2的池化层。它们的预训练模型在Caffe中包含了。VGGNet的一个缺点是消耗了更多的内存和参数(140M)。大多数的参数是在全连接层中,也就是那时人们发现这些全连接层可以在不降低表现的情况下被移除,大大减少了必要参数的个数
ResNet 2015 Kaiming He et al ILSVRC2015的赢家,它使用了特殊的跳跃连接及大量的batch normalization。这个结构在最后也没有使用全连接层。读者可以看看Kaiming的演讲(video,slides),以及最近一些Torch的复现实验。ResNet是目前最先进的卷积神经网络模型,且是目前应用卷积网络的默认选择(2016年5月10日)。Kaiming He等人最近的对网络的调整在这,于2016年3月发表

VGGNet的细节,让我们来了解一下VGGNet的细节。整个VGGNet的3×3卷积层stride=1,pad=1组成,池化层使用的是2×2的最大池化,stride=2(无padding),我们可以写出每一步的表达,并且列出表达的尺寸和权值的数量:

尺寸/内存 权值个数
INPUT 224×224×3=150K 0
CONV3-64 224×224×64=3.2M (3×3×3)×64=1,728
CONV3-64 224×224×64=3.2M (3×3×64)×64=36,864
POOL2 112×112×64=800K 0
CONV3-128 112×112×128=1.6M (3×3×64)×128=73,728
CONV3-128 112×112×128=1.6M (3×3×128)×128=147,456
POOL2 56×56×128=400K 0
CONV3-256 56×56×256=800K (3×3×128)×256=294,912
CONV3-256 56×56×256=800K (3×3×256)×256=589,824
CONV3-256 56×56×256=800K (3×3×256)×256=589,824
POOL2 28×28×256=800K 0
CONV3-512 28×28×512=400K (3×3×256)×512=1,179,648
CONV3-512 28×28×512=400K (3×3×512)×512=2,359,296
CONV3-512 28×28×512=400K (3×3×512)×512=2,359,296
POOL2 14×14×512=100K 0
CONV3-512 14×14×512=100K (3×3×512)×512=2,359,296
CONV3-512 14×14×512=100K (3×3×512)×512=2,359,296
CONV3-512 14×14×512=100K (3×3×512)×512=2,359,296
POOL2 7×7×512=25K 0
FC 1×1×4096=4096 7×7×512×4096=102,760,448
FC 1×1×4096=4096 4096×4096=16,777,216
FC 1×1×1000=1000 4096×1000=4,096,000
总计 24M*4bytes~=93MB/image(仅前向传播,总共预计2倍) 138M

在通常的卷积网络中,注意到多数内存被用在卷积层,而多数参数在全连接层,这里,第一个全连接层有100M个权值,而总共只有140M个权值

计算上的考虑

建立卷积网络结构的最大的瓶颈是内存,现代的GPU通常是3/4/6GB的内存。而最好的GPU有12GB的内存,这些内存被主要分配到以下几个方面

  • 中间volume:这些是ConvNet每层的的激活图,以及他们的梯度(与激活图尺寸相同)。通常,大多数激活单元在卷积网络的前几层(即第一层卷积层)。它们被保持在内存中因为需要进行反向传播,但在测试时可以仅仅存储当前层而舍弃之前的激活,从而节省大量的内存
  • 参数:这些是网络的参数,它们的梯度通常需要一步的缓存,如果优化方法使用的是(momentum,Adagrad,RMSProp)。因此,存储参数的内存也通常要乘以3来计算
  • 每个卷积网络的实现也需要维持各种各样的内存,比如批图片数据,也可能是它们的增强版本等

一旦你对于整体内存有了粗略的估计值(激活图的、梯度的和额外的),这个这个值要被转化为GB。将这个数值乘4来得到bytes值(因为每个浮点数是4bytes,或8bytes如果是双精度的),然后除以1024几次来分别得到KB、MB和GB。如果你的网络内存过大,一个常用的启发式的方法是减少批尺寸,因为大多数内存都是来源于激活图。

下周任务

何凯明的presentation
当前state of art的卷积网络是什么?
实现提出的几个网络

猜你喜欢

转载自blog.csdn.net/luo3300612/article/details/87107253
今日推荐