我紧跟这个例子: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
我已经阅读了很多资源,包括这个StackOverflow的question,但没有一个明确地概括了计算 .
如果可能,可以推广每层可学习参数的计算吗?
例如,卷积层:滤波器数量x滤波器宽度x滤波器高度 .
2 回答
让我们首先看一下如何为每个单独的图层类型计算可学习参数的数量,然后计算示例中的参数数量 .
Input layer :所有输入图层都读取输入图像,因此您无法在此学习任何参数 .
Convolutional layers :考虑一个卷积层,它在输入端采用
l
个特征映射,并具有k
个特征映射作为输出 . 过滤器大小为n
xm
. 例如,这将如下所示:这里,输入具有
l=32
特征映射作为输入,k=64
特征映射作为输出,并且过滤器大小为n=3
xm=3
. 重要的是要理解,我们不是简单地使用3x3滤波器,而是实际使用3x3x32滤波器,因为我们的输入具有32维 . 我们学习了64种不同的3x3x32过滤器 . 因此,权重总数为n*m*k*l
. 然后,每个要素图还有一个偏差项,因此我们有(n*m*l+1)*k
的参数总数 .Pooling layers :池化层,例如执行以下操作:"replace a 2x2 neighborhood by its maximum value" . 因此,您无法在池化层中学习任何参数 .
Fully-connected layers :在完全连接的层中,所有输入单元对每个输出单元具有单独的权重 . 对于
n
输入和m
输出,权重数为n*m
. 此外,您对每个输出节点都有偏差,因此您的参数为(n+1)*m
.Output layer :输出层是一个普通的完全连接层,所以
(n+1)*m
参数,其中n
是输入数,m
是输出数 .最后的困难是第一个完全连接的层:我们不知道该层输入的维数,因为它是卷积层 . 要计算它,我们必须从输入图像的大小开始,并计算每个卷积层的大小 . 在您的情况下,Lasagne已经为您计算并报告尺寸 - 这使我们很容易 . 如果你必须自己计算每一层的大小,那就有点复杂了:
在最简单的情况下(如你的例子),卷积层的输出大小是
input_size - (filter_size - 1)
,在你的情况下:28 - 4 = 24.这是由于卷积的性质:我们使用例如计算一个点的5x5邻域 - 但是两个最外面的行和列不计算这些点的任何输出 . 这就是我们的输出比输入小2 * 2 = 4行/列的原因 .如果不希望输出小于输入,可以对图像进行零填充(使用在Lasagne中的卷积层的
pad
参数) . 例如 . 如果在图像周围添加2行/列的零,则输出大小为(28 4)-4 = 28 . 因此,在填充的情况下,输出大小为input_size + 2*padding - (filter_size -1)
.如果您明确要在卷积过程中对图像进行下采样,则可以定义步幅,例如
stride=2
,表示您以2像素为单位移动滤镜 . 然后,表达式变为((input_size + 2*padding - filter_size)/stride) +1
.在您的情况下,完整的计算是:
因此,在您的网络中,您总共有832 9'248 205'056 2'570 = 217'706可学习参数,这正是Lasagne报道的内容 .
Build 在@ hbaderts的优秀回复之上,刚刚想出了一些I-C-P-C-P-H-O网络的公式(因为我正在处理类似的问题),在下图中分享它可能会有所帮助 .
此外,(1)具有2x2步幅的卷积层和(2)具有2x2步幅的卷积层1x1步幅(max / avg)汇集,每个参数具有相同数量的具有“相同”填充的参数,如下所示: