三篇参考:
1.https://blog.csdn.net/goodshot/article/details/79655915 TF-卷积函数 tf.nn.conv2d 介绍
2.https://blog.csdn.net/goodshot/article/details/79677758 tf.nn.conv2d理解(带通道的卷积图片输出案例)
3.https://blog.csdn.net/goodshot/article/details/79653742 tf.nn.conv2d是怎样实现卷积的?
文档解释
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
- 1
给定一个input的张量[batch, in_height, in_width, in_channels]
和一个过滤器 / 内核张量 [filter_height, filter_width, in_channels, out_channels]
后,执行以下操作:
- 展平filter为一个形状为
[filter_height * filter_width * in_channels, output_channels]
的二维矩阵。 - 从input中按照filter大小提取图片子集形成一个大小为
[batch, out_height, out_width, filter_height * filter_width * in_channels]
的虚拟张量。 - 循环每个图片子集,右乘filter矩阵。
举例
输入是[1,3,3,1],代表1个图像,大小2x2,1个通道
filter是[2,2,1,1],代表filter的大小是2x2,输入通道通道是1,与图片通道相同,输入通道也是1。
步长是1,padding是VALID
这种情况下,输出是1x2x2x1,其中2=(3-2)/1+1,即(图片大小-filter大小)/步长+1。
代码
input = tf.constant([[[[1],
[2],
[ 3]],
[[4],
[5],
[6 ]],
[[ 7],
[8],
[9]]]],dtype=tf.float32)
filter = tf.constant([[[[1]],
[[2]]],
[[[ 3]],
[[4]]]],dtype=tf.float32)
op = tf.nn.conv2d(input,filter,strides = [1,1,1,1],padding ='VALID')
with tf.Session() as sess:
sess.run(init)
result = sess.run(op)
print(result)
结果是
[[[[ 37.]
[ 47.]]
[[ 67.]
[ 77.]]]]
当padding=SAME时,输入与输出形状相同,如下面代码所示,输出形状输出是1x3x3x1。
input = tf.constant([[[[1],
[2],
[ 3]],
[[4],
[5],
[6 ]],
[[ 7],
[8],
[9]]]],dtype=tf.float32)
filter = tf.constant([[[[1]],
[[2]]],
[[[ 3]],
[[4]]]],dtype=tf.float32)
op = tf.nn.conv2d(input,filter,strides = [1,1,1,1],padding ='SAME')
with tf.Session() as sess:
sess.run(init)
result = sess.run(op)
print(result)
结果是
[[[[ 37.]
[ 47.]
[ 21.]]
[[ 67.]
[ 77.]
[ 33.]]
[[ 23.]
[ 26.]
[ 9.]]]]
填充方式如图所示:
如果是2x2的图像,过滤器是3x3,padding=SAME,填充方式如图:
对于多通道来说,输入是[1x3x3x2]是3x3图像有2个通道,过滤器是[2x2x2x1],步长是1,padding=VALID,输出是[1x2x2x1],如图: