卷积和反卷积是图片计算在深度学习中常用的上采样和下采样操作。相比其他采样操作,卷积层可以通过更新参数拟合图像特征(通过梯度反向传递即BP)。
另外作为特征提取的常用操作,卷积在计算中可以改变图片计算后的通道,把参数压缩为数量更少的卷积核。相比上一代的全连接操作,能降低计算量的同时,充分整合图像的局部特征。
在torchn.nn中,卷积操作是一个函数,输入为一组图片或特征变量[n,c,w,h],输出也为一组变量[n,c,w,h].变量类型为tensor.
卷积可以压缩整合图片特征,让通道/宽/高分别为:[c,w,h]的特征图片通过Conv2d。变为更多的通道(维度)c,更小的尺寸W/H.
这里有几个参数比较重要:
就是填充的意思,通过padding,可以填充图片的边缘,让图片的边缘的特征得到更充分的计算(不至于被截断)
卷积核尺寸,尺寸越大‘感受野’越大,及处理的特征单位越大,同时计算量也越大
卷积核移动的步数,默认1步,增大步数会忽略局部细节计算,适用于高分辨率的计算提升
蓝色为输入,蓝色上的阴影为卷积核(kernel),绿色为输出,蓝色边缘的白色框为padding
尺寸从[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]
尺寸从[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]
转置卷积,也称为反卷积(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’)
这里需要注意的是padding和stride和conv2d不同,padding不是蓝色的留白,是kernel像图像中心移动的单位。如下当padding=0时,卷积核刚好和输入边缘相交一个单位。因此pandding可以理解为卷积核向中心移动的步数。 同时stride也不再是kernel移动的步数,变为输入单元彼此散开的步数。
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]
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]
注意这个kernel也是向中心内移了2(对比padding=0),所以padding为2
图片
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]
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]
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