cs231n 学习笔记(6)- 卷积神经网络(CNNs/ConvNets)

目录

1. Architecture Overview

2. ConvNets layers

2.1 Layers used to build ConvNets

2.2 Convolutional layer

2.2.1 Overview

2.3 Pooling layer

2.4 Normalization layer

2.5 Full-connected layer

2.6 Converting FC layers to CONV layers

3. ConvNet Architectures

3.1 Layer pattern

3.2 Layer sizing patterns

3.3 Case studies

3.4 Computational considerations

4. Additional Resources



卷积神经网络和传统的神经网络非常相似:都是由神经元组成,都要为每个神经元学习相应的权重和偏置。每个神经元都要接受输入,将输入与权重进行点乘,之后再经过一个非线性变换得到输出。整个网络拟合了一个可微的打分函数:从最原始的图像到最后的类别得分。在最后一层(全连接层)还包括一个损失函数(例如SVM/softmax)。此外,常规网络的学习技巧同样适用与卷积神经网络。

1. Architecture Overview

回顾传统的神经网络

神经网络接受输入(一个向量),然后通过一些列的变换得到最后的输出。每个隐藏层由一组神经元组成,相邻两层的神经元是全连接的,同一层的神经元是独立且无任何连接的。最后一层的全连接层叫做输出层,用来给出类别得分。

传统的神经网络不太适用于图像

对于CIFAR-10数据集,第一个隐藏层的神经元包括32x32x32=3072个权重;当图像增大时,权重数量会成倍的增长;神经元的数量不止一个;所以传统的神经网络会包括大量的参数,并且非常容易过拟合。

3D神经元

图像由三个维度组成:width,height,channels,与之对应,卷积神经网络ConvNet的神经元也由三个维度组成:width,height,depth。注意:depth指的是激活函数的第三个维度,而不是神经网络的深度。

与全连接网络不同的是,卷积神经网络两层之间只使用部分连接,大大的减少了权重的个数。下图是一个对比图:

                      

左图是3层全连接网络;右图是卷积神经网络。右图中,神经元的输入是3D的图像块,数据在神经元之间的传播也是以3D图像块的形式进行的。

2. ConvNets layers

2.1 Layers used to build ConvNets

卷积神经网络也是由层构成,每层神经网络能够将输入的三维数据转换为输出数据。

常用来组成神经网络的有三种层:卷积层(convolutional layer),池化层(pooling layer),和全连接层(Full-connected layer)

  • Example Architecture. 以一个简单的用来分类CIFAR-10的卷积网络为例,网络结构为[INPUT - CONV - RELU - POOL - FC],具体如下:

    • INPUT [32x32x3]:输入数据为原始图像数据,图像的width和height均为32,是由R,G,B组成的三通道图像

    • CONV layer: 卷积层和输入层的输出相连接,每次计算都是计算权重与输入的局部区域的点乘。如果我们使用12个滤波(也称卷积核),并保证卷积后大小不发生改变,那么输出结果的大小就是[32x32x12]。

    • RELU layer:RELU是逐元素操作的(elementwise),使用函数max(0,x)对每个元素进行操作。经过RELU之后,输出的大小不会改变,仍为[32x32x12]。

    • POOL layer: 池化层在空间维度(width,height)做下采样操作,depth不变,采样后结果为[16x16x12]

    • FC layer: 全连接层计算每个类别的得分,输出大小为[1x1x10]。全连接层的神经元和上一层的每个神经元都有连接。

通过上面的结构,卷积神经网络就可以将原始的数据通过不同的层进行处理和传递,并输出最后的得分。

注意:一些连接层有参数,一些连接层没有参数。卷积层和全连接层具有参数,而池化层和RELU层没有参数。

总结:

  • 卷及网络架构就是由一系列的连接层组成,将输入的图像数据转换成最后的输出。
  • 卷积神经网络包括不同的层:卷积层,池化层,RELU层,全连接层。
  • 每个层都接收三维数据,之后通过处理输出三维数据。
  • 每一层可以包含参数,也可以不包含参数。例如:卷积层和全连接层有参数;池化层和RELU层没有参数。
  • 每一层可以包含超参数,也可以不包含超参数。例如:卷积层、全连接层和池化层有超参数;RELU层没有超参数。

2.2 Convolutional layer

卷积层是卷及网络的核心,大部分的计算量都在这个层。

2.2.1 Overview

卷积层的参数是一组滤波器,每个滤波器是的width和height都比较小,但是滤波器的深depth与输入数据的深度相等。例如,第一层卷积神经网络的滤波器的大小是5x5x3,5代表宽度和高度,3代表深度,与输入图像的3个channel相对应。在前向传播过程中,将卷积核沿着输入数据的宽和高滑动,计算滤波器和输入数据对应的位置的内积。随着滤波器滑过输入数据的宽和高,我们可以得到一个2维的激活图激活图的每个值是卷积核在每个空间位置的响应。直观上看,网络会让卷积核学到“对某些特定物体或颜色产生的激活”。假设我们有一个卷积核的集合,每个卷积核都会生成一个2维激活图,多个卷积核就可以在深度方向上得到输出。

大脑角度:从大脑角度看,每个3维输出都可以看做一个神经元的输出,每个神经元只特定观察到了输入数据的一部分,在空间上和左右两边的神经元进行参数共享。

局部连接:每个神经元只与输入数据的局部区域连接,这个局部区域的大小属于超参数,叫做神经元的感知域receptive field,也就是滤波器/卷积核的大小。卷积核的深度与输入数据的深度一致。

例1:输入数据大小为[32x32x3],如果感知域的大小为5x5,那么每个神经元都会有5x5x3=75个权重参数,以及1个偏置参数,共计76个个参数。

例2:输入数据大小为[16x16x20],如果感知域大小为3x3,那么每个神经元会有3x3x20=180个权重参数。

                                        

上图中,左图输入数据为32x32x3大小的图像块,图中卷积层的神经元只与输入图像的局部区域有连接,卷积层的深度与输入图像一致,可以看出左图中共包括5个神经元,故而输出图像的深度也为5。右图是一个普通的神经元,依旧计算权重和输入数据的点乘,再将其输入到一个非线性函数中。

空间安排:现在我们来介绍如何计算输出数据的大小。决定输出数据的大小的三个超参数包括:深度depth,步长stride,零填充zero-padding的大小。

  • 首先,输出数据的depth是一个超参数,depth = 滤波器(或:卷积核)的数量。不同的滤波器用来查找不同特征。例如,向卷积神经网络中输入图像,不同的神经元被不同的方向的边缘、颜色或特定形状所激活。将一组神经元查看的相同区域组成的输出叫做depth column,深度列。
  • stride指的是滤波器每次滑动的步长。当stride=1时,滤波器每次移动一个像素;当stride=2时,每次移动两个像素。通常在实践中stride不会大于2。stride越大,输出的width和height越小。
  • 我们也可以对输入图像的边缘填充0,这个操作叫作zero-padding。填充的大小也是一个超参数。填0的好处是可以控制输出的大小。通常用zero-padding来保证输出的大小等于输入的大小。

输出大小的计算公式:(W-F+2P)/S+1,其中W代表输入的大小,F代表滤波器的大小,P代表zero-padding的大小,S代表步长。例如,输入为7\times7,滤波器大小为3\times3,stride = 1,zero-padding = 0时,输出为5\times5;stride=2时输出为3\times3

下图给出了一个例子说明卷积计算的过程:

                                         

在上图中,最右边的图是卷积核,卷积核大小F=3;最左边的图输入是5维向量W=5,步长S=1,zero-padding的大小P=1,其输出大小的计算公式为:(5-3+2\times1)/1+1=5,故而输出为5维向量;中间的图是W=5,F=3,S=2,P=1的情况,此时输出大小为3维的向量。注意,当使用S=3时,会出现不能够被整除的情况,不满足输出需要为整数的条件。从图中我们可以看到,在同一幅激活图(输出)上,卷积核的参数并不改变,是共享的。

zero-padding的使用:上图的左图使用了zero-padding,使得输出大小和输入大小相等,均为5。在步长S=1的情况下,通过大小为P = (F-1)/2的zero-padding,就可以保证输出大小与输入大小一致。

步长strides的限制:注意,步长这个超参数有一些限制。例如,当(W-F+2P)/S+1 = (10-3+0)/2+1=4.5的情况下,发现没有被整除,导致神经元不能刚好滑过所有输入数据,那么S=2就是不合适的步长。此时,卷积库可能会报异常,或者通过zero-padding使其满足整除条件,或者对输入数据进行裁剪。

实际案例:AlexNet的输入大小是[227\times227\times3],第一个卷积层使用F=11大小的卷积核,步长S=4,没有使用zero-padding,共使用96个卷积核,故输出深度为K=96,根据公式可以计算输出大小为:(227-11+0)/4+1 = 55,故而输出为[56\times56\times96]大小的图像块。

参数共享机制:卷积神经网络中的参数共享机制极大的减少了参数的数量。以AlexNet的第一个卷积层为例,共有神经元55x55x96=290,400个,如果不使用参数共享,每个神经元有11x11x3=363个权重和1个bias,共有参数290400x364=105,705,600 个。使用参数共享机制,对输出在深度上进行切片,每个切片上使用同一个卷积核,那么参数数量可以降低到:96x11x11x3=34,848权重,加上96个偏置,共计34,944个参数。

这样,在反向传播时,要计算每个神经元的权重的梯度,并在一个深度切片上进行累加,更新时,单独更新每一个深度切片对应的权重。

注意:每个深度切片上对应的神经元使用相同的权重向量,因此前向传播的过程就是卷积的过程,这也是卷积神经网络名称的由来。这也是为什么将一组权重命名为卷积核或者滤波器的原因。

有时参数共享机制并没有意义。例如:当输入图像是中心对称结构,这时我们希望在不同位置学习到不同的特征。一个典型的例子就是人脸检测,如果人脸位于图像的中心,那么我们期望可以在其他位置学到眼睛或头发特征。这种情况下,就需要放宽参数共享机制,将这样的层叫做局部连接层Locallly-Connected Layer

总结:

  • 卷积层的输入数据大小为: W_1 \times H_1 \times D_1
  • 需要使用的超参数: 卷积核个数KK,卷积核大小F ,步长S ,零填充大小P
  • 输出大小为:W_2 \times H_2 \times D_2,计算公式为: 
    • W_2=(W_1 -F +2P)/S+1
    • H_2=(H_1 -F +2P)/S+1
    • D_2=K
  • 使用参数共享机制,每个滤波器的权重个数为: F\cdot F \cdot D_1,一个卷积层共有权重参数(F \cdot F \cdot D_1) \cdot K个,偏置K个。
  • 输出中,在d个深度切片的大小为W_2\times H_2,其结果是第d个卷积核与输入卷积的结果,卷积步长为S。

常用的超参数的设置有:F=3,S=1,P=1。但是具体问题要具体分析。

矩阵相乘的实现:卷积运算就是卷积核与输入数据的局部区域的点乘。常通过矩阵相乘进行实现:

  1. 使用im2col操作,将输入图像按照局部区域展开,每一个局部区域作为一个列向量,并将所有的列向量组成一个矩阵。例如:输入为[227x227x3],卷积核大小为[11x11x3],步长为4,那么我们可以把每个大小为[11x11x3]的小块拉伸成一个363维列向量;由于步长为4,且(227-11)/4+1=55,故而共有55x55=3025个局部区域需要计算,递归的将输入图像的局部小块拉伸成列向量并组合起来,生成一个[363x3025]的矩阵,将其称为X_col
  2. 将卷积核展开为行向量。例如:如果使用96个大小为[11x11x3]的卷积核,那么应该生成一个[96x363]大小的矩阵,将其称为W_row
  3. 那么卷积的结果就等于np.dot(W_row,X_col)。在上述例子中,输出的大小应该为:[96x3025]。
  4. 将第三步的输出重新排列到正确的维度:[55x55x96]。

上述方法的缺点是由于X_col中有重复计算,所以需要使用大量的内存。但是其优点是实现起来非常简单。另外,可以将im2col方法应用到池化层的计算当中。

反向传播:卷积计算的反向传播过程也是卷积计算过程。对于数据和权重都是,但是在空间反转。

1\times 1卷积:论文Network in Network首次提出了1x1卷积,信号处理背景的人可能疑惑,因为通常信号是2维数据,1x1卷积没有意义(只是缩放)。但是在卷积网络中,数据是3维的,滤波器深度和输入数据深度相同。例如输入[32x32x3],使用1x1卷积,是3维的点乘。

Dilated卷积:Fisher Yu and Vladlen Kultun的论文 的论文引入了另外一个超参数叫做dilation。目前为止我们讨论的卷积核都是是连续的,但是我们可以让卷积核的权重之间有间隔。例如,大小为3的卷积核w作用在输入x上,会有:w[0]x[0] + w[1]x[1] + w[2]x[2],这就是dilation=0的情况;如果dilation=1,那么卷积将计算:w[0]x[0] + w[1]x[2] + w[2]x[4]。将Dilated卷积核与正常的卷积结合起来将会非常有用,因为我们可以在很少的层中汇聚到大尺度特征。例如:使用2个3x3卷积,如果第二个卷积使用dilation=1的卷积,那么其对输入数据的感受视野为5x5。可以看出如果使用dilated卷积,感受视野将迅速增长。

2.3 Pooling layer

在卷积神经网络中,通常周期性的在连续的卷积层中穿插使用池化层。池化层的作用是降低维度,并且能够减少参数的数量和神经网络的计算量,进而减少过拟合。

池化操作作用在输入数据的深度切片上,对其进行放缩。常用的池化是2x2大小的最大池化,即:将大小为2x2的滤波器作用在输入图像上,步长S=2,在每个深度切片的width和height方向上进行下采样,忽略掉75%的激活信息。池化操作保持深度depth不变。

池化层:

  • 输入的大小为W_1 \times H_1 \times D_1
  • 池化层具有两个超参数:卷积核的大小F,步长S
  • 池化层的输出大小为:\bg_black W_2 \times H_2 \times D_2,计算公式为:
    • W_2 =(W_1 - F)/S +1
    • H_2 =(H_1 - F)/S +1
    • D_2 = D_1
  • 池化层没有参数
  • 在池化层中通常不使用zero-padding操作

经常使用的池化层类型有:F=3,S=2(有重叠池化);F=2,S=2,这个比较常见。注意:池化层越大,则对激活信息的破坏程度越大。

常用的池化:除了最大池化外,还有其他的池化操作,如:平均池化和L2-norm池化。但使用的并不多,因为相对而言,都没有最大池化的效果好。

下图给出了池化的示意图。左图输入数据的大小为[224x224x64],经过F=2,S=2的池化操作后,输出[112x112x64]大小的图像块。注意,经过池化操作后,深度不发生改变。右图给出了使用最大池化进行降采样操作的示意图。

                                           

反向传播:前面提到,对于max(x,y)的前向传播,只允许值大的通过;反向传播时只允许值大的输入的梯度反向传播。因此,池化层前向传播时记录下值大者的索引(有时叫做switches),这样反向传播就很高效。

不使用池化层:许多人不喜欢池化层,并建议不使用池化层。例如:Striving for Simplicity: The All Convolutional Net在架构中只是用卷积层,不使用池化层,通过采用大步长的卷积来减少数据的大小。此外,为了训练一个好的生成网络,可以去掉池化层,例如自编码(VAEs)或生成对抗网络(GANs:generative adversarial networks)。在未来的架构中,不使用池化层的可能性比较小。

2.4 Normalization layer

在神经网络架构中可以使用多种类型的归一化层。但Normalization layer的作用非常有限,故而实际中逐渐被放弃。想了解归一化层,可以参考cuda-convnet library API.

2.5 Full-connected layer

全连接层中的神经元与上一层神经元都有连接。故而可以通过矩阵乘法进行计算。

2.6 Converting FC layers to CONV layers

需要注意的是,全连接层和卷积层唯一的区别在于:卷积层只与输入的局部区域有连接,并且卷积层中使用参数共享机制。但是无论全连接层还是卷积层,他们都是用了点乘进行计算,它们函数形式是一致的。因此,它们可以相互转换:

  • 用全连接层来替换卷积层:替换后的权重矩阵非常大,并且包括很多0,只有有局部连接的地方权重才不为0;另外,由于参数共享机制,导致替换后的权重矩阵中有很多相同的权重块。

  • 用卷积层来替换全连接层:例如对于一个全连接层K=4096,输入为7×7×512,可以转换为一个卷积层,其中卷积核的大小为F=7,不使用零填充P=0,步长为S=1,卷积核个数为K=4096。

FC -> Conv 转换:

在实际过程中,将全连接层转换为卷积层非常有用。例如,以AlexNet架构为例,使用224x224x3的图像作为输入,经过一些列的卷积核池化层,可以得到7x7x512大小的输出;随后,通过2个大小为4096的全连接层;最后通过一个包括1000个神经元的全连接层得到类别得分。我们可以将AlexNet架构中的3个全连接层转换为卷积层,具体如下:

  • 使用包括4096个[7x7x512]大小的卷积核的卷积层,替换掉第一个全连接网络,得到[1x1x4096]大小的输出
  • 使用包含4096个大小为F=1的卷积核的卷积层,替换掉第二个全连接网络,得到[1x1x4096]大小的输出。
  • 使用包含1000个大小为F=1的卷积核的卷积层,替换掉最后一个全连接网络,得到[1x1x1000]大小的输出

上述的所有卷转都需要操作(例如reshape)权重矩阵W。将全连接层替换成卷积层,可以使得计算更高效。

3. ConvNet Architectures

卷积神经网络通常由刚刚介绍的的三种层组成,分别为:卷积层、池化层和全连接层。我们也可以将Relu激活函数作为一个层,叫做激活层。本节,将介绍如何将他们组成一个完整神经网络架构。

3.1 Layer pattern

卷积神经网络最常见的架构是:连续几个CONV-RELU,后面跟着一个POOL;重复这样的结构几次,直到输出比较小,在某一位置使用FC。最后一个FC输出结果,例如类别得分。即常见的模式为:

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

其中,*代表重复,POOL?代表池化层是可选项。常用的取值范围有:N\geqslant 0并且通常N \leqslant 3M\geqslant 0K\geqslant 0并且通常K < 3。例如,下面给出一些常见的网络结构:

  • INPUT->FC:实现了线性分类器,其中N=M=K=0
  • INPUT->CONV->RELU->FC
  • INPUT->[CONV->RELU->POOL]*2->FC->RELU,每隔一个卷积层就会有一个池化层
  • INPUT->[CONV->RELU->CONV->RELU->POOL]*3->[FC->RELU]*2->FC,每隔2个卷积层有一个池化层。多次堆叠卷积层能够提取更复杂的特征,减少池化带来的信息损失,对大型、较深的网络有很大好处。

用多层使用较小的滤波器替代在一层中使用较大的滤波器。假设堆叠3层使用3x3大小滤波器的卷积层,这样第一层卷积层的感知域大小为3x3;第二层卷积层的感知域也是3x3,但是两层加在一起感知域就被扩展为5x5; 到了第三层,三次叠加在一起的感知域就相当于7x7。和单层使用7x7大小的卷积层具有相同大小的感知域。但使用单层、卷积核较大的卷积层的有以下几个缺点:1. 一层对于输入来说是线性计算,三层堆叠在一起会具有很好的非线性,具有更强的表达能力;2. 假设channel数为C,对于一层7x7卷积层,共有权重C×(7×7×C)=49C,而三层3x3卷积层,共有参数3×(C×(3×3×C))=27C。可以看出,连续的小卷积核,具有更少的参数和更强的表达能力。但是使用连续小的卷积核在训练时会占用更多内存,因为在反向传播时需要用到中间结果。

最新进展 
上面提到的按照顺序堆叠网络设计卷积神经网络的方法已经受到挑战。例如:来自Google的Inception架构和来自微软的Residual Networks没有按照上面的方法设计网络结构,而是采用了更为复杂的结构设计。

实践经验:使用在ImageNet上表现最好的网络结构

注意:90%的应用当中,我们并不需要过多的思考如何设计网络架构。通常的方法是,找到在ImageNet挑战赛上表现性能好的网络,下载对应的预训练模型,然后用自己数据finetune。只有极少的情况才需要我们从头设计和训练。

3.2 Layer sizing patterns

目前为止,我们还没有介绍卷积神经网络中的超参数。接下来首先介绍一下设置这些超参数的一些规则:

输入层:输入层需要能够被2整除多次。常见的输入大小为32(例如:CIFAR-10数据集),64,96(例如STF-10数据集),或224(ImageNet),384,或512。

卷积层:卷积层需要使用较小的滤波器(例如:3x3或者最多5x5),使用步长S=1。当需要保持输出大小等于输入大小时,使用zero padding。例如,当F=3时,使用P=1进行填充;当F=5时,使用P=2进行填充,进而保持输出的大小不变。更一般的,填充大小的计算公式为:P=(F-1)/2。如果必须使用大的滤波器,如7*7大小或者更大的,通常建议将其使用在第一层中。

池化层:池化层用对输入数据进行下采样。最常见的是:2x2大小的最大池化(即:F=2),且步长S=2。注意,这将丢弃75%的激活信息。还有一个也比较常见的,F=3,S=2。很少使用更大的池化层,因为池化层会丢弃特征,太大的池化层影响性能。

减少尺寸设计问题

前面设计中,卷积层的输出的heigh和width与输入保持一致,只有池化层对数据进行下采样。但是,如果我们使用步长大于1或不使用零填充,那么池化层也会引起height和width的减小。需要注意的是,此时我们需要认真设计,确保数据和卷积核的大小匹配。

为什么使用步长S=1的卷积?

实践中步长越小效果越好;并且使用步长S=1,可以将所有的下采样操作都留给池化层来做,使得卷积层只用来改变深度。

为什么使用零填充?

使用零填充,除了可以保障卷积后的输出与输入的大小一致外,还可以提高性能。如果在卷积层不使用padding,经过卷积后,数据空间的维度会略微减小,导致图像边缘处的信息会迅速丢失。

注意内存的限制,必要时刻要妥协

卷积神经网络内存消耗非常快。例如:输入图像为224x224x3,使用64个大小为3x3的卷积核,zero-padding的大小为P=1,那额将会输出224x224x64大小的激活值,大约有1千万个激活值,约占用72M内存(每张图像,对于激活和梯度都是如此)。由于GPU显存的限制,常常要做出妥协。实践中,通常在第一层做出妥协,例如ZFnet第一层卷积核大小为7x7,步长为2;AlexNet第一层卷积核的大小为7x7,步长为4。

3.3 Case studies

常用的卷积神经网络的架构有:

  • LeNet:第一个成功的卷积网络架构,由Yann LeCun在九十年代发明,已经应用到邮政编码和数字识别
  • AlexNet:AlexNet第一个在计算机视觉领域开始流行的架构。由Alex Krizhevsky, Ilya Sutskever and Geoff Hinton发明,在2012年的 ImageNet ILSVRC中获得冠军,识别率远远超过第二名(top 5 错误了16%,第二名为26%)。相对于LeNet,AlexNet更深更广,它使用了连续的CONV-POOL堆叠(之前都是CONV后立刻跟着POOL)。
  • ZF Net:2013 ILSVRC获胜者使用的网络架构。ZF Net是其发明者Zeiler和Rob Fergus的缩写。该网络是基于AlexNet进行微调,扩大了中间卷积层的尺寸,减小了第一个卷积层的卷积核和步长的大小。
  • GoogleNet: 2014 ILSVRC获胜者。主要的贡献是发明了Inception Module,能够大幅度的减小参数的数量(4M,相对于AlexNet的60M)。此外,在网络的上层使用平均池化替代了全连接层,旨在消除无用参数的作用。GoogleNet有很多改进变种,例如Inception-v4
  • VGGNet: 2014 ILSVRC的亚军是VGGNet。VGGNet的贡献是:证明了深度对于卷积网络性能的重要性。他们最优的网络是16层的卷积/全连接层组成的结构,从输入到输出层结构相同,只使用3x3卷积核2x2池化。预训练模型可以在caffe上直接使用。其缺点是计算非常耗资源和内存,参数占用的内存大约为140M。大部分的参数位于第一个全连接层,后来发现可以移去这些全连接层,并且性能几乎不会收到影响,因此减少了参数个数。
  • ResNet:Residual Network获得了2015 ILSVRC的冠军。它的特点是大量使用了batch normalization可以跳过一些连接。ResNet在网络的末端没有使用全连接层;可以参考Kaiming的报告(videoslides)。它是目前(2016.5.10)最好的卷积神经网络。可以参考最近最这个网络的优化模型:Kaiming He et al. Identity Mappings in Deep Residual Networks 。

(立个Flag:这周要啃论文,弄懂这些网络结构~)

VGGNet详解:

整个VGG NET的卷积层都使用:3x3大小的卷积核,步长为1,zero-padding填充为1;所有池化层都是2x2大小,步长为2。可以将VGGNet每步的输出,输出占用内存情况、及参数的个数详细表示出来:

INPUT:[224x224x3]memory:224x224x3=150Kweights:0
CONV3-64:[224x224x64]memory:224x224x64=3.2Mweights:(3x3x3)x64 
CONV3-64:[224x224x64]memory:224x224x64=3.2Mweights:(3x3x64)x64 
POOL2:[112x112x64]memory:112x112x64=800Kweights:0
CONV3-128:[112x112x128]memory:112x112x128=1.6Mweights:(3x3x64)x128
CONV3-128:[112x112x128]memory:112x112x128=1.6Mweights:(3x3x128)x128
POOL2:[56x56x128]memory:56x56x128=400Kweights:0
CONV3-256:[56x56x256]memory:56x56x256=800Kweights:(3x3x128)x256
CONV3-256:[56x56x256]memory:56x56x256=800Kweights:(3x3x256)x256
CONV3-256:[56x56x256]memory:56x56x256=800Kweights:(3x3x256)x256
POOL2:[28x28x256]memory:28x28x256=200Kweights:0
CONV3-512:[28x28x512]memory:28x28x512=400Kweights:(3x3x256)x512
CONV3-512:[28x28x512]memory:28x28x512=400Kweights:(3x3x512)x512
CONV3-512:[28x28x512]memory:28x28x512=400Kweights:(3x3x512)x512
POOL2:[14x14x512]memory:14x14x512=100Kweights:0
CONV3-512:[14x14x512]memory:14x14x512=100Kweights:(3x3x512)x512
CONV3-512:[14x14x512]memory:14x14x512=100Kweights:(3x3x512)x512
CONV3-512:[14x14x512]memory:14x14x512=100Kweights:(3x3x512)x512
POOL2:[7x7x512]memory:7x7x512=25Kweights:0
FC: [1x1x4096]memory:4096weights: 7x7x512x4096=102,760,448
FC: [1x1x4096]memory:4096weights: 4096x4096 = 16,777,216
FC: [1x1x1000]memory:1000weights: 4096x1000 = 4,096,000
   
Total Memeory: 24M x 4 bytes -=93M/image (only forward! -----   *2 for backward)
Total params: 138Million parameters

注意,在卷积神经网络中,大部分的内存都被消耗在前面的卷积层,而大部分的参数则出现在全连接层。在上面的VGGNet中,全连接层包括约100 Million的参数,总参数数目约为140 Million。

3.4 Computational considerations

注意:构建卷积神经网络的最大限制就是内存的限制。时下GPU的显存一般为3/4/6GB,好一些的可以达到128GB。内存的消耗主要来自以下三种情况:

  • 中间结果:每个卷积层都有激活的原始数据和对应梯度(它们大小相同),大部分的激活数据出现在网络的前面几个卷积层中,例如第一个卷积层;因为在反向传播时需要使用这些数据,因此需要被保存下来。但是在测试时就可以释放前面激活层数据占用的内存。
  • 参数:网络需要保存大量的数值,包括:网络中包括的大量参数、反向传播时的梯度等。如果使用momentum,Adagrad,RMSProp还要记录一步缓存。所以参数存储空间要在最原始基础上乘以3甚至更多。
  • 卷积网络实现。实现还要占用各种混杂(miscellaneous)内存,例如图像数据batch等。

当估算好这些值的总数total number后,需要将其转换为GB。对total number乘以4 bytes (如果是双精度则乘以8bytes),再除以1024^3将其转为GB。如果所需内存超过限制,则需要调整网络,例如:减少batch size,因为大部分内存是被激活函数所消耗的。

4. Additional Resources

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值