先看一下 tensorflow中自带的卷积操作是什么样子的呢?
https://tensorflow.google.cn/api_docs/python/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 的维度。
在来看一下在padding 等于 same 和valid 两个参数下的计算方式。可以参考:https://www.jianshu.com/p/05c4f1621c7e
假设,我们输入的图像的大小为:W*H
kernel size的大小为: k_h*k_w
在 H 方向的stride为 h, 在W方向 的stride为 w
来求我们新输出的特征图的大小,n_h 和 n_w
如果是 valid 模式,他是只在原图进行修改
则 n_h =( H-k_h)/ h 向上取整后加 1 ; n_w = (W-k_w)/ h 向上取整后加 1 ;
如果是 SAME 模式,他会在填充的时候自动补0(在必要的时候)。
那么什么是必要的时候呢?它是先根据公式 n_h = H/h 向上取整 和 n_w=W/w 向上取整 得到最终的输出n_h和n_w,在根据得需要输出的 n_h 和 n_w 反向推到那些地方需要补 0 。
在 H 方向 pad_need_H = (n_h -1 ) * h +K_h - H
在矩阵每一行的上方需要添加的像素数为:
pad_need_H/2 取整
在矩阵每一行的下方需要添加的像素数为
pad_need_H - pad_need_H/2
同理可得在W方向,
源码如下。
例如输入的是feature map 是4*4 ,kernel size 为1*1,strides 1,1
则它需要补充后的图为
这里画斜杠的为填充的0
加入输入的feature map 为 2*5 kernel size 为2*2 , strides 为【1,2,1,1】
则它需要填充后的图为
最后一列为需要填充的0值,最后输出的feature map 为1*5
原文:https://blog.csdn.net/tiandd12/article/details/80271050