Matconvnet 中的卷积层到全连接层
Convolutional layer to fully connected layer in Matconvnet
我想了解 Matconvnet 中的 MNIST 示例是如何设计的。看起来他们使用的是 LeNet 变体,但由于我之前没有使用 Matconvnet,所以我很难理解最后一个卷积层和第一个全连接层之间的连接是如何建立的:
net.layers = {} ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,1,20, 'single'), zeros(1, 20, 'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...
'method', 'max', ...
'pool', [2 2], ...
'stride', 2, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,20,50, 'single'),zeros(1,50,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...
'method', 'max', ...
'pool', [2 2], ...
'stride', 2, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(4,4,50,500, 'single'), zeros(1,500,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(1,1,500,10, 'single'), zeros(1,10,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'softmaxloss') ;
通常,在像 Tensorflow 和 MxNet 这样的库中,最后一个卷积层被展平,然后连接到全连接层。在这里,据我了解,他们将第一个全连接层解释为权重 {{f*randn(4,4,50,500, 'single'), zeros(1,500,'single')}}
作为全连接层,但该层仍然给出三维激活图作为其结果。我不明白 "flattening" 是怎么发生的。我需要帮助了解如何在此处建立卷积层-全连接层连接。
据我所知,您应该只用卷积层替换全连接层,卷积层的滤波器宽度和高度等于输入的宽度和高度。事实上,您不需要在 Matconvnet 中的完全连接层之前展平数据(扁平数据具有 1x1xDxN
形状)。在您的情况下,使用与输入具有相同空间大小的内核,即 4x4
,将作为 FC 层运行,其输出将为 1 x 1 x 500 x B。(B 代表第四维输入)
更新:
网络架构及其输出可视化 here 以理解操作流程。
我想了解 Matconvnet 中的 MNIST 示例是如何设计的。看起来他们使用的是 LeNet 变体,但由于我之前没有使用 Matconvnet,所以我很难理解最后一个卷积层和第一个全连接层之间的连接是如何建立的:
net.layers = {} ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,1,20, 'single'), zeros(1, 20, 'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...
'method', 'max', ...
'pool', [2 2], ...
'stride', 2, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,20,50, 'single'),zeros(1,50,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...
'method', 'max', ...
'pool', [2 2], ...
'stride', 2, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(4,4,50,500, 'single'), zeros(1,500,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(1,1,500,10, 'single'), zeros(1,10,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'softmaxloss') ;
通常,在像 Tensorflow 和 MxNet 这样的库中,最后一个卷积层被展平,然后连接到全连接层。在这里,据我了解,他们将第一个全连接层解释为权重 {{f*randn(4,4,50,500, 'single'), zeros(1,500,'single')}}
作为全连接层,但该层仍然给出三维激活图作为其结果。我不明白 "flattening" 是怎么发生的。我需要帮助了解如何在此处建立卷积层-全连接层连接。
据我所知,您应该只用卷积层替换全连接层,卷积层的滤波器宽度和高度等于输入的宽度和高度。事实上,您不需要在 Matconvnet 中的完全连接层之前展平数据(扁平数据具有 1x1xDxN
形状)。在您的情况下,使用与输入具有相同空间大小的内核,即 4x4
,将作为 FC 层运行,其输出将为 1 x 1 x 500 x B。(B 代表第四维输入)
更新: 网络架构及其输出可视化 here 以理解操作流程。