在FCN,U-net,GAN中都有使用轉置卷積(Transposed Convolution)的過程,轉置卷積不能單純地理解爲逆卷積(deconvolution)。
在CNN正向卷積過程是一個將圖片變小的過程,轉置卷積使得圖片逐漸變大,直至與原圖一樣大。
如何理解轉置卷積呢,可以先從將卷積的計算轉換成矩陣的計算來開始。
好了,到這兒大致瞭解了轉置卷積是什麼,能幹什麼了。也就是由卷積後得到的小圖經過轉置卷積可以得到大一點的圖(這比喻不太恰當,意會就好)。
下面是tensorflow中關於轉置卷積的API
這兒再附上tf中關於padding參數的用法:
好了,最後實戰一下,怎麼用tf中的轉置卷積:
import tensorflow as tf
# 正向卷積
# 輸入尺度 [batch, height, width, in_channels]
inputx=tf.random_normal([100,255,255,3],dtype=tf.float32)
# kernel [height, width, in_channels, output_channels]
w=tf.random_normal(shape=[5,5,3,10],dtype=tf.float32)
# 卷積輸出 (100, 126, 126, 10),注意:這兒用的是VALID
outputy=tf.nn.conv2d(input=inputx,filter=w,strides=[1,2,2,1],padding='VALID')
用卷積計算輸出很容易,但是如果我現在想根據輸出圖片的大小,怎麼設置卷積核的尺寸和strides呢?先貼代碼
# 轉置卷積
# 輸入的value [batch, height, width, in_channels]
value=tf.random_normal(shape=[100,126,126,10])
# filter [height, width, output_channels, in_channels]
w=tf.random_normal(shape=[4,4,3,10])
# 轉置卷積得出的結果
result=tf.nn.conv2d_transpose(value=value,filter=w,output_shape=[100,255,255,3],strides=[1,2,2,1],padding='VALID')
with tf.Session() as sess:
tf.global_variables_initializer().run()
# sess.run(outputy)
# print(outputy.shape)
sess.run(result)
print(result.shape)
其實有個很簡單的思路,就是像計算卷積那樣計算轉置卷積。這句話是這麼個意思,比如代碼中我要得到255*255*3的一張圖片(也就是經過轉置卷積放大的圖片),第一步我們要確定我們用什麼padding方式,不同的padding方式確定不同的計算模式。代碼中我們使用VALID模式,那麼根據轉置卷積的輸入value是126*126*10的圖片,根據計算公式
設kernel等於4,stride算出來正好是2。
如果設置padding是SAME呢,據公式
參考鏈接:http://blog.csdn.net/u013250416/article/details/78247818,
https://www.tensorflow.org/api_docs/python/tf/nn/conv2d_transpose,
https://www.tensorflow.org/api_docs/python/tf/nn/convolution,
《a guide to convolution arithmetic for deep learning》