斯坦福机器学习课程学习笔记

CS231n 卷积神经网络: 架构, 卷积/池化层(下)

2018-08-02  本文已影响80人  tech0ne

卷积神经网络: 架构, 卷积/池化层(下)

2.CNNs中的各种层(接上文)

2.2 池化层

在CNNs架构中经常在连续的CONV层之间插入池化层,它的功能是逐渐降低空间大小来减少网络中的参数数量和计算量,并且也可以控制过拟合。池化层单独的在每个深度上进行操作,用MAX操作减小每个深度切片的空间大小。最常见的池化层用大小为2x2的滤波器以2为步长对每一个深度切片进行下采样,丢弃75%的输入数据。需要注意的是空间大小减小但深度不会改变。

概要 概括一下池化层的概念:

值得注意的是最大池化层在实践中只有两种常用的变种:一种是F=3S=2的重叠池化层(overlapping pooling),还有一种更常见的是F=2S=2的池化层。池化用更大的接受域对数据破坏性太大。

常规池化 除了最大池化,池化层也可以进行其他形式的处理,比如平均池化,甚至L2范数池化。平均池化以前经常用,不过最近不流行了,因为最大池化操作在实践中有更好的表现。

image

上图表示了大小为2x2,步长为2的滤波器在一个深度切片上的池化操作。

image

上图表示了通过池化操作后,数据的空间大小减小而深度不变。

反向传播 回忆一下BP章节中对max(x,y)的操作是只需要传导输入时最大值的所在位置的梯度值。所以只需要在池化的正向传递时记录最大值的索引(有时我们叫它switches)就能够在BP时高效的计算梯度。

去掉池化 有很多人不喜欢池化操作而且觉得没有它也行。比如Striving for Simplicity: The All Convolutional Net提议抛弃池化层而改用只有CONV的架构。他们建议在CONV层中用更大的步长来缩小数据的大小。摒弃池化层被发现对训练好的生成模型来说很重要,比如变分自动编码器(VAEs)或者生成对抗网络(GANs)。未来的CNNs架构或许很少有甚至没有池化层。

2.3 归一化层

许多种类的归一化层被提出并使用在CNNs构架中,为了实现生物大脑中观察到的抑制状态。然而它们在实践中的贡献非常小,相关论述请看cuda-convnet library API

2.4 全连接层

FC层中的神经元与上一层中的所有神经元相连,计算方式和普通神经网络的相关部分一样。

2.5 FC层转化为CONV层

值得注意的是FC层和CONV层的唯一区别就是CONV层的神经元共享参数并且只连接输入的一个局部区域。然而两种层仍然都是计算点积以至于函数形式是一样的。所以,结果是FC层和CONV层可以相互转换:

FC->CONV 转换 对于这两种转换,FC层向CONV层的转换在实践中特别有用。想一下一个输入为大小为224x224x3的图片的CNNs,然后用一系列的CONV层和POOL层来将图片缩小为大小为7x7x512的输出块(后面将会看到的AlexNet架构,每次下采样输入缩减一半数据,224/2/2/2/2/2= 7)。然后AlexNet用两个大小为4096的FC层,最后用一个FC层用1000个神经元计算类型得分。我们可以把这三个FC层分别用上述方法转换为CONV层:

每一个这种转换在实践中的操作是将FC层中的权值矩阵W变形成CONV层中的多个滤波器。这种转换的结果是可以让我们在一次前向传播中得到一张更大图片的多个空间位置的得分。

例如,如果224x224的图片产生的输出为[7x7x512],那么处理384x384的图片就会产生大小为[12x12x512]的输出(384/32=12)。接下经过来我们刚才从FC层变换而来的CONV层会最终产生大小为[6x6x1000]的输出,因为(12-7)/1+1=6。注意不同于224x224图片得到的为一组标量类型得分,384x384图片得到的是一组大小为6x6的类型得分。

用原始的CNNs(FC没有转换为CONV)以32为步长对384x384图片中的多个224x224区域进行评价的结果和用转换后的CNNs进行评价的结果一致。(这个地方原文比较难懂,其实可以看作是用224滤波器卷积384图片,输出大小为(384-224)/32 + 1 = 6,所以384图片的单个类型得分大小为6x6)

自然的,转换后的CNNs前向传播一次比原始CNNs在36个位置传播一次要高效,因为36次计算是共享参数的。这种技巧经常在实践用于提高性能,例如我们经常放大一张图片(其中很多数据是冗余的),然后用一个转换后的CNNs去评价在多个空间位置上的得分然后取平均值。

最后,当步长小于32像素时如果我们想要高效的处理图片该做什么?我们可以用多次前向传播解决这个问题。比如我们想要用16像素的步长可以这样做:将两次由转换后CNNs前向传播的输出合并,前一次使用原始图片,第二次使用在宽和高上都平移了16个像素的图片。

3.CNNs架构

我们已经看到CNNs一般由三种类型的层构成:CONV,POOL(不特殊申明一般指最大池化)和FC。我们会显式的将RELU激活作为一层,它对所有元素进行非线性操作。在这一部分我们讨论如何堆叠这些层来构建整个CNNs。

3.1 层排列

最常见的CNNs形式是堆叠一些CONV-RELU层,在它们后面添加POOL层,然后不断重复这种模式直到图片被从空间上合并到一个小的尺度。在这之后,经常需要接上一些全连接层,最后一个全连接层保存像类型得分之类的输出。最常见的CNNs架构遵从下面的模式:

INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC

其中的*代表重复,?代表可选项。一般情况下:

N >= 0 && N <=3, M >= 0, K >= 0 && K < 3

下面是一些遵循上述模式的基本CNNs架构:

使用一堆小滤波器的CONV层而不是一个大滤波器的CONV层。

假设你堆叠三个3x3的CONV层(当前每层之间有非线性单元),在这种排列下第一层CONV的每个神经元对输入有3x3的视野。第二层CONV的神经元对第一层CONV有3x3的视野,因此对输入有5x5的视野。类似的,一个第三层CONV的神经元对第二层CONV有3x3的视野,对输入有7x7的视野。

假设不用三个3x3的CONV层,而直接使用一个单独的7x7的CONV层,这样会有很多缺点。首先,这些神经元对输入做线性操作,而三个CONV层含有非线性单元操作使得它们更有表现力。第二,如果我们假设有C个通道,那么7x7的CONV层有C \times (7 \times 7 \times C) = 49 C^2个参数,而三个3x3的CONV层只有3 \times (C \times (3 \times 3 \times C) = 27 C^2个参数。这种方式也有一个缺点,在实践中需要更多的显存在存储BP时中间CONV层的结果。

非线性的层排列 应该注意的是传统的线性排列层的模式已经被挑战了,在Google的Inception构架中和最近的(最先进的)残差网络(Residual Network)中,都采用了与线性排列不同的且更复杂的层连接结构。

在实践用什么架构在ImageNet中效果最好 如果你已经对思考架构选择感到疲劳了,可能会对下面的结论感到高兴,其实90%甚至更多的应用不需要考虑这些问题。对这个问题的总结为“不要逞英雄”:当你在对问题采用什么架构摇摆不定时,应该看看当前ImageNet上表现最好的架构,下载预训练模型然后在你的数据上进行微调。你应该基本没有必要去从头开始训练CNNs或者从头设计CNNs。我也是从Deep Learning school了解这一点的。

3.2 层定制

到目前为止我们没有提及CNNs每类层中常用的超参数。我们首先将会论述一些定制层的常用规则,随后是一些关于规则的讨论:

减少定制层的麻烦。 上述方案是令人愉快的,因为CONV层保持了输入的空间大小,POOL层单独的负责在空间上下采样数据。如果我们在CONV层中用大于1的步长而且不用0填充,那就要特别小心CNNs中每层的输出,保证所有的步长和滤波器能够协同工作。

CONV为什么使用为1的步长? 小的步长在实践中效果更好,而且已经提到过步长为1可以使所有空间上下采样的工作都交给POOL层,CONV层只变换改变输入块的深度。

为什么使用0填充? 除了之前提到的可以在CONV层处理后保持空间大小之外,其实还可以提高性能。如果CONV层不进行0填充而只做有效卷积,那么在CONV后数据会减小,数据边界处的信息会很快被“洗掉”。

对显存限制的妥协。 在某种情况下,使用上述经验使显存消耗增长非常快。例如用64个3x3滤波器且0填充为1的CONV层处理224x224x3的图片,应该生成3D输出块大小为[224x224x64]。这大概有1000万个参数和300万个输出元素,换句话说要消耗大概99MB的显存。因为通常GPU的瓶颈来自显存,所以有必要进行妥协。在实践中,人们一般只在CNNs的第一个CONV层进行妥协,例如ZFNet中的7x7滤波器和步长2,AlexNet中的11x11滤波器和步长4。

3.3 案例学习

下面这些是在CNNs领域中著名的架构:

VGGNet的细节 让我们分析VGGNet的更多细节作为案例教学。整个VGGNet由大小3x3、步长为1、0填充为1的CONV层和大小2x2、步长为2的POOL层组成。我们可以把每一步的数据大小写下来,并追踪数据大小和参数总数:

INPUT: [224x224x3]        memory:  224*224*3=150K   weights: 0
CONV3-64: [224x224x64]  memory:  224*224*64=3.2M   weights: (3*3*3)*64 = 1,728
CONV3-64: [224x224x64]  memory:  224*224*64=3.2M   weights: (3*3*64)*64 = 36,864
POOL2: [112x112x64]  memory:  112*112*64=800K   weights: 0
CONV3-128: [112x112x128]  memory:  112*112*128=1.6M   weights: (3*3*64)*128 = 73,728
CONV3-128: [112x112x128]  memory:  112*112*128=1.6M   weights: (3*3*128)*128 = 147,456
POOL2: [56x56x128]  memory:  56*56*128=400K   weights: 0
CONV3-256: [56x56x256]  memory:  56*56*256=800K   weights: (3*3*128)*256 = 294,912
CONV3-256: [56x56x256]  memory:  56*56*256=800K   weights: (3*3*256)*256 = 589,824
CONV3-256: [56x56x256]  memory:  56*56*256=800K   weights: (3*3*256)*256 = 589,824
POOL2: [28x28x256]  memory:  28*28*256=200K   weights: 0
CONV3-512: [28x28x512]  memory:  28*28*512=400K   weights: (3*3*256)*512 = 1,179,648
CONV3-512: [28x28x512]  memory:  28*28*512=400K   weights: (3*3*512)*512 = 2,359,296
CONV3-512: [28x28x512]  memory:  28*28*512=400K   weights: (3*3*512)*512 = 2,359,296
POOL2: [14x14x512]  memory:  14*14*512=100K   weights: 0
CONV3-512: [14x14x512]  memory:  14*14*512=100K   weights: (3*3*512)*512 = 2,359,296
CONV3-512: [14x14x512]  memory:  14*14*512=100K   weights: (3*3*512)*512 = 2,359,296
CONV3-512: [14x14x512]  memory:  14*14*512=100K   weights: (3*3*512)*512 = 2,359,296
POOL2: [7x7x512]  memory:  7*7*512=25K  weights: 0
FC: [1x1x4096]  memory:  4096  weights: 7*7*512*4096 = 102,760,448
FC: [1x1x4096]  memory:  4096  weights: 4096*4096 = 16,777,216
FC: [1x1x1000]  memory:  1000 weights: 4096*1000 = 4,096,000

TOTAL memory: 24M * 4 bytes ~= 93MB / image (only forward! ~*2 for bwd)
TOTAL params: 138M parameters

在CNNs常见的是大多数的显存开销(计算时间也一样)是使用在开始的几个CONV层中,大多数的参数都在最后几个FC层中。在上面的例子中,第一个FC层包含1亿个权值,整个网络权值大概总共1.4亿个。

3.4 计算开销的注意事项

当构建CNNs架构时最大的瓶颈是显存,很多现代GPU有3/4/6GB的显存限制,最好的GPU大概有12GB显存。有三个主要的显存开销需要跟踪:

一旦你已经粗略的估计了显存开销(激活数据,参数,梯度和杂项),应该将开销大小转化为GB。转化方法是取得这个数值后将它乘以4获得开销的原始字节数量(因为浮点数占4字节,或者使用双精度乘以8),然后除以1024多次获得开销的KB数,MB数和GB数。如果你的网络开销超过硬件限制,一个常用的方法是减小batch的大小,因为大多数显存开销消耗在激活数据上。

4.额外的资源

关于CNNs实现的额外资源:

上一篇下一篇

猜你喜欢

热点阅读