我正在使用Lasagne为MNIST数据集创建CNN。我将密切关注这个示例:卷积神经网络和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
我想知道这个数字是如何计算的?我已经阅读了许多资源,包括有关StackOverflow的问题的信息,但没有一个可以清楚地概括该计算。
如果可能,是否可以概括每层可学习参数的计算?
例如,卷积层:滤镜数量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
。然后,每个特征图都有一个偏差项,因此我们的参数总数为(n*m*l+1)*k
。
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行/列的原因。pad
Lasagne中卷积层的参数)。例如,如果在图像周围添加零的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报告的内容。
好答案,谢谢。我唯一仍然感到困惑的是如何计算卷积层大小。我不确定24x24和10x10的来源。
我在卷积层中添加了有关大小计算的更多详细信息-如果这有帮助,请告诉我。
嗨@hbaderts,我还有另一个问题。根据你们这里的这张表,模型尺寸是指这里所有个体尺寸的总和,对吗?对于CNN,理解模型大小与可学习参数的数量成反比是否明智?请您看一下stackoverflow.com/questions/43443342/…吗?
@hbaderts,您的解释非常有帮助,但令我感到困惑的是,如果我有16个输出特征,为什么要处理偏差1 in((n m l + 1)* k),所以偏差也将为16,是'是吗?所以我们必须在上面的公式中加上16?
@ honar.cs如果您有16个输出功能,则
k=16
。等式为(n*m*l+1)*k
,+1
括号内为。因此,+1
也要乘以16,n*m*l*16 + 16
举一个例子。这有帮助吗?