如果反卷积操作中步长大于1, 那么不仅需要在四周补零, 每行元素和每列元素之间均需要补零
示例-2: 步长为 2
输入数据 1*1*3*3(Batch 和 Channel 均为 1)
In [1]: import torch
In [2]: torch.manual_seed(5);
In [3]: x = torch.randint(6, size=(1,1,3,3), dtype=torch.float)
In [4]: x
Out[4]:
tensor([[[[5., 0., 1.],
[3., 2., 4.],
[4., 5., 0.]]]])
卷积核 1*1*2*2(与示例-1 一致)
In [5]: w = torch.tensor([[1,2],[0,1]], dtype=torch.float).view(1,1,2,2)
In [6]: w
Out[6]:
tensor([[[[1., 2.],
[0., 1.]]]])
创建反卷积层, 无偏置
In [7]: from torch import nn
In [8]: layer = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=2, stride=2, padding=0, bias=False)
In [9]: layer.weight = nn.Parameter(w)
In [10]: layer.eval();
手动计算
- 翻转卷积核
- 填充零(包括四周补零与行列之间补零)
步长为 2 时, 行列之间补充一行或一列零
计算输出尺寸, oup = (inp + 2*padding - kernel_size) / stride + 1
, 将 oup=3,padding=0,kernel_size=2,stride=2
代入, 可得 inp=6
, 即输出尺寸为6, 为了得到此输出, 还需在四周补充一圈零
- 正向卷积
此处的卷积, 步长视为1
使用 PyTorch 计算
In [11]: with torch.no_grad():
...: y = layer(x)
...:
In [12]: y
Out[12]:
tensor([[[[ 5., 10., 0., 0., 1., 2.],
[ 0., 5., 0., 0., 0., 1.],
[ 3., 6., 2., 4., 4., 8.],
[ 0., 3., 0., 2., 0., 4.],
[ 4., 8., 5., 10., 0., 0.],
[ 0., 4., 0., 5., 0., 0.]]]])