欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

卷积神经网络特征图大小的计算

程序员文章站 2022-04-30 17:14:24
...

前言

特征图大小计算式卷积神经网络中一个很基础的问题,也是一个必须理解的问题。卷到最后我们要知道提取的特征的维度的大小,所以我们必须知道,卷积后特征图的大小。这里我们讲解一下卷积的不同方式以及特征图大小计算的公式。

基本公式

卷积神经网络特征图大小的计算

卷积的不同方式

常用的卷积(不包含反卷积/转置卷积)的方式有两种,一种是Valid,一种是SAME。阅读过深度学习开源代码的小伙伴,估计知道这两个参数。比如在使用tensorflow的tf.nn.conv2d函数卷积时padding参数就可以指定为VALID或者SAME,下面我们就讲解一下这两个参数取值的意义。

VALID

valid是卷积方式的一种,卷积的示例如下图:
卷积神经网络特征图大小的计算
可以看到,使用valid方式卷积时,不会做填充,卷积核不会有超出特征图的范围。如果在卷积时剩下的部分不能被卷积核完全覆盖,则这部分将会被放弃,不参与卷积。具体如下图:
这是一个2X3的特征图,卷积核的大小是2X2,步长是2,则只能进行一次卷积,最后一列将被对其丢弃,不参与卷积。
卷积神经网络特征图大小的计算

对于valid方式卷积后特征图大小的计算,同样可以使用第二部分中的公式,此时P=0:
width = (W - F) / S + 1 不能整除时向下取整
height = (H - F) / S + 1 不能整除时向下取整

SAME

same也是卷积方式的一种,如果卷积核的大小是3X3,卷积的示例如下图:
卷积神经网络特征图大小的计算可以看到,使用same方式卷积时,会做填充,填充圈数的公式为P = (F-1)/2。这样可以保证所有的内容都参与卷积,不会丢弃任何列。
同样对于一个2X3的特征图,卷积核的大小是2X2,步长是2,将进行padding,这样将可以进行两次卷积操作。
卷积神经网络特征图大小的计算

对于same方式卷积后特征图大小的计算,同样可以使用第二部分中的公式:
width = (W - F + 2P) / S + 1 不能整除时向下取整数
height = (H - F + 2P) / S + 1 不能整除时向下取整数
其中,P = (F-1)/2。
注意

  1. 需要注意的是,SAME方式并不是保证卷积出的特征图和输入的特征图大小是等大的。只有stride为1时,并且卷积的方式是SAME输出的特征图才和输入的特征图是等大的。
  2. 所以SAME方式还有卷积的特征图的大小的计算还有一个公式,这个公式更加常用和通用,并且不需要计算P的大小。有时候P的大小是不容易确定的,如上面的2X3的卷积,在使用SAME卷积的时候,只在右侧填充了一列。所以SAME卷积的特征图的大小的计算一般使用如下公式:
    width = W / S 向上取整
    height = H / S 向上取整

实验

是在不太明白的怎么回事,或者对结果不太确定的话,我们可以通过实验验证,如果使用tensorflow实验的话会用到tf.nn.conv2d函数:

tf.nn.conv2d(
    input,
    filter,
    strides,
    padding,
    use_cudnn_on_gpu=True,
    data_format='NHWC',
    dilations=[1, 1, 1, 1],
    name=None
)

其中data_format这个参数我们很少了解,其实它是固定你input的格式,NHWC对应着你的输入数据的维度时[batch_size,Heigth,Width,Channel],NCHW对应[batch_size,Channel,Heigth,Width]。

其实strides里面的参数和这个data_format是一一对应的,什么意思呢?就是说,如果我们采用NHWC的方式和strides=[a,b,c,d]的情况下,计算卷积核移动过程是怎么样的呢?它会在batch的维度上按照 step=a的大小进行移动计算,同理,分别在HWC的维度上移动的step为b c d。因为我们需要对每一个batch和channel都需要进行计算,所以这里 a,d 的值为1。b c的值可以根据实际情况进行改变,他们的值直接关系到输出的feature map 的维度。

import tensorflow as tf

x = tf.constant([[1., 2., 3.],
                 [4., 5., 6.]])
x = tf.reshape(x, [1, 2, 3, 1])  # give a shape accepted by tf.nn.max_pool

valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')

print(valid_pad.get_shape())
print(same_pad.get_shape())

输出结果为:

(1, 1, 1, 1)
(1, 1, 2, 1)

参考文章:

  1. TensorFlow中CNN的两种padding方式“SAME”和“VALID”
  2. 关于理解卷积操作中Padding的两种方式
  3. 【神经网络】卷积层输出大小计算(长、宽、深度)
  4. 卷积神经网络池化后的特征图大小计算
  5. 卷积神经网络中特征图大小的计算