Pytorch中的卷積與反捲積詳解(conv2d和convTranspose2d)
卷積和反捲積是圖片計算在深度學習中常用的上採樣和下采樣操作。相比其他採樣操作,卷積計算不僅可以保存參數的梯度傳遞(適用用BP),還可以改變圖片的通道以更好的整合局部特徵。
在torchn.nn中,卷積操作是一個函數,輸入爲一組圖片或特徵變量[n,c,w,h],輸出也爲一組變量[n,c,w,h].變量類型爲tensor.
1.Conv2d
卷積可以壓縮整合圖片特徵,讓通道/寬/高分別爲:[c,w,h]的特徵圖片通過Conv2d。變爲更多的通道(維度)c,更小的尺寸W/H.
這裏有幾個參數比較重要:
- padding
就是填充的意思,通過padding,可以填充圖片的邊緣,讓圖片的邊緣的特徵得到更充分的計算(不至於被截斷)
- kernel_size
卷積核尺寸,尺寸越大‘感受野’越大,及處理的特徵單位越大,同時計算量也越大
- stide
卷積核移動的步數,默認1步,增大步數會忽略局部細節計算,適用於高分辨率的計算提升
1.2 卷積操作及可視化
藍色爲輸入,藍色上的陰影爲卷積核(kernel),綠色爲輸出,藍色邊緣的白色框爲padding
- padding=0,stride=1,kernel_size=3
尺寸從[4,4]->[2,2]
import torch
import torch.nn as nn
x = torch.randn(1,1,4,4)
l = nn.Conv2d(1,1,3)#Conv2d(1, 1, kernel_size=(3, 3), stride=(1, 1),padding=0)
y = l(x) # y.shape:[1,1,2,2]
- padding=2,stride=1,kernel_size=4
尺寸從[5,5]->[6,6]
import torch
import torch.nn as nn
x = torch.randn(1,1,5,5)
l = nn.Conv2d(1,1,4,padding=2)#Conv2d(1, 1, kernel_size=4,stride=1,padding=2)
y = l(x) # y.shape:[1,1,6,6]
2.ConvTranspose2d
轉置卷積,也稱爲反捲積(deconvlution)和分部卷積(fractionally-strided convolution)。爲卷積的逆操作,即把特徵的維度壓縮,但尺寸放大。
函數形式如下:
torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1, padding_mode=‘zeros’)
2.1 操作及可視化
這裏需要注意的是padding和stride和conv2d不同,padding不是藍色的留白,是kernel像圖像中心移動的單位。如下當padding=0時,卷積核剛好和輸入邊緣相交一個單位。因此pandding可以理解爲卷積核向中心移動的步數。 同時stride也不再是kernel移動的步數,變爲輸入單元彼此散開的步數。
- padding=0,kernel_size=3,stride=1
import torch
import torch.nn as nn
x = torch.randn(1,1,2,2)
l = nn.ConvTranspose2d(1,1,3)#Conv2d(1, 1, kernel_size=3,stride=1,padding=0)
y = l(x) # y.shape:[1,1,4,4]
- padding=2,kernel_size=4,stride=1
import torch
import torch.nn as nn
x = torch.randn(1,1,6,6)
l = nn.ConvTranspose2d(1,1,4,padding=2)#Conv2d(1, 1, kernel_size=4,stride=1,padding=2)
y = l(x) # y.shape:[1,1,5,5]
- padding=2,kernel_size=3,stride=1
注意這個kernel也是向中心內移了2(對比padding=0),所以padding爲2
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-akm2ZYNY-1587864415801)(https://s1.ax1x.com/2020/04/26/J662rt.gif)]
import torch
import torch.nn as nn
x = torch.randn(1,1,7,7)
l = nn.ConvTranspose2d(1,1,3,padding=2)#Conv2d(1, 1, kernel_size=3,stride=1,padding=2)
y = l(x) # y.shape:[1,1,5,5]
- padding=0,kernel_size=3,stride=2
import torch
import torch.nn as nn
x = torch.randn(1,1,2,2)
l = nn.ConvTranspose2d(1,1,3,stride=2,padding=0)#Conv2d(1, 1, kernel_size=3,stride=2,padding=0)
y = l(x) # y.shape:[1,1,5,5]
- padding=1,kernel_size=3,stride=2
import torch
import torch.nn as nn
x = torch.randn(1,1,3,3)
l = nn.ConvTranspose2d(1,1,3,stride=2,padding=1)#Conv2d(1, 1, kernel_size=3,stride=2,padding=1)
y = l(x) # y.shape:[1,1,5,5]
參考
https://pytorch.org/docs/master/nn.html#torch.nn.ConvTranspose2d
https://github.com/vdumoulin/conv_arithmetic