tensorflow学习笔记(三十二):conv2d_transpose ("解卷积")

deconv解卷积,实际是叫做conv_transpose, conv_transpose实际是卷积的一个逆向过程,tf 中, 编写conv_transpose代码的时候,心中想着一个正向的卷积过程会很有帮助。

想象一下我们有一个正向卷积: input_shape = [1,5,5,3] kernel_shape=[2,2,3,1] strides=[1,2,2,1] padding = "SAME"

那么,卷积激活后,我们会得到 x(就是上面代码的x)。那么,我们已知x,要想得到input_shape 形状的 tensor,我们应该如何使用conv2d_transpose函数呢? 就用下面的代码

import tensorflow as tf
tf.set_random_seed(1)
x = tf.random_normal(shape=[1,3,3,1])
#正向卷积的kernel的模样
kernel = tf.random_normal(shape=[2,2,3,1])

# strides 和padding也是假想中 正向卷积的模样。当然,x是正向卷积后的模样
y = tf.nn.conv2d_transpose(x,kernel,output_shape=[1,5,5,3],
    strides=[1,2,2,1],padding="SAME")
# 在这里,output_shape=[1,6,6,3]也可以,考虑正向过程,[1,6,6,3]
# 通过kernel_shape:[2,2,3,1],strides:[1,2,2,1]也可以
# 获得x_shape:[1,3,3,1]
# output_shape 也可以是一个 tensor
sess = tf.Session()
tf.global_variables_initializer().run(session=sess)

print(y.eval(session=sess))

conv2d_transpose 中会计算 output_shape 能否通过给定的参数计算出 inputs的维度,如果不能,则报错

import tensorflow as tf
from tensorflow.contrib import slim

inputs = tf.random_normal(shape=[3, 97, 97, 10])

conv1 = slim.conv2d(inputs, num_outputs=20, kernel_size=3, stride=4)

de_weight = tf.get_variable('de_weight', shape=[3, 3, 10, 20])

deconv1 = tf.nn.conv2d_transpose(conv1, filter=de_weight, output_shape=tf.shape(inputs),
                                 strides=[1, 3, 3, 1], padding='SAME')

# ValueError: Shapes (3, 33, 33, 20) and (3, 25, 25, 20) are not compatible

上面错误的意思是:

  • conv1 的 shape 是 (3, 25, 25, 20)
  • 但是 deconv1 对 conv1 求导的时候,得到的导数 shape 却是 [3, 33, 33, 20],这个和 conv1 的shape 不匹配,当然要报错咯。
import tensorflow as tf
from tensorflow.contrib import slim
import numpy as np

inputs = tf.placeholder(tf.float32, shape=[None, None, None, 3])

conv1 = slim.conv2d(inputs, num_outputs=20, kernel_size=3, stride=4)

de_weight = tf.get_variable('de_weight', shape=[3, 3, 3, 20])

deconv1 = tf.nn.conv2d_transpose(conv1, filter=de_weight, output_shape=tf.shape(inputs),
                                 strides=[1, 3, 3, 1], padding='SAME')

loss = deconv1 - inputs
train_op = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

with tf.Session() as sess:
    tf.global_variables_initializer().run()

    for i in range(10):
        data_in = np.random.normal(size=[3, 97, 97, 3])
        _, los_ = sess.run([train_op, loss], feed_dict={inputs: data_in})
        print(los_)
# InvalidArgumentError (see above for traceback): Conv2DSlowBackpropInput: Size of out_backprop doesn't match computed: actual = 25, computed = 33

如果 输入的 shape 有好多 None 的话,那就是另外一种 报错方式了,如上所示: 这个错误的意思是:

  • conv1 的 shape 第二维或第三维的 shape 是 25
  • 但是 deconv1 对 conv1 求导的时候,得到的 倒数 shape 的第二位或第三维却是 33

至于为什么会这样,因为 deconv 的计算方式就是 conv 求导的计算方式,conv 的计算方式,就是 decov 求导的方式。

deconv 求导就相当于 拿着 conv_transpose 中的参数对 deconv 输出的值的导数做卷积。

如何灵活的控制 deconv 的output shape

conv2d_transpose() 中,有一个参数,叫 output_shape, 如果对它传入一个 int list 的话,那么在运行的过程中,output_shape 将无法改变(传入int list已经可以满足大部分应用的需要),但是如何更灵活的控制 output_shape 呢?

  • 传入 tensor
# 可以用 placeholder
outputs_shape = tf.placeholder(dtype=tf.int32, shape=[4])
deconv1 = tf.nn.conv2d_transpose(conv1, filter=de_weight, output_shape=output_shape,
                                 strides=[1, 3, 3, 1], padding='SAME')

# 可以用 inputs 的shape,但是有点改变
inputs_shape = tf.shape(inputs)
outputs_shape = [inputs_shape[0], inputs_shape[1], inputs_shape[2], some_value]
deconv1 = tf.nn.conv2d_transpose(conv1, filter=de_weight, output_shape=outputs_shape,
                                 strides=[1, 3, 3, 1], padding='SAME')                                 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器之心

业界 | 谷歌开源「Tangent」:一个用于自动微分的源到源Python库(附API概述)

34780
来自专栏AI研习社

实例+代码,你还怕不会构建深度学习的代码搜索库吗?

本文展示了一个端到端的实例,说明如何构建一个可以语义化搜索对象的系统。项目作者是 Hamel Husain (https://www.linkedin.com/...

8930
来自专栏SeanCheney的专栏

《Scikit-Learn与TensorFlow机器学习实用指南》 第2章 一个完整的机器学习项目使用真实数据项目概览获取数据数据探索和可视化、发现规律为机器学习算法准备数据选择并训练模型模型微调启动

本章中,你会假装作为被一家地产公司刚刚雇佣的数据科学家,完整地学习一个案例项目。下面是主要步骤: 项目概述。 获取数据。 发现并可视化数据,发现规律。 为机器学...

1.2K150
来自专栏AI科技评论

开发 | 谷歌推出开源 Python 库“Tangent”,支持前向模式自动微分

AI科技评论消息:日前,Google Research Blog 推出开源 Python库“Tangent”。据介绍,这个库与现有的机器学习库相比,存在诸多优势...

29850
来自专栏BestSDK

13个Tensorflow实践案例,深度学习没有想象中那么难

关于深度学习,每个人都有自己的看法。有人说就是炼丹,得个准确率召回率什么的,拿到实际中,问问为什么,都答不上来。各种连代码都没写过的人,也纷纷表示这东西就是小孩...

544100
来自专栏机器之心

资源 | 谷歌全attention机器翻译模型Transformer的TensorFlow实现

选自GitHub 机器之心编译 参与:黄小天、Smith 谷歌前不久在 arXiv 上发表论文《Attention Is All You Need》,提出一种完...

543110
来自专栏机器学习算法与Python学习

KNN算法实战-改进约会网站配对效果

kNN实战之改进约会网站配对效果 引言 简单的说,KNN算法采用测量不同特征值之间的距离方法进行分类。工作原理:存在一个样本数据集,即训练数据集,并且样本集中每...

597100
来自专栏大数据挖掘DT机器学习

13个Tensorflow实践案例,教你入门到进阶

关于深度学习,每个人都有自己的看法。有人说就是炼丹,得个准确率召回率什么的,拿到实际中,问问为什么,都答不上来。各种连代码都没写过的人,也纷纷表示这东西就是小孩...

540150
来自专栏大数据挖掘DT机器学习

用python实现K-近邻算法改进约会网站的配对效果

摘自:《机器学习实战》,用python编写的(需要matplotlib和numpy库)   海伦一直使用在线约会网站寻找合适自己的约会对象。尽管约会网站会推荐不...

33050
来自专栏FreeBuf

Kaggle:一套完整的网站流量预测模型

今天给大家推荐的是一个名叫Kaggle的网站流量预测项目,本项目采用Python语言开发,可以给大家的流量预测建模提供一些思路。 ? 数据模型 Kaggle的训...

50860

扫码关注云+社区

领取腾讯云代金券