如何计算卷积神经网络的参数数量?

45

我无法给出AlexNetVGG Net的正确参数数量。

例如,要计算VGG Net中conv3-256层的参数数量,答案是0.59M = (3*3)*(256*256),即(卷积核大小)*(联合层中通道数量的乘积),然而按照这种方式,我无法得到138M个参数。

所以请您告诉我哪里出错了,或者提供正确的计算步骤?


1
请提供所有层的完整计算,以便我们看到问题出在哪里。以下是一个起点,可以了解如何计算总数:http://learning.eng.cam.ac.uk/pub/Public/Turner/Teaching/ml-lecture-3-slides.pdf - runDOSrun
讲座第10张幻灯片中的 S 代表什么?下采样的 Stride 吗?@runDOSrun - nn0p
2
这是我对类似问题的回答:https://dev59.com/aF0a5IYBdhLWcg3wYXu8#39687866。如果您正在使用Caffe,可以编写一个简单的Python脚本来计算参数的总数。请参阅https://gist.github.com/kaushikpavani/a6a32bd87fdfe5529f0e908ed743f779。 - Kaushik Pavani
5个回答

67
如果您参考的是16层的VGG Net(表1,列D),那么138M是指该网络的参数总数,即包括所有卷积层和全连接层。观察由3个conv3-256层组成的第3个卷积阶段:
  • 第一个具有N=128的输入面板和F=256输出面板,
  • 另外两个具有N=256的输入面板和F=256输出面板。
这些层的卷积核都是3x3。就参数而言,这样可以得到以下结果:
  • 第一个有295,168个参数,其中128x3x3x256(权重)+ 256(偏差)= 295,168个参数
  • 后两个共有590,080个参数,每个都有256x3x3x256(权重)+ 256(偏差)= 590,080个参数。
正如上面所解释的,您必须对所有层以及全连接层执行此操作,并将这些值相加以获取最终的138M数字。
-更新:各层之间的分割如下:
conv3-64  x 2       : 38,720
conv3-128 x 2       : 221,440
conv3-256 x 3       : 1,475,328
conv3-512 x 3       : 5,899,776
conv3-512 x 3       : 7,079,424
fc1                 : 102,764,544
fc2                 : 16,781,312
fc3                 : 4,097,000
TOTAL               : 138,357,544

特别是对于全连接层(fc):

 fc1 (x): (512x7x7)x4,096 (weights) + 4,096 (biases)
 fc2    : 4,096x4,096     (weights) + 4,096 (biases)
 fc3    : 4,096x1,000     (weights) + 1,000 (biases)

(x) 请参阅文章的第3.2节:全连接层首先被转换为卷积层(第一个FC层变成7×7的卷积层,最后两个FC层变成1×1的卷积层)。

fc1的详细信息

如上所述,在将输入传递给全连接层之前,空间分辨率为7×7像素。这是因为该VGG Net在卷积之前使用了空间填充,详见论文第2.1节:

[...]卷积层输入的空间填充使得在卷积之后空间分辨率得以保留,即对于3×3的卷积层来说,填充应为1个像素。

通过这样的填充,并且使用224×224像素的输入图像,在最后一个卷积/池化阶段之后,分辨率会按以下方式降低:512个特征映射的112×112、56×56、28×28、14×14和7×7。

这给出了一个具有512x7x7维度的特征向量,传递给fc1


我只是为了好玩而使用相同的假设来运算,但结果并没有得到138M。可能是因为我在这个相当长的表达式中打错了一个字母。 - runDOSrun
1
卷积层参数为14,714,688,全连接层参数为123,642,856,总共为138M。 - deltheil
“fc1” 的填充问题正是我卡住的地方。非常感谢您提供如此详细的解释。 - Eric
在今天的架构中,我们是否应该包括批量归一化/缩放层的参数? 在caffe中,BN层被分成两个BN和scale层。这实际上会使参数数量翻倍,我想。 因此,像BN(caffe风格)和drop-out这样的层也需要包括在这个计算中吗? - Hossein
1
@deltheil:在这样的架构中,如何计算操作(乘/加)的数量? - Hossein

48

CS231n课程笔记中,对VGG-16网络的计算进行了很好的解析。

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

1
@Ray:我们有没有Python/Matlab脚本可以自动计算这些总参数?谢谢。 - John
CNN的计算成本与参数直接相关吗? - Aadnan Farooq A
2
嗨,@Ray。你能告诉我如何获取“TOTAL memory: 24M”吗? - roachsinai
@Ray,请问你能指出生成这个输出的代码吗? - Anu

5
下面的VGG-16架构在原始论文中由@deltheil在(表1,D列)中突出显示, 我从那里引用。

2.1 架构

在训练过程中,我们的ConvNets的输入是固定大小的224 × 224 RGB图像。我们唯一的预处理是从每个像素中减去在训练集上计算得出的平均RGB值。

图像通过一堆卷积(conv.)层传递,其中我们使用具有非常小的感受野的滤波器:3×3(这是捕捉左/右、上/下、中心概念的最小尺寸)。卷积步幅固定为1像素;对于3×3 conv.层,卷积层输入的空间填充使得空间分辨率在卷积后保持不变,即对于3×3 conv.层,填充为1像素。空间池化由五个最大池化层执行,这些层遵循一些卷积层(并非所有卷积层都跟随最大池化)。最大池化在2×2像素窗口上执行,步幅为2。

一堆卷积层(在不同的架构中具有不同的深度)后面是三个全连接(FC)层:前两个分别具有4096个通道,第三个执行1000路ILSVRC分类,因此包含1000个通道(每个类别一个)。

最后一层是软最大化层。

使用上述内容,以及
  • 一种公式来查找层的激活形状!

  • 计算每层权重的公式:

注意:

  • 你可以简单地将相应的激活形状列相乘以获取激活大小。

  • CONV3:意味着一个3*3的过滤器将在输入上进行卷积!

  • MAXPOOL3-2:意味着第三个池化层,使用2*2的过滤器,步幅为2,填充为0(在池化层中非常标准)。

  • 阶段-3:意味着它有多个堆叠的CONV层!具有相同的填充=1,步幅=1和过滤器3*3。

  • Cin:表示来自输入层的深度,也称为通道!

  • Cout:表示深度,即出站(您可以以不同方式配置它,以学习更复杂的功能!),

Cin和Cout是您堆叠在一起以在不同比例上学习多个特征的过滤器数量,例如在第一层中,您可能希望学习垂直边缘、水平边缘和45度的边缘等等,64种不同类型的边缘过滤器!!

  • n:输入维度,不包括深度,例如输入图像的n=224!

  • p:每层的填充

  • s:每层使用的步幅

  • f:过滤器大小,例如CONV的3*3和MAXPOOL层的2*2!

  • 在MAXPOOL5-2之后,您只需将卷积体展平并将其与第一个FC层接口即可!

我们得到表格: enter image description here

最后,如果您将最后一列中计算的所有权重相加,您将得到138,357,544(1.38亿)个参数,用于训练VGG-15!


2

以下是计算每个CNN层参数数量的方法:
一些定义
n--过滤器宽度
m--过滤器高度
k--输入特征图数
L--输出特征图数
那么参数数量 #= (n*m*k+1)*L,其中第一个部分来自权重,第二个部分来自偏置。


1
我知道这是一个旧帖子,但我认为@deltheil的被接受答案包含一个错误。如果不是,我很乐意被纠正。卷积层不应该有偏置。 即 128x3x3x256(权重)+ 256(偏置)= 295,168 应该是 128x3x3x256(权重)= 294,9112 谢谢

你应该将评论添加到答案中。 - Sahil Mittal
是的,我想这样做,但由于声誉的原因无法实现。 - rav
1
请纠正我如果我错了,但默认情况下Caffe在卷积层[1]中使用偏置项(bias_term [默认为true]),而官方VGG 16预训练模型[2]也使用了这种默认方式(在图层定义中没有bias_term:false)。[1]:http://caffe.berkeleyvision.org/tutorial/layers/convolution.html [1]:https://gist.githubusercontent.com/ksimonyan/211839e770f7b538e2d8/raw/0067c9b32f60362c74f4c445a080beed06b07eb3/VGG_ILSVRC_16_layers_deploy.prototxt - deltheil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接