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