反卷積實現 tensorflow 實現

2021-08-28 02:28:22 字數 3800 閱讀 8456

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

上面錯誤的意思是:

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=)

print(los_)

# invalidargumenterror (see above for traceback): conv2dslowbackpropinput: size of out_backprop doesn't match computed: actual = 25, computed = 33

如果 輸入的 shape 有好多none的話,那就是另外一種 報錯方式了,如上所示: 

這個錯誤的意思是:

至於為什麼會這樣,因為deconv的計算方式就是conv求導的計算方式,conv的計算方式,就是decov求導的方式。

deconv求導就相當於 拿著conv_transpose中的引數對deconv輸出的值的導數做卷積。

conv2d_transpose()中,有乙個引數,叫output_shape, 如果對它傳入乙個 int list 的話,那麼在執行的過程中,output_shape將無法改變(傳入int list已經可以滿足大部分應用的需要),但是如何更靈活的控制output_shape呢?

# 可以用 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')

參考:

tensorflow實現卷積與反卷積自編碼框架

從dcgan中了解到了反卷積的操作,所以我本來打算能通過卷積操作作為編碼器將一幀影象轉換為乙個20維的向量,而後再通過反卷積實現解碼功能從而達到影象恢復效果,先把程式貼上,後續有空再調整網路層數和引數吧 from tensorflow.examples.tutorials.mnist import ...

TensorFlow演示反卷積的操作

一 反卷積函式介紹 1 語法格式 def conv2d transpose value,filter,output shape,strides,padding same data format nhwc name none 2 引數說明 value 代表通過卷積操作之後的張量,一般為nhwc型別。f...

卷積和反卷積

n image h 2 pad h kernel h stride h 1 image w 2 pad w kernel w stride w 1 image h 輸入影象的高度 image w 輸入影象的寬度 pad h 在輸入影象的高度方向兩邊各增加pad h個單位長度 因為有兩邊,所以乘以2 ...