tf.nn.conv2d_transpose反卷积(转置卷积)

tf.nn.conv2d_transpose反卷积(转置卷积)

查阅资料了许久,很多博客资料都对知识进行详细讲解,但一到strides,padding就一带而过,自己发现还是对于步长stride和填充padding这两个因素对输出张量大小的关系不是很清楚,于是自行代码实验并在此记录。
反卷积的基本资料查阅:
1、介绍了反卷积的各种详细的知识: https://blog.csdn.net/mao_xiao_feng/article/details/71713358
2、给予了动图方便理解: https://blog.csdn.net/u012938704/article/details/52838902

一、strides=[1,1,1,1],padding="VALID"情况

反卷积是卷积的逆过程,其参数代表了正向卷积的过程,如:注意此时的参数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.]]]]

二、strides=[1,1,1,1],padding="SAME"情况

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=[1,2,2,1],padding="VALID"情况

当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.]]]]

四、strides=[1,2,2,1],padding="SAME"情况

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.]]]]
彩蛋:可能大家发现了其实此时输出的张量也可以是[1,4,4,1](就不再作图了),这也正是印证了为什么当strides,padding等等这些参数都确定了还需要指定out_shape,只有这样才是最后完善的!
  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值