TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的


Posted in Python onApril 20, 2020

今天来介绍一下Tensorflow里面的反卷积操作,网上反卷积的用法的介绍比较少,希望这篇教程可以帮助到各位

反卷积出自这篇论文:Deconvolutional Networks,有兴趣的同学自行了解

首先无论你如何理解反卷积,请时刻记住一点,反卷积操作是卷积的反向

如果你随时都记住上面强调的重点,那你基本就理解一大半了,接下来通过一些函数的介绍为大家强化这个观念

conv2d_transpose(value, filter, output_shape, strides, padding="SAME", data_format="NHWC", name=None)

除去name参数用以指定该操作的name,与方法有关的一共六个参数:
第一个参数value:指需要做反卷积的输入图像,它要求是一个Tensor
第二个参数filter:卷积核,它要求是一个Tensor,具有[filter_height, filter_width, out_channels, in_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,卷积核个数,图像通道数]
第三个参数output_shape:反卷积操作输出的shape,细心的同学会发现卷积操作是没有这个参数的,那这个参数在这里有什么用呢?下面会解释这个问题
第四个参数strides:反卷积时在图像每一维的步长,这是一个一维的向量,长度4
第五个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式
第六个参数data_format:string类型的量,'NHWC'和'NCHW'其中之一,这是tensorflow新版本中新加的参数,它说明了value参数的数据格式。'NHWC'指tensorflow标准的数据格式[batch, height, width, in_channels],'NCHW'指Theano的数据格式,[batch, in_channels,height, width],当然默认值是'NHWC'

开始之前务必了解卷积的过程,参考我的另一篇文章:https://3water.com/article/177798.htm

首先定义一个单通道图和3个卷积核

x1 = tf.constant(1.0, shape=[1,3,3,1])
kernel = tf.constant(1.0, shape=[3,3,3,1])

先别着急!我们不直接用反卷积函数,而是再定义一些图

x2 = tf.constant(1.0, shape=[1,6,6,3])
x3 = tf.constant(1.0, shape=[1,5,5,3])

x2是6×6的3通道图,x3是5×5的3通道图
好了,接下来对x3做一次卷积操作

y2 = tf.nn.conv2d(x3, kernel, strides=[1,2,2,1], padding="SAME")

所以返回的y2是一个单通道的图,如果你了解卷积过程,很容易看出来y2是[1,3,3,1]的Tensor,y2的结果如下:

[[[[ 12.]
  [ 18.]
  [ 12.]]
 
 [[ 18.]
  [ 27.]
  [ 18.]]
 
 [[ 12.]
  [ 18.]
  [ 12.]]]]

又一个很重要的部分!tf.nn.conv2d中的filter参数,是[filter_height, filter_width, in_channels, out_channels]的形式,而tf.nn.conv2d_transpose中的filter参数,是[filter_height, filter_width, out_channels,in_channels]的形式,注意in_channels和out_channels反过来了!因为两者互为反向,所以输入输出要调换位置

既然y2是卷积操作的返回值,那我们当然可以对它做反卷积,反卷积操作返回的Tensor,应该和x3的shape是一样的(不难理解,因为是卷积的反过程)

y3 = tf.nn.conv2d_transpose(y2,kernel,output_shape=[1,5,5,3], strides=[1,2,2,1],padding="SAME")

好,现在返回的y3果然是[1,5,5,3]的Tensor,结果如下:

[[[[ 12. 12. 12.]
  [ 30. 30. 30.]
  [ 18. 18. 18.]
  [ 30. 30. 30.]
  [ 12. 12. 12.]]
 
 [[ 30. 30. 30.]
  [ 75. 75. 75.]
  [ 45. 45. 45.]
  [ 75. 75. 75.]
  [ 30. 30. 30.]]
 
 [[ 18. 18. 18.]
  [ 45. 45. 45.]
  [ 27. 27. 27.]
  [ 45. 45. 45.]
  [ 18. 18. 18.]]
 
 [[ 30. 30. 30.]
  [ 75. 75. 75.]
  [ 45. 45. 45.]
  [ 75. 75. 75.]
  [ 30. 30. 30.]]
 
 [[ 12. 12. 12.]
  [ 30. 30. 30.]
  [ 18. 18. 18.]
  [ 30. 30. 30.]
  [ 12. 12. 12.]]]]

这个结果是怎么得来的?可以用一张动图来说明,图片来源:反卷积的真正含义

TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的

看起来,tf.nn.conv2d_transpose的output_shape似乎是多余的,因为知道了原图,卷积核,步长显然是可以推出输出图像大小的,那为什么要指定output_shape呢?
看这样一种情况:

y4 = tf.nn.conv2d(x2, kernel, strides=[1,2,2,1], padding="SAME")

我们把上面的x2也做卷积,获得shape为[1,3,3,1]的y4如下:

[[[[ 27.]
  [ 27.]
  [ 18.]]
 
 [[ 27.]
  [ 27.]
  [ 18.]]
 
 [[ 18.]
  [ 18.]
  [ 12.]]]]

[1,6,6,3]和[1,5,5,3]的图经过卷积得到了相同的大小,[1,3,3,1]
让我们再反过来看,那么[1,3,3,1]的图反卷积后得到什么呢?产生了两种情况。所以这里指定output_shape是有意义的,当然随意指定output_shape是不允许的,如下情况程序会报错:

y5 = tf.nn.conv2d_transpose(x1,kernel,output_shape=[1,10,10,3],strides=[1,2,2,1],padding="SAME")

以上是stride为2的情况,为1时也类似,当卷积核大于原图时,默认用VALID方式(用SAME就无意义了)参考下图:

程序清单:

import tensorflow as tf
 
x1 = tf.constant(1.0, shape=[1,3,3,1])
 
x2 = tf.constant(1.0, shape=[1,6,6,3])
 
x3 = tf.constant(1.0, shape=[1,5,5,3])
 
kernel = tf.constant(1.0, shape=[3,3,3,1])
 
 
 
y1 = tf.nn.conv2d_transpose(x1,kernel,output_shape=[1,6,6,3],
  strides=[1,2,2,1],padding="SAME")
 
y2 = tf.nn.conv2d(x3, kernel, strides=[1,2,2,1], padding="SAME")
 
y3 = tf.nn.conv2d_transpose(y2,kernel,output_shape=[1,5,5,3],
  strides=[1,2,2,1],padding="SAME")
 
y4 = tf.nn.conv2d(x2, kernel, strides=[1,2,2,1], padding="SAME")
 
'''
Wrong!!This is impossible
y5 = tf.nn.conv2d_transpose(x1,kernel,output_shape=[1,10,10,3],strides=[1,2,2,1],padding="SAME")
'''
sess = tf.Session()
tf.global_variables_initializer().run(session=sess)
x1_decov, x3_cov, y2_decov, x2_cov=sess.run([y1,y2,y3,y4])
print(x1_decov.shape)
print(x3_cov.shape)
print(y2_decov.shape)
print(x2_cov.shape)

到此这篇关于TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的 的文章就介绍到这了,更多相关TensorFlow tf.nn.conv2d_transpose 反卷积内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
浅谈配置OpenCV3 + Python3的简易方法(macOS)
Apr 02 Python
python实现在IDLE中输入多行的方法
Apr 19 Python
python 读取目录下csv文件并绘制曲线v111的方法
Jul 06 Python
python实现简易动态时钟
Nov 19 Python
解决Pyinstaller 打包exe文件 取消dos窗口(黑框框)的问题
Jun 21 Python
Django 开发调试工具 Django-debug-toolbar使用详解
Jul 23 Python
python爬虫 正则表达式解析
Sep 28 Python
django admin 添加自定义链接方式
Mar 11 Python
Python面向对象程序设计之静态方法、类方法、属性方法原理与用法分析
Mar 23 Python
python golang中grpc 使用示例代码详解
Jun 03 Python
Python中OpenCV实现查找轮廓的实例
Jun 08 Python
Python实现猜拳与猜数字游戏的方法详解
Apr 06 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
Apr 20 #Python
解决python脚本中error: unrecognized arguments: True错误
Apr 20 #Python
python argparse传入布尔参数false不生效的解决
Apr 20 #Python
parser.add_argument中的action使用
Apr 20 #Python
Python ArgumentParse的subparser用法说明
Apr 20 #Python
python列表的逆序遍历实现
Apr 20 #Python
python sitk.show()与imageJ结合使用常见的问题
Apr 20 #Python
You might like
第四节 构造函数和析构函数 [4]
2006/10/09 PHP
解析PHP跨站刷票的实现代码
2013/06/18 PHP
使用Linux五年积累的一些经验技巧
2013/06/20 PHP
详解laravel安装使用Passport(Api认证)
2018/07/27 PHP
你所要知道JS(DHTML)中的一些技巧
2007/01/09 Javascript
jquery 可排列的表实现代码
2009/11/13 Javascript
30个最佳jQuery Lightbox效果插件分享
2011/04/11 Javascript
简单的前端js+ajax 购物车框架(入门篇)
2011/10/29 Javascript
jQuery限制图片大小的方法
2016/05/25 Javascript
BootStrap实现树形目录组件代码详解
2016/06/21 Javascript
快速入门Vue
2016/12/19 Javascript
mongoose中利用populate处理嵌套的方法
2017/05/26 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
js 索引下标之li集合绑定点击事件
2018/01/12 Javascript
微信小程序与公众号卡券/会员打通的问题
2019/07/25 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
js实现拖拽元素选择和删除
2020/08/25 Javascript
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
2015/08/16 Python
Python创建二维数组实例(关于list的一个小坑)
2017/11/07 Python
查看django执行的sql语句及消耗时间的两种方法
2018/05/29 Python
python for循环输入一个矩阵的实例
2018/11/14 Python
mac安装python3后使用pip和pip3的区别说明
2020/09/01 Python
cosme官方海外旗舰店:日本最大化妆品和美容产品的综合口碑网站
2017/01/18 全球购物
巴西美妆购物网站:Kutiz Beauté
2019/03/13 全球购物
navabi英国:设计师大码女装
2019/06/25 全球购物
亚洲航空公司官方网站:AirAsia
2019/11/25 全球购物
意大利网上书店:LaFeltrinelli
2020/06/12 全球购物
关于Java String的一道面试题
2013/09/29 面试题
《晏子使楚》教学反思
2014/02/08 职场文书
继承权公证书
2014/04/09 职场文书
致百米运动员广播稿5篇
2014/10/13 职场文书
巧用 -webkit-box-reflect 倒影实现各类动效(小结)
2021/04/22 HTML / CSS
Java新手教程之ArrayList的基本使用
2021/06/20 Java/Android
详解JavaScript中Arguments对象用途
2021/08/30 Javascript
【海涛教你打DOTA】虚空假面第一视角骨弓3房29杀
2022/04/01 DOTA