【TensorFlow基础】对于卷积神经网络中遇到的tf.nn.conv2d()函数理解和输出feature map的size求法

很多地方已讲解得十分详细,在这里把自己的理解用几句话记录下来以后回顾用。


tf.nn.conv2d()简介

TensorFlow中函数conv2d主要实现了输入张量与设定卷积核的卷积操作,其函数形式如下:

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

1.input,filter是设定的输入和卷积核,参数strides,padding分别决定了卷积操作中滑动步长和图像边沿填充的方式。

2.参数 strides = [1, strides[1], strides[2], strides[3]]
为长度为4的一阶张量,并且要求strides[0]=strides[3]=1,strides[1],strides[2]决定卷积核在输入图像in_hight,in_width方向的滑动步长。

3.参数padding
为什么要有padding?
卷积核的大小和图像的大小有时候不是完全匹配,再考虑到滑动步长strides,需要在边界填充数值。padding参数的两个值SAME,VALID决定了其填充方式。


重点

关于padding设置成SAME、VALID后不同的工作方式如何不重要
我只想知道最后输出的feature map尺寸size如何。

先上几句话结论

output_size=( input_size + padding * 2 - conv_size ) / strides + 1
得出的结果若是小数,就取其整数部分
padding=‘SAME’ —> padding =1 ;
padding=‘VALID’ —> padding = 0.

想求长或是宽的output_size,input_size、conv_size就代入长或宽,当然大多情况下都一样。
(按照CNN的理论知识:feature map的size会有4个值,首尾的值分别代表输入的样本个数和输出多少个feature map,需要求的output_size是指中间位置的2个值)


看如下代码示例:

情况1:公式计算的结果本身就是整数
padding = ‘SAME’

// output_size=( input_size + padding * 2 - conv_size ) / strides + 1
// 公式计算的结果本身就是整数
// (5 + 2 * 1 - 3)/1 + 1 = 5
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

input = tf.Variable(tf.ones([1,5,5,1]))
# 第一个'1'指样本个数,相当于xs = tf.placeholder(tf.float32,[None,25])中的None;后面的'1'指channel是1通道(RGB的话就是3;25=5*5

filter = tf.Variable(tf.ones([3,3,1,1]))
# 3*3指卷积核size,前一个'1'指一个卷积核,因为输入就1个channel;后一个'1'指设定输出的feature_map有1个,自己设置的,一般64128...

op = tf.nn.conv2d(input,filter,strides=[1,1,1,1],padding='SAME')
# strides默认其为长度为4的一阶张量,并且要求strides[0]=strides[3]=1,strides[1],strides[2]决定卷积核在输入图像in_hight,in_width方向的滑动步长

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(op).shape)
    print('-'*33)
    print(sess.run(op))
// sess.run(op).shape 为 (1, 5, 5, 1)

padding = ‘VALID’

// 设置参数padding='VALID'后,结果为 (1, 3, 3, 1)
// (5 + 2 * 0 - 3)/1 + 1 = 3

情况2:公式计算的结果是小数
padding = ‘SAME’

// output_size=( input_size + padding * 2 - conv_size ) / strides + 1
// 公式计算的结果是小数
// (28 + 2 * 1 - 3)/2 + 1 = 14.5		
// 取计算结果整数部分 14
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

input = tf.Variable(tf.ones([1,28,28,1]))

filter = tf.Variable(tf.ones([3,3,1,1]))

op = tf.nn.conv2d(input,filter,strides=[1,2,2,1],padding='SAME')

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(op).shape)
    print('-'*33)
    print(sess.run(op))
// sess.run(op).shape 为(1, 14, 14, 1)

padding = ‘VALID’

// 设置参数padding='VALID'后,结果为 (1, 13, 13, 1)
// (28 + 2 * 0 - 3)/2 + 1 = 13.5
// 取整数部分 13

参考:https://blog.csdn.net/wangpengfei163/article/details/80987145?spm=1001.2014.3001.5506

Guess you like

Origin blog.csdn.net/sinat_26753005/article/details/121291523