卷積和反卷積詳細說明


轉載:https://zhuanlan.zhihu.com/p/124626648

轉載:https://www.cnblogs.com/wanghui-garcia/p/10791328.html

1. 卷積 Convolution

1.1 卷積輸出尺寸

輸出圖像尺寸可以根據以下公式獲得

[公式]

  • [公式] :輸入圖像尺寸
  • [公式] : padding 大小
  • [公式] : 卷積核大小
  • [公式] : 步長

卷積:藍色的輸入圖片(4 x4),深藍色代表卷積核(3 x 3),綠色為輸出圖像(2 x 2)

假如現在有一個4 x 4的圖片, 使用一個3 x 3的kernel 進行卷積

圖片: [公式] 卷積核: [公式]

strides = 1 , padding = 0, 卷積后,輸出圖像的尺寸為 [公式]

如果卷積核很大,那么可以使用傅里葉變換, 提升卷積的性能。

2. 反卷積 Transposed Convolution

由於卷積核一般比原始圖像小,所以卷積之后的圖像尺寸往往會變小。有時候我們需要將卷積后的圖像還原成原始圖像的尺寸,即實現圖像從小分辨率到大分辨率的映射,這種操作就叫做上采樣(Upsampling)。而反卷積正是一種上采樣方法。

反卷積,又稱為轉置卷積(Transposed Convolution,),它是一種特殊的卷積,先padding來擴大圖像尺寸,緊接着跟正向卷積一樣,旋轉卷積核180度,再進行卷積計算。看上去就像,已知正向卷積的輸出圖像,卷積核,得到正向卷積中的原始圖像(並非真的得到原始圖像,像素點是不一樣的,但是尺寸是一致的)。

它看上去像是正向卷積的逆運算,但其實並不是。因為反卷積只能還原原始圖像的尺寸,但是並不能真的恢復原始圖像內容,即每個元素值其實是不一樣的。

卷積過程中:

[公式] 表示輸出, [公式] 表示輸入, [公式] :表示kernel的大小, [公式]:表示padding, [公式] : 表達strides

反卷積過程中:

[公式] 表示輸出, [公式] 表示輸入, [公式] :表示kernel的大小, [公式]:表示padding, [公式] : 表達strides

卷積后的 [公式] 則反卷積的 [公式] , 一般卷積核是不會變的, [公式] ,需要注意的是,卷積與反卷積的padding很可能是不一樣。

2.1 Striding

反卷積的Striding跟卷積有點不一樣,它在輸入的每個元素之間插入 [公式] 個值為0的元素

Transposed convolution : Striding

如果我們將反卷積看成是一種特殊的卷積,它其實是根據反卷積中指定的步長strides, 修改了輸入 [公式], 根據strding 進行補0操作,得到 [公式] , 其大小變為 [公式] , 然后對 [公式] 進行s=1的卷積。例如,對應上面的三個子圖, [公式] 對應的 [公式] , [公式] 對應的 [公式] , [公式] 對應的 [公式] 。

反卷積:藍色是輸入(3 x 3), 灰色是卷積核(3 x 3), 綠色是輸出(5 x 5),padding=1,strides = 2

反卷積:藍色是輸入(5 x 5), 灰色是卷積核(3 x 3), 綠色是輸出(5 x 5),padding=1,strides =1

3 反卷積的輸出尺寸

可見這里沒考慮output_padding

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

論文 A guide to convolution arithmetic for deep learning 涉及了14種有關反卷積的尺寸大小公式的關系,但是歸納起來就只有兩種情況。

3.1 [公式]

反卷積的輸出尺寸為 [公式] 或者 [公式]

對應上面提到的卷積的例子,分別用上面兩條公式進行驗算,驗算結果都成立。

卷積時, [公式] ,[公式] , [公式] , [公式] , 所以計算的結果 [公式]

反卷積, [公式] , [公式] , [公式] , [公式] ,

代入第一個式子 [公式]

代入第二個式子 [公式]

反卷積,藍色是輸入(2 x 2), 灰色是卷積核(3 x 3), 綠色是輸出(4 x 4),padding=2

4.下面舉例說明

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