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


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

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

計算式子為:

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

 

2.然后實現上面的卷積的轉置卷積

定義其參數為:

 

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

 

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

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

1)對輸入的特征圖y進行變換,得到新的特征圖ynew

1》內部變換

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

即需要在輸入的特征圖y的每個相鄰值之間插入(stride-1)行和列0,因為特征圖中能夠插入的相鄰位置有(height-1)個位置,所以此時得到的特征圖的大小由Hout*Hout(Hout即height) 變為新的 Hout_new*Hout_new,即[Hout + (stride-1) * (Hout-1)] * [Hout + (stride-1) * (Hout-1)]

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM