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 相关文章推荐
如何解决django配置settings时遇到Could not import settings 'conf.local'
Nov 18 Python
Python中分数的相关使用教程
Mar 30 Python
python中常用的九种预处理方法分享
Sep 11 Python
Python中shutil模块的学习笔记教程
Apr 04 Python
基于Python实现的微信好友数据分析
Feb 26 Python
python获取代码运行时间的实例代码
Jun 11 Python
利用Pandas读取文件路径或文件名称包含中文的csv文件方法
Jul 04 Python
OpenCV+Python识别车牌和字符分割的实现
Jan 31 Python
Python docx库用法示例分析
Feb 16 Python
django+tornado实现实时查看远程日志的方法
Aug 12 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
Mar 01 Python
Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法
Jul 28 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
特转载一高手总结PHP学习资源和链接.
2006/12/05 PHP
javascript setAttribute, getAttribute 在不同浏览器上的不同表现
2010/08/05 Javascript
js 上下左右键控制焦点(示例代码)
2013/12/14 Javascript
通过JS来判断页面控件是否获取焦点
2014/01/03 Javascript
NodeJS制作爬虫全过程(续)
2014/12/22 NodeJs
Node.js的包详细介绍
2015/01/14 Javascript
jQuery移动页面开发中的触摸事件与虚拟鼠标事件简介
2015/12/03 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
bootstrap警告框使用方法解析
2017/01/13 Javascript
jQuery实现base64前台加密解密功能详解
2017/08/29 jQuery
原生JS写Ajax的请求函数功能
2017/12/22 Javascript
详解使用mpvue开发github小程序总结
2018/07/25 Javascript
element-ui 时间选择器限制范围的实现(随动)
2019/01/09 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
Bootstrap简单实用的表单验证插件BootstrapValidator用法实例详解
2020/03/29 Javascript
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
django 创建过滤器的实例详解
2017/08/14 Python
Python MySQLdb 使用utf-8 编码插入中文数据问题
2018/03/13 Python
浅谈pandas中shift和diff函数关系
2018/04/08 Python
解决Python2.7读写文件中的中文乱码问题
2018/04/12 Python
Python实现的线性回归算法示例【附csv文件下载】
2018/12/29 Python
python中yield的用法详解——最简单,最清晰的解释
2019/04/04 Python
基于python实现操作redis及消息队列
2020/08/27 Python
Python unittest如何生成HTMLTestRunner模块
2020/09/08 Python
德国最大的拼图在线商店:Puzzle.de
2016/12/17 全球购物
阿里巴巴的Oracle DBA笔试题答案-SQL tuning类
2016/04/03 面试题
什么是组件架构
2016/05/15 面试题
测绘工程本科生求职信
2013/10/10 职场文书
厨房工作人员岗位职责
2013/11/15 职场文书
自强自立美德少年事迹材料
2014/08/16 职场文书
弘扬焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
2014年四风个人对照检查及整改措施
2014/10/28 职场文书
惹女朋友生气检讨书
2015/05/06 职场文书
医院合作意向书范本
2015/05/08 职场文书
《静夜思》教学反思
2016/02/17 职场文书
这样写python注释让代码更加的优雅
2021/06/02 Python