1

CNN中的参数解释及计算

 2 years ago
source link: https://flat2010.github.io/2018/06/15/%E6%89%8B%E7%AE%97CNN%E4%B8%AD%E7%9A%84%E5%8F%82%E6%95%B0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
%E6%89%8B%E7%AE%97CNN%E4%B8%AD%E7%9A%84%E5%8F%82%E6%95%B0%E9%A6%96%E5%9B%BE%E9%A6%96%E5%9B%BE.png

Talk is cheap, explain me the Paper.

  设计深度学习模型的时候,不管是自己从头搭建还是修改别人的,都离不开相关参数的计算,主要是输入图形先后经过卷积、池化层后输出尺寸的变化,尤其是涉及多个卷积或池化层时,如果对这两种操作的原理不清楚,就会对网络的各个参数产生困惑,不知道如何去修改以便适配自己的业务场景。
  这里对CNN(卷积神经网络)中的主要参数的计算做一个归纳整理,方便参考。我们先用图示的方式给出这两种操作的运行过程,最后再归纳出数学公式。
  注意:本文主要是结合Tensorflow来讲的,不同的平台会有所差异。

二、术语解释

  CNN网络的主要参数有下面这么几个:

  • 卷积核Kernal(在Tensorflow中称为filter);
  • 填充Padding;
  • 滑动步长Strides;
  • 池化核Kernal(在Tensorflow中称为filter);
  • 通道数Channels。

2.1 卷积核

  顾名思义,卷积核是在进行卷积操作的时候使用的,在Tensorflow中,被称为filter,通过一个四元列表传递。文档中对该参数的说明如下:

"""
filter: A `Tensor`. Must have the same type as `input`.
A 4-D tensor of shape
`[filter_height, filter_width, in_channels, out_channels]`
"""
# 定义一个大小为3*2,输入channel为3,输出channel为64的filter
conv_kernal = [3, 2, 3, 64]

  卷积核的示意图如下图中间部分(这里的卷积核大小为3*3)所示:

%E5%8D%B7%E7%A7%AF%E6%A0%B8%E7%A4%BA%E6%84%8F%E5%9B%BE.png

图2-1  卷积核示意图

  由上图可知,卷积这一步的操作,实际上是在输入数据上取与卷积核大小相同的矩阵,然后与卷积核矩阵进行哈达马达乘积),然后求这个乘积矩阵所有元素的和,作为卷积的结果。

  需要说明的是,这里的卷积跟我们信号与系统里面的卷积有所差异。

  上面提到的通道数(in_channels、out_channels)实际上就是我们的feature_map的数量。因为不同的卷积核卷积出来的feature_map是不一样的,因此有多少个out_channels,就有多少个不同的卷积核。关于这点,会在后边的通道参数里面解释。

  对于直接与输入层连接的卷积层来说,输入通道数in_channels,图片通常为3(因为包含R、G、B三色矩阵),文本则通常为1。

2.2 填充

  填充在卷积池化这两个操作里面都可能会用到,填充的作用主要是尽可能充分的保留和使用输入特征(如果不使用填充,网络层数越深,所丢失的边缘数据就越多,到最后可能无特征可用),同时也应注意填充的尺寸不宜过大,避免引入过多无用的数据。
  关于填充作用的说明还可以参考知乎上的这篇文章。Tensorflow中的填充只有两种类型,说明如下:

"""
padding: A `string` from: `"SAME", "VALID"`.
The type of padding algorithm to use.
"""
# VALID 对应的是不填充,即不做任何处理。
# SAME 这种填充方式在strides=1的情况下,使得输出能够保持和输入尺寸一致。

  Theano中的填充则有不填充、半填充、全填充三种,它的半填充对应Tensorflow的SAME

  SAME类型以0进行填充的示意图如下:

SAME%E5%A1%AB%E5%85%85%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图2-2  ‘SAME’类型填零示意图

  可以看到,这个操作实际上是在原始数据外面包裹了一层填充数据。

2.3 滑动步长

  滑动步长决定了在卷积或者池化的过程中,每次操作后移动的步数。在Tensorflow中,该参数也是一个四元列表,关于该参数的解释如下:

"""
strides: A list of `ints`.
1-D tensor of length 4. The stride of the sliding window for each
dimension of `input`. The dimension order is determined by the value of `data_format`, see below for details.
strides = [batch, height, width, channels]
"""
# 定义一个不跳过任何样本、不跳过任何颜色通道,垂直方向步长为2,水平方向步长为2的strides
strides = [1, 2, 2, 1]

  它的第2、3个参数分别对应在数据垂直和水平方向上的滑动步长。第1个参数表示在样本上的跳跃幅度,一般都是置为1(表示不会跳过任何样本)。第4个参数表示在通道上的跳跃幅度,通常也是置为1。更详细的可参见Stackoverflow上的讨论以及该博客

  卷积过程中的滑动过程示意如下:

%E6%AD%A5%E9%95%BF%E4%B8%BA1%E6%97%B6%E7%9A%84%E6%BB%91%E5%8A%A8%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图2-3  步长为1时的滑动示意图

  由上图可知,卷积核在输入数据上的操作顺序是先沿着水平方向,再沿着垂直方向。因为水平方向上步长为1,所以卷积核在水平方向上每操作一次,就往右移动一格,再进行下一次操作。当水平方向上操作完了以后,就回到最左边,在垂直方向向下移动一格,然后进行操作,如此往复循环,直到所有数据均处理完。

  此外需要说明的是,由于卷积核中值为0的部分对最终的结果没有任何贡献,因此在动图中卷积的时候没有高亮(黄色)显示,并不代表它们没有参与卷积。另外输入和卷积核的元素可以是任意值(上图只是为方便举的简单例子)。

  如果你把卷积核看做单反的取景框,把输入数据当作我们的风景,卷积核在输入上的移动过程就类似于我们拍全景照的过程,从左往右,从上往下。

  我们再来看看水平、垂直方向上滑动步长均为2并且使用了SAME方式填充的情况,如下图所示:

%E6%AD%A5%E9%95%BF%E4%B8%BA2%E6%97%B6%E7%9A%84%E6%BB%91%E5%8A%A8%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图2-4  步长为2时的滑动示意图

  由上图可知,其操作流程与步长为1时并没有区别,只不过每次沿水平/垂直方向挪动的步长为2。另外不太一样的地方是,对于有填充的数据,卷积核的取景(取值)范围不会超出填充数据(第一行最后一次移动)。

2.4 池化核

  池化核则是在进行池化操作时候的Kernal,池化的作用类似于PCA,可以有效的对数据降维同时保留关键特征。常用的池化核有如下几种类型:

  • 最大池化核,取池化数据(取景框取出来的所有数据)的最大值;
  • 平均池化核,取池化数据的平均值;
  • 最小池化核,取池化数据的最小值;
  • L2池化核,取池化数据的L2范数;

  下图分别展示了步长分别为1、2时的最大池化过程:

%E6%AD%A5%E9%95%BF%E4%B8%BA1%E6%97%B6%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B1%A0%E5%8C%96%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图2-5  步长为1时的最大池化示意图

%E6%AD%A5%E9%95%BF%E4%B8%BA2%E6%97%B6%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B1%A0%E5%8C%96%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图2-6  步长为2时的最大池化示意图

  关于池化的作用可参考该CSDN博客

2.5 通道数

  从上面的介绍我们可以看出,对于同一个输入矩阵,改变卷积核的元素值,将会产生不同的输出。因此,卷积核的数量决定了卷积操作之后生成的feature map(卷积核在输入上卷积后的输出矩阵我们称为feature map)数量。

  对于CNN来说,其隐藏层部分,上一层的卷积核(即为该层的输出通道数out_channels)数量决定了下一层的输入通道数(in_channels)。输入层部分,输入的类型决定了第一个隐藏层的输入通道数。对于图片数据来说,会拆分成3个输入矩阵,分别对应RGB三原色,如下图所示:

%E5%9B%BE%E7%89%87%E4%B8%89%E9%80%9A%E9%81%93%E7%A4%BA%E6%84%8F%E5%9B%BE1.png

图2-7  彩色图片三通道示意图(图片摘自网络

%E5%9B%BE%E7%89%87%E4%B8%89%E9%80%9A%E9%81%93%E7%A4%BA%E6%84%8F%E5%9B%BE.png

图2-8  彩色图片三通道输入矩阵示意图(图片摘自网络博客

  当然图片如果是以CMYK格式存储的,那么输入通道数就会变成4个。而对于文本类的输入,其通道数则只有1个。当然,也可以通过reshape操作后把文本输入变成3通道的数据(将文本数据模拟成图像,360曾经把网络流量转换成黑白图片,并用来训练DNN模型,从而判别是否包含恶意数据,这个想法真的是非常有创意。详见这里)。

  总之,数据是死的,人脑是活的,怎么玩,就靠你自己去发挥想象力了。下图是步长为2,卷积核数量为2上的卷积过程示意图:

%E5%A4%9A%E4%B8%AA%E5%8D%B7%E7%A7%AF%E6%A0%B8%E5%8D%B7%E7%A7%AF%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图2-9  步长为2、卷积核数量为2无填充情况的卷积示意图

三、参数计算

  主要有两个部分的参数需要计算,一个是卷积后的尺寸,另一个是池化后的尺寸。先看一些具体的比较简单的例子,方便去数。最后再给出通用的计算公式。

3.1 卷积后的尺寸

3.1.1 无填充、步长为1

  整个过程如下所示:

%E6%97%A0%E5%A1%AB%E5%85%85%E6%AD%A5%E9%95%BF%E4%B8%BA1%E5%8D%B7%E7%A7%AF%E7%A4%BA%E6%84%8F%E5%A4%A7%E5%9B%BE.gif

图3-1  无填充步长为1卷积示意图

  如上图所示,相关数据如下表所示:

输入通道数
(个) 输入尺寸
(高*宽) 卷积核数量
(个) 卷积核尺寸
(高*宽) 步长
(步) 输出通道数
(个) 输出尺寸
(高*宽) 填充

1 6 * 6 1 3 * 3 1 1 4 * 4 VALID

3.1.2 无填充、步长为2

  整个过程如下所示:

%E6%97%A0%E5%A1%AB%E5%85%85%E6%AD%A5%E9%95%BF%E4%B8%BA2%E5%8D%B7%E7%A7%AF%E7%A4%BA%E6%84%8F%E5%A4%A7%E5%9B%BE.gif

图3-2  无填充步长为2卷积示意图

  如上图所示,相关数据如下表所示:

输入通道数
(个) 输入尺寸
(高*宽) 卷积核数量
(个) 卷积核尺寸
(高*宽) 步长
(步) 输出通道数
(个) 输出尺寸
(高*宽) 填充

1 6 * 6 1 3 * 3 2 1 2 * 2 VALID

  由上述两图、表可知,除卷积核大小外其它所有条件都不变的情况下,第二种情况相较于第一种情况,其输出的尺寸缩小了24∗24=1424∗24=14,高、宽各自方向上则缩小了24=1224=12。

3.1.3 有填充、步长为2

  整个过程如下所示:

%E6%9C%89%E5%A1%AB%E5%85%85%E6%AD%A5%E9%95%BF%E4%B8%BA2%E5%8D%B7%E7%A7%AF%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图3-3  有填充步长为2卷积示意图

  如上图所示,相关数据如下表所示:

输入通道数
(个) 输入尺寸
(高*宽) 卷积核数量
(个) 卷积核尺寸
(高*宽) 步长
(步) 输出通道数
(个) 输出尺寸
(高*宽) 填充

1 6 * 6 1 3 * 3 2 1 3 * 3 SAME(8*8)

3.2 池化后的尺寸

3.2.1 无填充、步长为1

  整个过程如下所示:

%E6%97%A0%E5%A1%AB%E5%85%85%E6%AD%A5%E9%95%BF%E4%B8%BA1%E6%B1%A0%E5%8C%96%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图3-4  无填充步长为1池化示意图

  如上图所示,相关数据如下表所示:

输入通道数
(个) 输入尺寸
(高*宽) 池化核数量
(个) 池化核尺寸
(高*宽) 步长
(步) 输出通道数
(个) 输出尺寸
(高*宽) 填充

1 4 * 4 1 2 * 2 1 1 3 * 3 VALID

3.2.2 无填充、步长为2

  整个过程如下所示:

%E6%97%A0%E5%A1%AB%E5%85%85%E6%AD%A5%E9%95%BF%E4%B8%BA2%E6%B1%A0%E5%8C%96%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图3-5  无填充步长为2池化示意图

  如上图所示,相关数据如下表所示:

输入通道数
(个) 输入尺寸
(高*宽) 池化核数量
(个) 池化核尺寸
(高*宽) 步长
(步) 输出通道数
(个) 输出尺寸
(高*宽) 填充

1 4 * 4 1 2 * 2 2 1 2 * 2 VALID

3.2.3 有填充、步长为2

  整个过程如下所示:

%E6%9C%89%E5%A1%AB%E5%85%85%E6%AD%A5%E9%95%BF%E4%B8%BA2%E6%B1%A0%E5%8C%96%E7%A4%BA%E6%84%8F%E5%9B%BE.gif

图3-6  有填充步长为2池化示意图

  如上图所示,相关数据如下表所示:

输入通道数
(个) 输入尺寸
(高*宽) 池化核数量
(个) 池化核尺寸
(高*宽) 步长
(步) 输出通道数
(个) 输出尺寸
(高*宽) 填充

1 4 * 4 1 2 * 2 2 1 3 * 3 SAME(8*8)

3.3 计算公式

  卷积后的参数无非就三个,通道数、高、宽。其中通道数不用计算,就等于卷积核数量。为方便叙述,记:

  • HinHin,输入矩阵行数(像素高度);
  • HoutHout,输出矩阵行数(像素高度);
  • WinWin,输入矩阵列数(像素宽度);
  • WoutWout,输出矩阵列数(像素宽度);
  • HkerHker,卷积/池化核矩阵行数(高度);
  • WkerWker,卷积/池化核矩阵列数(宽度);
  • CHinCHin,输入通道数;
  • CHoutCHout,输出通道数;
  • SS,步长;
  • KK,卷积/池化核数量;
  • PP,填充数量(VALID时为0,SAME时为1);
  • ⌈⌉⌈⌉,向上取整(等价于Python中的math.ceil()函数);

3.3.1 卷积部分推导

  给定相关参数后,设卷积核在水平、垂直方向分别可以有效移动(对有填充情况,超出填充部分则该次移动无效。无填充情况,超出输入数据则移动无效。)m、nm、n次,则有:

3.3.1.1 水平方向

  移动情况如下所示:

%E6%B0%B4%E5%B9%B3%E6%96%B9%E5%90%91%E8%AF%81%E6%98%8E%E7%A4%BA%E6%84%8F%E5%9B%BE.png

图3-4  水平方向移动示意图

m⋅S+Hker≤Hin+2⋅P(3 - 1)(3 - 1)m⋅S+Hker≤Hin+2⋅P

m≤(Hin+2⋅P−Hker)S(3 - 2)(3 - 2)m≤(Hin+2⋅P−Hker)S

  而HoutHout就是我们最大的滑动次数,即:

Hout=mmax+1=⌊(Hin+2⋅P−Hker)S⌋+1=(Hin+2⋅P−Hker)S+1(3 - 3)(3 - 3)Hout=mmax+1=⌊(Hin+2⋅P−Hker)S⌋+1=(Hin+2⋅P−Hker)S+1

  注意:上式中mmaxmmax还要加1,因为第0次滑动的时候,也是做了卷积操作的。对应的文字版公式为:

输出宽度=(输入宽度+2⋅填充宽度−卷积核宽度)步长+1(3 - 4)(3 - 4)输出宽度=(输入宽度+2⋅填充宽度−卷积核宽度)步长+1

3.3.1.2 垂直方向

  垂直方向的推导与水平方向一致,只不过换了个方向而已,在此不赘述,直接给出其计算公式如下:

Wout=nmax+1=⌊(Win+2⋅P−Wker)S⌋+1=(Win+2⋅P−Wker)S+1(3 - 5)(3 - 5)Wout=nmax+1=⌊(Win+2⋅P−Wker)S⌋+1=(Win+2⋅P−Wker)S+1

  对应的文字版公式为:

输出高度=(输入高度+2⋅填充高度−卷积核高度)步长+1(3 - 6)(3 - 6)输出高度=(输入高度+2⋅填充高度−卷积核高度)步长+1

3.3.1.3 结论

  综上,再加入输出通道数,有卷积操作后输出的尺寸的计算公式如下:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩Hout=⌊(Hin+2⋅P−Hker)S⌋+1=(Hin+2⋅P−Hker)S+1Wout=⌊(Win+2⋅P−Wker)S⌋+1=(Win+2⋅P−Wker)S+1CHout=K(3 - 7)(3 - 7){Hout=⌊(Hin+2⋅P−Hker)S⌋+1=(Hin+2⋅P−Hker)S+1Wout=⌊(Win+2⋅P−Wker)S⌋+1=(Win+2⋅P−Wker)S+1CHout=K

  对应的文字版公式为:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩输出宽度=(输入宽度+2⋅填充宽度−卷积核宽度)步长+1输出高度=(输入高度+2⋅填充高度−卷积核高度)步长+1输出通道数=卷积核数量(3 - 8)(3 - 8){输出宽度=(输入宽度+2⋅填充宽度−卷积核宽度)步长+1输出高度=(输入高度+2⋅填充高度−卷积核高度)步长+1输出通道数=卷积核数量

  如果有疑问,可以把前面的例子拿来验证。Tensorflow中关于这部分的说明参考官方文档

3.3.2 池化部分推导

  池化部分因为工作原理和卷积部分基本上是一样的,所以其公式推导也并没有什么不同,有一点需要指出的是,池化部分仍然可以有填充。池化部分的推导这里就不再赘述。

3.3.3 小结

3.3.3.1 公式整合

  综上,整理出卷积/池化参数的通用计算公式如下:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩Hout=⌊(Hin+2⋅P−Hker)S⌋+1=(Hin+2⋅P−Hker)S+1Wout=⌊(Win+2⋅P−Wker)S⌋+1=(Win+2⋅P−Wker)S+1CHout=K(3 - 9)(3 - 9){Hout=⌊(Hin+2⋅P−Hker)S⌋+1=(Hin+2⋅P−Hker)S+1Wout=⌊(Win+2⋅P−Wker)S⌋+1=(Win+2⋅P−Wker)S+1CHout=K

  对应的文字版公式为:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩输出宽度=(输入宽度+2⋅填充宽度−卷积/池化核宽度)步长+1输出高度=(输入高度+2⋅填充高度−卷积/池化核高度)步长+1输出通道数=卷积/池化核数量(3 - 10)(3 - 10){输出宽度=(输入宽度+2⋅填充宽度−卷积/池化核宽度)步长+1输出高度=(输入高度+2⋅填充高度−卷积/池化核高度)步长+1输出通道数=卷积/池化核数量

  使用式(3-9)最右边的表达式计算时一定要注意,这种表达不是特别严谨,这样写是为了兼容网络上的一些博客的写法,分式结果要记得向下取整。

3.3.3.2 参考资料

  大部分参考的文献资料都在相应位置给出了,剩下还有些参考的资料罗列如下:

3.4 示例

  举几个例子来验证下。

3.4.1 示例1

  该例子是牛客网上题库中的一个题,试题如下:

  输入图片大小为200×200,依次经过一层卷积(kernel size 5×5,padding 1,stride 2),pooling(kernel size 3×3,padding 0,stride 1),又一层卷积(kernel size 3×3,padding 1,stride 1)之后,输出特征图大小为:
A. 95
B. 96
C. 97
D. 98
E. 99
F. 100
答案: C

  可以看出,该网络隐藏层共有3层(2层卷积,1层池化),再加上输入、输出层,该网络是一个5层的NN。

  对第一层卷积层,我们有Hin=Win=200, Hker=Wker=5, S=2, P=1, K=?Hin=Win=200,Hker=Wker=5,S=2,P=1,K=?,则根据公式(3-9)有:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩Hout=⌊(Hin+2⋅P−Hker)S⌋+1=⌊(200+2×1−5)2⌋+1=99Wout=⌊(Hin+2⋅P−Hker)S⌋+1=⌊(200+2×1−5)2⌋+1=99(3 - 11)(3 - 11){Hout=⌊(Hin+2⋅P−Hker)S⌋+1=⌊(200+2×1−5)2⌋+1=99Wout=⌊(Hin+2⋅P−Hker)S⌋+1=⌊(200+2×1−5)2⌋+1=99

  对第二层池化层,同理我们有Hin=Win=99, Hker=Wker=3, S=1, P=0, K=?Hin=Win=99,Hker=Wker=3,S=1,P=0,K=?,则有:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩Hout=⌊(99+2×0−3)1⌋+1=97Wout=⌊(99+2×0−3)1⌋+1=97(3 - 12)(3 - 12){Hout=⌊(99+2×0−3)1⌋+1=97Wout=⌊(99+2×0−3)1⌋+1=97

  对第三层池化层,同理我们有Hin=Win=97, Hker=Wker=3, S=1, P=1, K=?Hin=Win=97,Hker=Wker=3,S=1,P=1,K=?,则有:

⎧⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎨⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎩Hout=⌊(97+2×1−3)1⌋+1=97Wout=⌊(97+2×1−3)1⌋+1=97(3 - 13)(3 - 13){Hout=⌊(97+2×1−3)1⌋+1=97Wout=⌊(97+2×1−3)1⌋+1=97

3.4.2 示例2

  该例子是经典的LeNet-5,网络结构如下图所示:

LeNet-5%E7%BD%91%E7%BB%9C%E7%BB%93%E6%9E%84%E5%9B%BE.png

图3-5  LeNet-5网络结构图(图片摘自Paper

  其网络参数参考下图(卷积核大小均为5*5,步长1。池化核大小均为2*2,步长为2,通道数不定。):

层数 层类型 对应名称 相关参数

1 输入层 INPUT 输入尺寸 32 * 32 * 1

2 第1个卷积层 C1 卷积核尺寸 5 * 5 * 6, 步长 1, 填充 VALID

3 第1个池化层 S2 池化核尺寸 2 * 2 * 6, 步长 2, 填充 VALID

4 第2个卷积层 C3 卷积核尺寸 5 * 5 * 16, 步长 1, 填充 VALID

5 第2个池化层 S4 池化核尺寸 2 * 2 * 16, 步长 2, 填充 VALID

6 第3个卷积层 C5 卷积核尺寸 5 * 5 * 120, 步长 1, 填充 VALID

7 第1个全连接层 F6 压扁为84个神经元

8 输出层 OUTPUT 10种分类

  第1个卷积层C1,有:

Wout=Hout=⌊(32+2×0−5)1⌋+1=28(3 - 14)(3 - 14)Wout=Hout=⌊(32+2×0−5)1⌋+1=28

  第1个池化层S2,有:

Wout=Hout=⌊(28+2×0−2)2⌋+1=14(3 - 15)(3 - 15)Wout=Hout=⌊(28+2×0−2)2⌋+1=14

  第2个卷积层C3,有:

Wout=Hout=⌊(14+2×0−5)1⌋+1=10(3 - 16)(3 - 16)Wout=Hout=⌊(14+2×0−5)1⌋+1=10

  第2个池化层S4,有:

Wout=Hout=⌊(10+2×0−2)2⌋+1=5(3 - 17)(3 - 17)Wout=Hout=⌊(10+2×0−2)2⌋+1=5

  第2个池化层S4,有:

Wout=Hout=⌊(10+2×0−2)2⌋+1=5(3 - 18)(3 - 18)Wout=Hout=⌊(10+2×0−2)2⌋+1=5

  第3个卷积层C5,有:

Wout=Hout=⌊(5+2×0−5)1⌋+1=1(3 - 19)(3 - 19)Wout=Hout=⌊(5+2×0−5)1⌋+1=1

  第1个全连接层F6(全连接层没有卷积/池化操作),有:

⎧⎨⎩Hout=1Wout=84(3 - 20)(3 - 20){Hout=1Wout=84

  所有结果计算出来都与原始Paper吻合,证明我们的公式是准确无误的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK