一. 基本操作
不同于一般的卷积做的是多个元素->1个元素,转置卷积是从1个元素到多个元素
二. 填充、步幅和多通道
1. 填充
- 常规卷积中padding是在输入的外圈添加元素,转置卷积中的padding则是在输出中删除外圈的元素
x = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
x = x.reshape(1, 1, 2, 2)
k = torch.tensor([[4.0, 7.0], [2.0, 2.0]])
k = k.reshape(1, 1, 2, 2)
tconv1 = nn.ConvTranspose2d(1, 1, kernel_size=2, padding=0, bias=False)
tconv1.weight.data = k
print(tconv1(x))
tconv2 = nn.ConvTranspose2d(1, 1, kernel_size=2, padding=1, bias=False)
tconv2.weight.data = k
print(tconv2(x))
Output:
tensor([[[[ 0., 4., 7.],
[ 8., 28., 23.],
[ 4., 10., 6.]]]], grad_fn=<ConvolutionBackward0>)
tensor([[[[28.]]]], grad_fn=<ConvolutionBackward0>)
2. 步幅
- 步幅这里指的是每一个像素扩展出的的输出的摆放方式。
x = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
x = x.reshape(1, 1, 2, 2)
k = torch.tensor([[4.0, 7.0], [2.0, 2.0]])
k = k.reshape(1, 1, 2, 2)
tconv1 = nn.ConvTranspose2d(1, 1, kernel_size=2, stride=4, bias=False)
tconv1.weight.data = k
print(tconv1(X))
Output:
tensor([[[[ 0., 0., 0., 0., 4., 7.],
[ 0., 0., 0., 0., 2., 2.],
[ 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.],
[ 8., 14., 0., 0., 12., 21.],
[ 4., 4., 0., 0., 6., 6.]]]], grad_fn=<ConvolutionBackward0>)
3. 多通道
nn.ConvTranspose2d(2, 1, kernel_size=2, bias=False)
指的是用1个\(2*2*2\)的卷积核做转置卷积。
x = torch.tensor([[[0, 1.0], [2.0, 3.0]],
[[4, 5], [7, 8]]])
x = x.reshape(1, 2, 2, 2)
k = torch.tensor([[[0.0, 1.0], [2.0, 3.0]],
[[4, 5], [2, 3]]])
k = k.reshape(2, 1, 2, 2)
tconv3 = nn.ConvTranspose2d(2, 1, kernel_size=2, bias=False)
tconv3.weight.data = k
print(x)
print(k)
print(tconv3(x))
print(tconv3(x).shape)
Output:
tensor([[[[0., 1.],
[2., 3.]],
[[4., 5.],
[7., 8.]]]])
tensor([[[[0., 1.],
[2., 3.]]],
[[[4., 5.],
[2., 3.]]]])
tensor([[[[16., 40., 26.],
[36., 93., 61.],
[18., 49., 33.]]]], grad_fn=<ConvolutionBackward0>)
torch.Size([1, 1, 3, 3])
- 下面分析下为啥是这个结果
原图中第一个像素的扩展方式为:
\[0*\begin{matrix}0 & 1 \\2 & 3 \\\end{matrix}+4*\begin{matrix}4 & 5 \\2 & 3 \\\end{matrix}=\begin{matrix}16 & 20\\8 & 12\\\end{matrix}\]
09-13 21:20