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

我正在使用 Lasagne 为 MNIST 数据集创建一个 CNN。

我现在使用的 CNN 架构,不包括任何退出层,它是:

NeuralNet(
layers=[('input', layers.InputLayer),        # Input Layer
('conv2d1', layers.Conv2DLayer),     # Convolutional Layer
('maxpool1', layers.MaxPool2DLayer), # 2D Max Pooling Layer
('conv2d2', layers.Conv2DLayer),     # Convolutional Layer
('maxpool2', layers.MaxPool2DLayer), # 2D Max Pooling Layer
('dense', layers.DenseLayer),        # Fully connected layer
('output', layers.DenseLayer),       # Output Layer
],
# input layer
input_shape=(None, 1, 28, 28),


# layer conv2d1
conv2d1_num_filters=32,
conv2d1_filter_size=(5, 5),
conv2d1_nonlinearity=lasagne.nonlinearities.rectify,


# layer maxpool1
maxpool1_pool_size=(2, 2),


# layer conv2d2
conv2d2_num_filters=32,
conv2d2_filter_size=(3, 3),
conv2d2_nonlinearity=lasagne.nonlinearities.rectify,


# layer maxpool2
maxpool2_pool_size=(2, 2),




# Fully Connected Layer
dense_num_units=256,
dense_nonlinearity=lasagne.nonlinearities.rectify,


# output Layer
output_nonlinearity=lasagne.nonlinearities.softmax,
output_num_units=10,


# optimization method params
update= momentum,
update_learning_rate=0.01,
update_momentum=0.9,
max_epochs=10,
verbose=1,
)

它输出以下层信息:

  #  name      size
---  --------  --------
0  input     1x28x28
1  conv2d1   32x24x24
2  maxpool1  32x12x12
3  conv2d2   32x10x10
4  maxpool2  32x5x5
5  dense     256
6  output    10

输出可学习参数的个数为 217,706

我想知道这个数字是怎么计算出来的?我已经阅读了许多资源,包括 StackOverflow 的 有个问题,但是没有一个清楚地概括了计算。

如果可能的话,每层可学习参数的计算能否推广?

例如,卷积层: 滤波器的数量 x 滤波器的宽度 x 滤波器的高度。

86599 次浏览

让我们首先看一下如何为每个单独类型的层计算可学习参数的数量,然后计算示例中的参数数量。

  • 输入层 : 输入层所做的就是读取输入图像,所以这里没有可以学习的参数。
  • 卷积层 : 考虑一个卷积层,它在输入端接受 l特征映射,并将 k特征映射作为输出。过滤器的大小是 n x m。例如,这看起来像这样:

    Visualization of a convolutional layer

    这里输入 l=32特征映射作为输入,k=64特征映射作为输出,滤波器大小为 n=3 x m=3。重要的是要明白,我们不仅仅有一个3x3的过滤器,而是一个3x3x32的过滤器,因为我们的输入有32个维度。我们学习了64种不同的3x3x32过滤器。 因此,权重的总数是 n*m*k*l。 然后,对于每个特征映射还有一个偏差项,所以我们得到了 (n*m*l+1)*k的参数总数。

  • 池层 : 池层执行以下操作,例如: “用邻居的最大值替换一个2x2的邻居”。因此,在池层中没有可以学习的参数。
  • 完全连接层 : 在完全连接层中,所有输入单元对每个输出单元都有单独的权重。对于 n输入和 m输出,权值的个数是 n*m。另外,对于每个输出节点都有一个偏置,因此处于 (n+1)*m参数。
  • 输出层 : 输出层是一个普通的完全连接层,因此 (n+1)*m参数,其中 n是输入数,m是输出数。

最后一个困难是第一个完全连接的层: 我们不知道该层的输入的维数,因为它是一个卷积层。为了计算它,我们必须从输入图像的大小开始,并计算每个卷积层的大小。在您的情况下,千层面已经为您计算和报告的大小-这使我们很容易。如果你必须自己计算每一层的大小,那就有点复杂了:

  • 在最简单的例子中(如您的例子) ,卷积层的输出大小是 input_size - (filter_size - 1),在您的例子中是: 28-4 = 24。这是由于卷积的本质: 我们使用一个5x5的邻域来计算一个点——但是最外面的两行和两列没有一个5x5的邻域,所以我们不能计算这些点的任何输出。这就是为什么我们的输出是2 * 2 = 4行/列小于输入。
  • 如果不希望输出小于输入,可以对图像进行零点填充(使用 Lasagne 中卷积层的 pad参数)。例如,如果在图像周围添加2行/2个零,输出大小将是(28 + 4)-4 = 28。所以在填充的情况下,输出大小是 input_size + 2*padding - (filter_size -1)
  • 如果你想在卷积过程中缩小图像采样范围,你可以定义一个步长,例如 stride=2,这意味着你需要以2像素的步长移动滤波器。然后,表达式变成 ((input_size + 2*padding - filter_size)/stride) +1

在您的例子中,完整的计算是:

  #  name                           size                 parameters
---  --------  -------------------------    ------------------------
0  input                       1x28x28                           0
1  conv2d1   (28-(5-1))=24 -> 32x24x24    (5*5*1+1)*32   =     832
2  maxpool1                   32x12x12                           0
3  conv2d2   (12-(3-1))=10 -> 32x10x10    (3*3*32+1)*32  =   9'248
4  maxpool2                     32x5x5                           0
5  dense                           256    (32*5*5+1)*256 = 205'056
6  output                           10    (256+1)*10     =   2'570

所以在你的网络中,你总共有832 + 9’248 + 205’056 + 2’570 = 217’706个可学习的参数,这正是 Lasagne 所报道的。

建立在@hbadert 的出色回复之上,刚刚提出了一个 I-C-P-C-P-H-O 网络的公式(因为我正在研究一个类似的问题) ,在下面的图中分享它,可能会有帮助。

enter image description here

此外,(1)2x2步长的卷积层和(2)1x1步长的卷积层 + (max/avg)2x2步长的合并卷积层,每个卷积层提供相同数量的参数,具有“相同”填充,如下图所示:

enter image description here

卷积层尺寸为 calculated=((n+2p-k)/s)+1

给你,

  • N 是输入 p 是填充 k 是内核或者过滤器 s 是步长

在上面的例子中

  • N = 28p = 0k = 5s = 1