查阅资料了许久,很多博客资料都对知识进行详细讲解,但一到strides,padding就一带而过,自己发现还是对于步长stride和填充padding这两个因素对输出张量大小的关系不是很清楚,于是自行代码实验并在此记录。
反卷积的基本资料查阅:
1、介绍了反卷积的各种详细的知识: https://blog.csdn.net/mao_xiao_feng/article/details/71713358
2、给予了动图方便理解: https://blog.csdn.net/u012938704/article/details/52838902
反卷积是卷积的逆过程,其参数代表了正向卷积的过程,如:注意此时的参数padding="VALID"反映的是正向卷积过程不进行填充,但是在上采样反卷积过程中,是一直存在填充0的。
直接上代码,简单易懂。
import tensorflow as tf
test1 = tf.constant(1.0, shape=[1,2,2,1])
w = tf.constant(1.0, shape=[3,3,1,1])
result = tf.nn.conv2d_transpose(test1, w, output_shape=[1,4,4,1], strides=[1,1,1,1],padding="VALID")
with tf.Session() as sess:
print(sess.run(result))
我们定义了一个shape为[1,2,2,1]的张量test1,即其实可以直接理解为2×2的矩阵,因为其他维度(batch size和channel)均为1。
反卷积核为3×3,输出通道和输入通道不变均为1。
此时output_shape只能为[1,4,4,1]了,尺寸扩大了一倍。
现在注意到了,因为其实该 tf.nn.conv2d_transpose反卷积过程是卷积的逆过程,只有[1,4,4,1]的张量在strides=[1,1,1,1],padding="VALID"情况下卷积才能得到[1,2,2,1]的结果,所以发现里面的参数都是相互联系的,互相已经进行了确认。
[[[[1.]
[2.]
[2.]
[1.]]
[[2.]
[4.]
[4.]
[2.]]
[[2.]
[4.]
[4.]
[2.]]
[[1.]
[2.]
[2.]
[1.]]]]
import tensorflow as tf
test1 = tf.constant(1.0, shape=[1,2,2,1])
w = tf.constant(1.0, shape=[3,3,1,1])
result = tf.nn.conv2d_transpose(test1, w, output_shape=[1,2,2,1], strides=[1,1,1,1],padding="SAME")
with tf.Session() as sess:
print(sess.run(result))
若strides=[1,1,1,1],padding="SAME"情况,同上一样,这时候的output_shape只能是[1,2,2,1],只能是2×2的张量大小经过3×3卷积,并且参数strides=[1,1,1,1],padding=“SAME”,才能得到2×2的张量。
[[[[4.]
[4.]]
[[4.]
[4.]]]]
当strides步长为2的时候,在进行0填充的时候有一点不同,它在进行填充的时候进行了一些改变,在下图中进行了表示,同时strides步长为2同样表示的是正向卷积过程的参数(正如上面第一点讨论的padding="VALID"但是也进行了0填充),而反卷积过程中,其卷积核移动仍然是一步一步移动的。
话不多说,还是直接上代码。
import tensorflow as tf
test1 = tf.constant(1.0, shape=[1,2,2,1])
w = tf.constant(1.0, shape=[3,3,1,1])
result = tf.nn.conv2d_transpose(test1, w, output_shape=[1,5,5,1], strides=[1,2,2,1],padding="VALID")
with tf.Session() as sess:
print(sess.run(result))
此时发现output_shape只能是[1,5,5,1]了,不难理解,在strides=[1,2,2,1],padding="VALID"的情况下,也只有5×5的张量能够得到2×2的张量。
[[[[1.]
[1.]
[2.]
[1.]
[1.]]
[[1.]
[1.]
[2.]
[1.]
[1.]]
[[2.]
[2.]
[4.]
[2.]
[2.]]
[[1.]
[1.]
[2.]
[1.]
[1.]]
[[1.]
[1.]
[2.]
[1.]
[1.]]]]
import tensorflow as tf
test1 = tf.constant(1.0, shape=[1,2,2,1])
w = tf.constant(1.0, shape=[3,3,1,1])
result = tf.nn.conv2d_transpose(test1, w, output_shape=[1,3,3,1], strides=[1,2,2,1],padding="SAME")
with tf.Session() as sess:
print(sess.run(result))
[[[[1.]
[2.]
[1.]]
[[2.]
[4.]
[2.]]
[[1.]
[2.]
[1.]]]]