定义
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
函数作用是用于tensorflow中的卷积运算
参数
- input:待操作的张量,要求是tensor,结构为[ batch_size, height, width, in_channels ]。计算后的结果是四维的tensor,即常说的特征图(feature map);输入数据类型必须是float32或者float64
- filter:卷积核,要求是tensor,结构为[ filter_height, filter_width, in_channels, out_channels ]。这里的in_channels和input中的in_channels必须相同;数据类型与input一致
- strides:步长,结构是[ 1, strides, strides, 1]。第一维和第四维必须为1,第二第三维为步长,[1, 2, 2, 1]即设步长为2
- padding:填充,结构只有两类:“SAME”, “VALID”。same代表补0填充,会优先在图右侧和下侧补0;valid代表不补0,卷积核没有扫到的部分直接丢弃
- use_cudnn_on_gpu=None:是否使用GPU加速,bool类型,默认为True
- name:给这个指定的操作命名
例子
- 默认batch为1,输入为331的图,通道为1,使用2*2的filter,将图增加到3维,使用SAME padding,步长为2
input_tensor = tf.Variable(tf.random_normal([1,3,3,1])) # b, h, w, c
filter_1 = tf.Variable(tf.ones([2,2,1,3])) # f_h, f_w, in_c, out_c
output = tf.nn.conv2d(input_tensor, filter_1, strides=[1, 2, 2, 1], padding='SAME',
use_cudnn_on_gpu=False)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print(sess.run(output))
print(output.shape)
得到:
[[[[ 1.1837978 1.1837978 1.1837978]
[ 0.5729767 0.5729767 0.5729767]]
[[-1.4685228 -1.4685228 -1.4685228]
[ 1.6717577 1.6717577 1.6717577]]]]
(1, 2, 2, 3)
- 默认batch为1,输入为331的图,通道为1,使用2*2的filter,将图增加到3维,使用VALID padding,步长为2
input_tensor = tf.Variable(tf.random_normal([1,3,3,1])) # b, h, w, c
filter_1 = tf.Variable(tf.ones([2,2,1,3])) # f_h, f_w, in_c, out_c
output = tf.nn.conv2d(input_tensor, filter_1, strides=[1, 2, 2, 1], padding='VALID',
use_cudnn_on_gpu=False)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print(sess.run(output))
print(output.shape)
得到:
[[[[-1.8322035 -1.8322035 -1.8322035]]]]
(1, 1, 1, 3)
关于padding:
可以看到不同的padding拥有不同的输出结果shape,因为步长为2,所以22的filter并不能完全覆盖33的图(VALID padding),所以最终输出的shape为(1,1,1,3);使用"SAME"方法的则能在33的图中右边和下边各补充0,使22的filter能够完全覆盖图,最终输出的shape为(1,2,2,3)
- 更改batch为4,输入为331的图,通道为1,使用2*2的filter,将图增加到3维,使用SAME padding,步长为2
input_tensor = tf.Variable(tf.random_normal([4,3,3,1])) # b, h, w, c
filter_1 = tf.Variable(tf.ones([2,2,1,3])) # f_h, f_w, in_c, out_c
output = tf.nn.conv2d(input_tensor, filter_1, strides=[1, 2, 2, 1], padding='SAME',
use_cudnn_on_gpu=False)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print(sess.run(output))
print(output.shape)
得到:
[[[[-1.2321737 -1.2321737 -1.2321737 ]
[ 1.2999856 1.2999856 1.2999856 ]]
[[ 0.3062305 0.3062305 0.3062305 ]
[-0.6112298 -0.6112298 -0.6112298 ]]]
[[[-3.1887996 -3.1887996 -3.1887996 ]
[ 1.3863715 1.3863715 1.3863715 ]]
[[ 0.54844457 0.54844457 0.54844457]
[ 0.97763544 0.97763544 0.97763544]]]
[[[-1.5045768 -1.5045768 -1.5045768 ]
[ 2.008266 2.008266 2.008266 ]]
[[-0.1533035 -0.1533035 -0.1533035 ]
[ 0.22152434 0.22152434 0.22152434]]]
[[[ 1.1186421 1.1186421 1.1186421 ]
[-1.3898249 -1.3898249 -1.3898249 ]]
[[-0.3974297 -0.3974297 -0.3974297 ]
[-1.3495198 -1.3495198 -1.3495198 ]]]]
(4, 2, 2, 3)
可以看到:
计算结果batch仍旧为之前设置的,并不会改变,改变的只是特征图的形状和通道数