如何计算卷积神经网络的参数个数?
How to calculate the number of parameters for convolutional neural network?
我正在使用千层面为 MNIST 数据集创建 CNN。我正在密切关注这个例子:Convolutional Neural Networks and Feature Extraction with Python.
我目前的 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
我想知道这个数字是如何计算出来的?我已经阅读了很多资源,包括这个 Whosebug 的 ,但是 none 清楚地概括了计算。
如果可以的话,每层可学习参数的计算是否可以泛化?
例如卷积层:滤波器个数 x 滤波器宽度 x 滤波器高度。
让我们先看看如何为您拥有的每种层类型计算可学习参数的数量,然后计算您的示例中的参数数量。
- 输入层:输入层所做的只是读取输入图像,所以这里没有你可以学习的参数。
卷积层:考虑一个卷积层,它在输入处采用l
个特征图,并且具有k
个特征图作为输出。过滤器大小为 n
x m
。例如,这将如下所示:
此处,输入有 l=32
个特征图作为输入,k=64
个特征图作为输出,滤波器大小为 n=3
x m=3
。重要的是要理解,我们不只是有一个 3x3 过滤器,实际上是一个 3x3x32 过滤器,因为我们的输入有 32 个维度。我们学习了 64 个不同的 3x3x32 过滤器。
因此,权重总数为n*m*k*l
。
然后,每个feature map还有一个bias term,所以我们总共有(n*m*l+1)*k
.
个参数
- 池化层:池化层,例如执行以下操作:"replace a 2x2 neighborhood by its maximum value"。所以没有你可以在池化层中学习的参数。
- 全连接层:在全连接层中,所有输入单元对每个输出单元都有单独的权重。对于
n
个输入和 m
个输出,权重数为 n*m
。此外,每个输出节点都有偏差,因此您处于 (n+1)*m
个参数。
- 输出层:输出层是普通的全连接层,所以
(n+1)*m
个参数,其中n
是输入个数,m
是输出的数量。
最后的难点是第一个全连接层:我们不知道该层输入的维数,因为它是一个卷积层。要计算它,我们必须从输入图像的大小开始,计算每个卷积层的大小。对于您的情况,Lasagne 已经为您计算并报告尺寸 - 这对我们来说很容易。如果要自己计算每一层的大小,那就有点复杂了:
- 在最简单的情况下(如您的示例),卷积层的输出大小为
input_size - (filter_size - 1)
,在您的情况下:28 - 4 = 24。这是由于卷积的性质: 我们使用例如一个 5x5 邻域来计算一个点 - 但最外面的两个行和列没有 5x5 邻域,因此我们无法计算这些点的任何输出。这就是为什么我们的输出比输入小 2*2=4rows/columns。
- 如果不希望输出小于输入,可以对图像进行零填充(使用 Lasagne 中卷积层的
pad
参数)。例如。如果在图像周围添加 2 rows/cols 个零,则输出大小将为 (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 报告的内容。
在@hbaderts 的优秀回复的基础上,刚刚想出了一些 I-C-P-C-P-H-O 网络的公式(因为我正在处理类似的问题),在下图中分享它,可能会有所帮助。
此外,(1) 步幅为 2x2 的卷积层和 (2) 步幅为 1x1 的卷积层 + (max/avg) 步幅为 2x2 的池化,每个都贡献相同数量的参数,并使用 'same' 填充,如下所示:
卷积层大小为calculated=((n+2p-k)/s)+1
这里,
- n 是输入 p 是填充 k 是内核或过滤器 s 是步长
在上面的例子中
- n=28 p=0 k=5 s=1
我正在使用千层面为 MNIST 数据集创建 CNN。我正在密切关注这个例子:Convolutional Neural Networks and Feature Extraction with Python.
我目前的 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
我想知道这个数字是如何计算出来的?我已经阅读了很多资源,包括这个 Whosebug 的
如果可以的话,每层可学习参数的计算是否可以泛化?
例如卷积层:滤波器个数 x 滤波器宽度 x 滤波器高度。
让我们先看看如何为您拥有的每种层类型计算可学习参数的数量,然后计算您的示例中的参数数量。
- 输入层:输入层所做的只是读取输入图像,所以这里没有你可以学习的参数。
卷积层:考虑一个卷积层,它在输入处采用
l
个特征图,并且具有k
个特征图作为输出。过滤器大小为n
xm
。例如,这将如下所示:此处,输入有
l=32
个特征图作为输入,k=64
个特征图作为输出,滤波器大小为n=3
xm=3
。重要的是要理解,我们不只是有一个 3x3 过滤器,实际上是一个 3x3x32 过滤器,因为我们的输入有 32 个维度。我们学习了 64 个不同的 3x3x32 过滤器。 因此,权重总数为n*m*k*l
。 然后,每个feature map还有一个bias term,所以我们总共有(n*m*l+1)*k
. 个参数
- 池化层:池化层,例如执行以下操作:"replace a 2x2 neighborhood by its maximum value"。所以没有你可以在池化层中学习的参数。
- 全连接层:在全连接层中,所有输入单元对每个输出单元都有单独的权重。对于
n
个输入和m
个输出,权重数为n*m
。此外,每个输出节点都有偏差,因此您处于(n+1)*m
个参数。 - 输出层:输出层是普通的全连接层,所以
(n+1)*m
个参数,其中n
是输入个数,m
是输出的数量。
最后的难点是第一个全连接层:我们不知道该层输入的维数,因为它是一个卷积层。要计算它,我们必须从输入图像的大小开始,计算每个卷积层的大小。对于您的情况,Lasagne 已经为您计算并报告尺寸 - 这对我们来说很容易。如果要自己计算每一层的大小,那就有点复杂了:
- 在最简单的情况下(如您的示例),卷积层的输出大小为
input_size - (filter_size - 1)
,在您的情况下:28 - 4 = 24。这是由于卷积的性质: 我们使用例如一个 5x5 邻域来计算一个点 - 但最外面的两个行和列没有 5x5 邻域,因此我们无法计算这些点的任何输出。这就是为什么我们的输出比输入小 2*2=4rows/columns。 - 如果不希望输出小于输入,可以对图像进行零填充(使用 Lasagne 中卷积层的
pad
参数)。例如。如果在图像周围添加 2 rows/cols 个零,则输出大小将为 (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 报告的内容。
在@hbaderts 的优秀回复的基础上,刚刚想出了一些 I-C-P-C-P-H-O 网络的公式(因为我正在处理类似的问题),在下图中分享它,可能会有所帮助。
此外,(1) 步幅为 2x2 的卷积层和 (2) 步幅为 1x1 的卷积层 + (max/avg) 步幅为 2x2 的池化,每个都贡献相同数量的参数,并使用 'same' 填充,如下所示:
卷积层大小为calculated=((n+2p-k)/s)+1
这里,
- n 是输入 p 是填充 k 是内核或过滤器 s 是步长
在上面的例子中
- n=28 p=0 k=5 s=1