tensorflow反卷積

反卷積


  1. 反卷積計(jì)算

假設(shè)有一個(gè)輸入為4x4的矩陣X,和一個(gè)3x3的矩陣kernel

當(dāng)卷積參數(shù)為步長(zhǎng)為1,填充為0時(shí),輸出為Y=2x2

此時(shí)我們將X展開(kāi)為16x1的列向量,Y展開(kāi)為4x1的列向量,則存在矩陣C,有Y = CX,
C的shape為4x16。稀疏矩陣可以推導(dǎo)出來(lái),從而根據(jù)C和Y我們可以求的X。但是這個(gè)操作只能恢復(fù)X的shape,而不能恢復(fù)
它的每個(gè)元素的值。

  1. 反卷積輸出的shape

首先對(duì)于正向卷積,輸出shape計(jì)算公式output = (input - kernelsize + 2padding) / strides + 1,舉例,input=6x6,kernel=3x3,
stride=2,padding=1,則它的輸出shape=3x3

對(duì)于反卷積,第一種情況,(output + 2padding - kernel) % s = 0(注意這里的output是卷積的輸出),此時(shí)的反卷積輸出為o = strides(input - 1) - 2padding + kernel,即
此時(shí)反卷積輸出為5x5.

第二種情況,(output + 2padding - kernel) % s != 0

此時(shí)反卷積輸出尺寸為o = strides(input - 1) - 2padding + kernel + (output + 2padding - kernel) % s,即對(duì)于上述的正向卷積,
做反向卷積是輸出為6x6。

  1. tensorflow實(shí)驗(yàn)

反卷積
第一種情況,輸出的shape為5x5

import tensorflow as tf
img = tf.Variable(tf.constant([[1.,2,3],[4,5,6],[7,8,9]], shape=[1,3,3,1]))
kernel = tf.Variable(tf.constant([[1.0,0.,0.],[0,1.0,0],[0,0,1.0]],shape=[3,3,1,1]))
conts = tf.nn.conv2d_transpose(img,kernel,[1,5,5,1],strides=[1,2,2,1],padding='SAME')

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print('conts:\n', sess.run(conts))

'''
輸出為5x5
1 0 2 0 3
0 6 0 8 0
4 0 5 0 6
0 12 0 14 0
7 0 8 0 9
'''

第二種情況,輸出shape為6x6

# 代碼同上,conts = tf.nn.conv2d_transpose(img,kernel,[1,5,5,1],strides=[1,2,2,1],padding='SAME')中【1,5,5,1】改為【1,6,6,1】
'''
輸出為
1 0 2 0 3 0
0 1 0 2 0 3
4 0 6 0 8 0
0 4 0 5 0 6
7 0 12 0 14 0
0 7 0 8 0 9
'''
  1. tensorflow計(jì)算規(guī)則

tensorflow執(zhí)行反卷積時(shí),會(huì)首先根據(jù)輸入的參數(shù)計(jì)算卷積結(jié)果是否成立,也即shape是否合法。

對(duì)于第一種情況,計(jì)算時(shí)先對(duì)輸入的矩陣中間補(bǔ)0,每?jī)蓚€(gè)元素之間補(bǔ)0的個(gè)數(shù)由strides確定,即補(bǔ)strides-1個(gè)0,對(duì)于3x3矩陣,補(bǔ)零之后變?yōu)?x5

         1 0 2 0 3                       1 0 2 0 3
1 2 3    0 0 0 0 0                       0 6 0 8 0
4 5 6 -> 4 0 5 0 6 -> 卷積核轉(zhuǎn)置 ->        4 0 5 0 6
7 8 9    0 0 0 0 0                       0 12 0 14 0
         7 0 8 0 9                       7 0 8 0 9

第二種情況,計(jì)算時(shí)除了對(duì)矩陣元素中間補(bǔ)零之外,還在外圍填充0(也就是same填充),此時(shí)input從3x3變?yōu)榱?x5,padding=1,但此時(shí)通過(guò)卷積公式計(jì)算
output = (input - kernelsize + 2padding) / strides + 1 = (5 - 3 + 2)/ 1 + 1 = 5,不等于6,所以繼續(xù)在外圍填充0,
tensorflow優(yōu)先在左側(cè)和上側(cè)填充,此時(shí)輸出的shape就變?yōu)?x6了。

注:這一步有的分析上也說(shuō)是上下左右都補(bǔ)零,但是輸出結(jié)果對(duì)下方和右方的最后一列進(jìn)行裁剪操作,但實(shí)際上效果是一樣的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容