逆卷積的詳細解釋ConvTranspose2d(fractionally-strided convolutions)

1.首先先定義進行卷積的參數:html

  • 輸入特徵圖爲高寬同樣的Hin*Hin大小的x
  • 卷積核大小kernel_size
  • 步長stride
  • padding填充數(填充0)
  • 輸出特徵圖爲Hout*Hout大小的y

計算式子爲:git

Hout =  floor( Hin + 2*padding - kernel_size / stride) + 1github

 

2.而後實現上面的卷積的轉置卷積c#

定義其參數爲:ide

 

  • 輸入特徵圖爲高寬同樣的Hout*Hout大小的y
  • 卷積核大小kernel_size
  • 步長stride
  • paddingnew 填充數(填充0)
  • 輸出特徵圖爲Hin*Hin大小的x

 

逆卷積的過程主要分兩步:ui

  • 對輸入的特徵圖y進行變換,獲得新的特徵圖ynew
  1. 內部變換,與卷積時設置的stride相關
  2. 外部變換,與卷積時設置的padding相關
  • 根據獲得的特徵圖進行卷積便可

1)對輸入的特徵圖y進行變換,獲得新的特徵圖ynewurl

1》內部變換spa

當卷積時設置的stride>1時,將對輸入的特徵圖y進行插值操做(interpolation)。.net

即須要在輸入的特徵圖y的每一個相鄰值之間插入(stride-1)行和列0,由於特徵圖中可以插入的相鄰位置有(height-1)個位置,因此此時獲得的特徵圖的大小由Hout*Hout(Hout即height) 變爲新的 Hout_new*Hout_new,即[Hout + (stride-1) * (Hout-1)] * [Hout + (stride-1) * (Hout-1)]htm

 

2》外部變換

爲了實現由Hout*Hout大小的y逆卷積獲得Hin*Hin大小的x,還須要設置paddingnew的值爲(kernel_size - padding - 1),這裏的padding是卷積操做時設置的padding值

因此計算式子變爲:

Hin =  floor( [Hout_new + 2*paddingnew - kernel_size] / stride') + 1

⚠️該式子變換後,定義向下取整的分母stride'值爲定值1

 

Hout_new和paddingnew的值代入上面的式子,即變爲:

Hin =  floor( Hout + (stride-1) * (Hout-1) + 2*(kernel_size - padding - 1) - kernel_size) + 1

化簡爲:

Hin =  floor( (Hout - 1) * stride - 2*padding + kernel_size - 1) + 1

     = (Hout - 1) * stride - 2*padding + kernel_size

這樣式子使的卷積Conv2d和逆卷積ConvTranspose2d在初始化時具備相同的參數,而在輸入和輸出形狀方面互爲倒數。

因此這個式子其實就是官網給出的式子:

可見這裏沒考慮output_padding

output_padding的做用:可見nn.ConvTranspose2d的參數output_padding的做用

 

3.下面舉例說明

https://github.com/vdumoulin/conv_arithmetic#convolution-arithmetic

 

1)當stride=1時,就不會進行插值操做,只會進行padding,舉例說明:

卷積操做爲:

藍色爲輸入特徵圖Hin*Hin=4*4,綠色爲輸出特徵圖Hout*Hout=2*2,卷積核kernel_size=3, stride=1

根據式子Hout =  floor( Hin + 2*padding - kernel_size / stride) + 1

可得padding=0

 

其對應的逆卷積操做爲:

藍色爲輸入特徵圖Hout*Hout=2*2,綠色爲輸出特徵圖Hin*Hin=4*4,卷積核kernel_size=3, stride=1

卷積時的padding=0

將這些值代入上面的式子Hin = (Hout - 1) * stride - 2*padding + kernel_size

果真輸入Hout*Hout=2*2能獲得輸出Hin*Hin=4*4

 

變形過程爲:

paddingnew = kernel_size - padding -1 = 3 -0 -1 = 2

因此可見下方的藍色最後的大小爲7*7 = Hout + 2*paddingnew = 2 + 2*2 = 6

⚠️這裏可見是有padding的,爲何定義是爲no padding呢?

這是由於它對應的卷積操做的padding=0

 

 1)當stride=2時,進行插值和padding操做,舉例說明:

卷積操做爲:

藍色爲輸入特徵圖Hin*Hin=5*5,綠色爲輸出特徵圖Hout*Hout=3*3,卷積核kernel_size=3, stride=2

根據式子Hout =  floor( Hin + 2*padding - kernel_size / stride) + 1

可得padding=1

 

其對應的逆卷積操做爲:

藍色爲輸入特徵圖Hout*Hout=3*3,綠色爲輸出特徵圖Hin*Hin=5*5,卷積核kernel_size=3,stride=2

卷積時的padding=1

將這些值代入上面的式子Hin = (Hout - 1) * stride - 2*padding + kernel_size

果真輸入Hout*Hout=3*3能獲得輸出Hin*Hin=5*5

 

變形操做爲:

Hout_new = Hout + (stride-1) * (Hout-1) = 3 + (2-1)*(3-1) = 5

paddingnew = kernel_size - padding -1 = 3 -1 -1 = 1

因此可見下方的藍色最後的大小爲7*7 = Hout_new + 2*paddingnew = 5 + 2*1 = 7

 

⚠️由於這裏的逆卷積對應的卷積操做的padding= 1,因此這裏不是no padding,而是padding

相關文章
相關標籤/搜索