参考资料:
https://www.cnblogs.com/shine-lee/p/11559825.html
转置卷积(transposed convolution)是一种上采样的方法。对于语义分割等问题,需要输入与输出保持相同的大小,因此需要在提取特征减小特征图大小后通过上采样的方法还原成输入的大小。
在计算机视觉当中,图像的上采样有许多方法:最近邻插值、双线性插值等。但是这些方法都是人为提前设计好了的固定模式,没有可以学习的余地。转置卷积可以通过学习参数来进行上采样。
1、卷积
卷积在没有padding的情况下会减小输入的大小。卷积可以写成矩阵乘法的形式:
例:输入为3x3:
X
=
[
x
11
x
12
x
13
x
21
x
22
x
23
x
31
x
32
x
33
]
X = {\begin{bmatrix}{} {{x_{11}}}&{{x_{12}}}&{{x_{13}}}\\ {{x_{21}}}&{{x_{22}}}&{{x_{23}}}\\ {{x_{31}}}&{{x_{32}}}&{{x_{33}}} \end{bmatrix}}
X=⎣⎡x11x21x31x12x22x32x13x23x33⎦⎤
卷积核为:
w
=
[
w
11
w
12
w
21
w
22
]
w = {\begin{bmatrix}{} {{w_{11}}}&{{w_{12}}}\\ {{w_{21}}}&{{w_{22}}} \end{bmatrix}}
w=[w11w21w12w22]
输出为:
y
=
[
y
11
y
12
y
21
y
22
]
y = {\begin{bmatrix} {{y_{11}}}&{{y_{12}}}\\ {{y_{21}}}&{{y_{22}}} \end{bmatrix}}
y=[y11y21y12y22]
如果将输入X拉成一个
9
×
1
9\times1
9×1 的向量,将输出y拉成一个
4
×
1
4\times1
4×1 的向量。
X
=
[
x
11
x
12
x
13
x
21
x
22
x
23
x
31
x
32
x
33
]
T
X = { {\begin{bmatrix} {{x_{11}}}&{{x_{12}}}&{{x_{13}}}&{{x_{21}}}&{{x_{22}}}&{{x_{23}}}&{{x_{31}}}&{{x_{32}}}&{{x_{33}}} \end{bmatrix}} ^T}
X=[x11x12x13x21x22x23x31x32x33]T
y = [ y 11 y 12 y 21 y 22 ] T y = { {\begin{bmatrix} {{y_{11}}}&{{y_{12}}}&{{y_{21}}}&{{y_{22}}} \end{bmatrix}} ^T} y=[y11y12y21y22]T
则卷积可以写为
C
=
[
w
11
w
12
0
w
21
w
22
0
0
0
0
0
w
11
w
12
0
w
21
w
22
0
0
0
0
0
0
w
11
w
12
0
w
21
w
22
0
0
0
0
0
w
11
w
12
0
w
21
w
22
]
C = {\begin{bmatrix} {{w_{11}}}&{{w_{12}}}&0&{{w_{21}}}&{{w_{22}}}&0&0&0&0\\ 0&{{w_{11}}}&{{w_{12}}}&0&{{w_{21}}}&{{w_{22}}}&0&0&0\\ 0&0&0&{{w_{11}}}&{{w_{12}}}&0&{{w_{21}}}&{{w_{22}}}&0\\ 0&0&0&0&{{w_{11}}}&{{w_{12}}}&0&{{w_{21}}}&{{w_{22}}} \end{bmatrix}}
C=⎣⎢⎢⎡w11000w12w11000w1200w210w110w22w21w12w110w220w1200w21000w22w21000w22⎦⎥⎥⎤
y = C X y = CX y=CX
其中 C i j = 0 C_{ij}=0 Cij=0 代表向量形式的 x j x_j xj 和 y i y_i yi 没有连接关系。例如 C 13 = 0 C_{13}=0 C13=0 表示 x 13 x_{13} x13 和 y 11 y_{11} y11 没有连接关系。
2、转置卷积
以上是将一个长度为9的向量映射成为了一个长度为4的向量。如果想要反过来将一个长度为4的向量映射成为一个长度为9的向量,并且保持连接关系不变。那么就可以通过转置卷积实现这种映射:
X
=
C
T
y
X = {C^T}y
X=CTy
[
w
11
0
0
0
w
12
w
11
0
0
0
w
12
0
0
w
21
0
w
11
0
w
22
w
21
w
12
w
11
0
w
22
0
w
12
0
0
w
21
0
0
0
w
22
w
21
0
0
0
w
22
]
[
y
11
y
12
y
21
y
22
]
T
{\begin{bmatrix} {{w_{11}}}&0&0&0\\ {{w_{12}}}&{{w_{11}}}&0&0\\ 0&{{w_{12}}}&0&0\\ {{w_{21}}}&0&{{w_{11}}}&0\\ {{w_{22}}}&{{w_{21}}}&{{w_{12}}}&{{w_{11}}}\\ 0&{{w_{22}}}&0&{{w_{12}}}\\ 0&0&{{w_{21}}}&0\\ 0&0&{{w_{22}}}&{{w_{21}}}\\ 0&0&0&{{w_{22}}} \end{bmatrix}} {{\begin{bmatrix} {{y_{11}}}\\ {{y_{12}}}\\ {{y_{21}}}\\ {{y_{22}}} \end{bmatrix}} ^T}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡w11w120w21w2200000w11w120w21w22000000w11w120w21w2200000w11w120w21w22⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎡y11y12y21y22⎦⎥⎥⎤T
以上操作中,
C
i
,
j
T
=
0
C^T_{i,j}=0
Ci,jT=0 代表
x
i
x_i
xi 和
y
j
y_j
yj 没有连接关系。例如
C
12
=
0
C_{12}=0
C12=0 表示映射得到的
x
11
x_{11}
x11 和
y
12
y_{12}
y12 没有连接关系(即
y
12
y_{12}
y12 对映射得到
x
11
x_{11}
x11 没有贡献)。可以看到
y
11
y_{11}
y11 同时参与了
x
11
x_{11}
x11
x
12
x_{12}
x12
x
21
x_{21}
x21
x
22
x_{22}
x22 的映射,这种连接关系就是和之前卷积是一样的。
注意这里的 X 和 y 都只是表达形状,里面的数值不同于刚才的 X 和 y
这个操作就等价于将输出y 进行
1
×
1
1\times1
1×1 的padding,原卷积核做中心对称之后,二者进行普通的卷积操作得到。
y
=
[
0
0
0
0
0
y
11
y
12
0
0
y
21
y
22
0
0
0
0
0
]
y = {\begin{bmatrix} 0&0&0&0\\ 0&{{y_{11}}}&{{y_{12}}}&0\\ 0&{{y_{21}}}&{{y_{22}}}&0\\ 0&0&0&0 \end{bmatrix}}
y=⎣⎢⎢⎡00000y11y2100y12y2200000⎦⎥⎥⎤
w = [ w 22 w 21 w 12 w 11 ] w = {\begin{bmatrix} {{w_{22}}}&{{w_{21}}}\\ {{w_{12}}}&{{w_{11}}} \end{bmatrix}} w=[w22w12w21w11]
transposed convolution和convolution的参数有无相关性取决于其应用场景:
- 在特征可视化(ZFNet)、训练阶段的反向传播中的转置卷积的参数与卷积共享(中心对称)
- 在图像分割、生成模型中的转置卷积中的参数都要通过学习获得。
3、转置卷积计算
对于卷积,有如下公式:
o
u
t
=
i
n
−
k
+
2
p
s
+
1
out = \frac{{in - k + 2p}}{s} + 1
out=sin−k+2p+1
若要用
i
n
in
in 求得
o
u
t
out
out,则要分为式中的分式能不能整除的两种情况。
整除情况
将上式变形得到
i
n
=
k
−
2
p
+
(
o
u
t
−
1
)
s
in = k - 2p + (out - 1)s
in=k−2p+(out−1)s
变成卷积公式的形式
i
n
=
o
u
t
+
(
o
u
t
−
1
)
(
s
−
1
)
−
k
+
2
(
k
−
p
−
1
)
1
+
1
in = \frac{{out + (out - 1)(s - 1) - k + 2(k - p - 1)}}{1} + 1
in=1out+(out−1)(s−1)−k+2(k−p−1)+1
令
i
n
′
=
o
u
t
+
(
o
u
t
−
1
)
(
s
−
1
)
in'=out+(out-1)(s-1)
in′=out+(out−1)(s−1),
k
′
=
k
k'=k
k′=k,
s
′
=
1
s'=1
s′=1,
p
′
=
k
−
p
−
1
p'=k-p-1
p′=k−p−1 。上式即变成标准卷积的公式
o
u
t
′
=
i
n
′
−
k
+
2
p
′
s
′
+
1
out' = \frac{{in' - k + 2p'}}{{s'}} + 1
out′=s′in′−k+2p′+1
转置卷积使用的超参数可以理解如下:
-
i n ′ = o u t + ( o u t − 1 ) ( s − 1 ) in'=out+(out-1)(s-1) in′=out+(out−1)(s−1):原来卷积的输出大小为 o u t × o u t out\times out out×out ,那么行和列方向的间隔就为 o u t − 1 out-1 out−1 。就相当于在输出 o u t out out 的基础上,在其每个间隔插入了 s − 1 s-1 s−1 个0,整体作为转置卷积的输入特征图进行计算。
-
p ′ = k − p − 1 p'=k-p-1 p′=k−p−1:对于padding,有三种情况:
- FULL Padding: p = k − 1 p=k-1 p=k−1 ,则 p ′ = 0 p'=0 p′=0 ,对应VALID Padding,即不进行填充
- SAME Padding: p = k − 1 2 p=\frac{k-1}2 p=2k−1 ,则 p ′ = k − 1 2 p'=\frac{k-1}2 p′=2k−1 ,同样对应SAME Padding
- VALID Padding: p = 0 p=0 p=0 ,则 p ′ = k − 1 p'=k-1 p′=k−1 ,对应FULL Padding
-
k ′ = k k'=k k′=k:转置卷积和卷积使用的核形状相同
-
s ′ = 1 s'=1 s′=1:转置卷积的 stride 为1
不整除
则原有卷积公式变为
o
u
t
=
i
n
−
k
+
2
p
s
+
1
+
[
(
i
n
−
k
+
2
p
)
m
o
d
s
]
out = \frac{{in - k + 2p}}{s} + 1 + \left[ {\left( {in - k + 2p} \right)\bmod s} \right]
out=sin−k+2p+1+[(in−k+2p)mods]
将
(
i
n
−
k
+
2
p
)
m
o
d
s
{\left( {in - k + 2p} \right)\bmod s}
(in−k+2p)mods 记为
a
a
a,则有
o
u
t
=
i
n
−
k
+
2
p
s
+
1
+
a
out = \frac{{in - k + 2p}}{s} + 1+a
out=sin−k+2p+1+a
o u t ′ = i n ′ − k + 2 p ′ + a s ′ + 1 out' = \frac{{in' - k + 2p'+a}}{{s'}} + 1 out′=s′in′−k+2p′+a+1
所以,在转置卷积的输入特征图的右边和下边添加a行和a列填充再进行卷积即可。至于为什么是右边和下边,可以举个简单的例子
输入特征图大小为
4
×
4
4\times4
4×4,用
k
e
r
n
e
l
=
3
×
3
kernel=3\times 3
kernel=3×3 ,
s
t
i
d
e
=
2
stide = 2
stide=2 ,
p
a
d
d
i
n
g
=
0
padding=0
padding=0 的卷积核卷积
i
n
p
u
t
=
[
i
11
i
12
i
13
i
14
i
21
i
22
i
23
i
24
i
31
i
32
i
33
i
34
i
41
i
42
i
43
i
44
]
input ={\begin{bmatrix} {{i_{11}}}&{{i_{12}}}&{{i_{13}}}&{{i_{14}}}\\ {{i_{21}}}&{{i_{22}}}&{{i_{23}}}&{{i_{24}}}\\ {{i_{31}}}&{{i_{32}}}&{{i_{33}}}&{{i_{34}}}\\ {{i_{41}}}&{{i_{42}}}&{{i_{43}}}&{{i_{44}}} \end{bmatrix}}
input=⎣⎢⎢⎡i11i21i31i41i12i22i32i42i13i23i33i43i14i24i34i44⎦⎥⎥⎤
w = [ w 11 w 12 w 13 w 21 w 22 w 23 w 31 w 32 w 33 ] w = {\begin{bmatrix} {{w_{11}}}&{{w_{12}}}&{{w_{13}}}\\ {{w_{21}}}&{{w_{22}}}&{{w_{23}}}\\ {{w_{31}}}&{{w_{32}}}&{{w_{33}}} \end{bmatrix}} w=⎣⎡w11w21w31w12w22w32w13w23w33⎦⎤
这时候不能整除,因此输出特征图为 1 × 1 1\times 1 1×1 的,实际上输入特征图的最右边一列和最下边一行并没有参与生成输入特征图。因此在不能整除的情况下,转置卷积在最右边和最下边补0可以保证之前的连接关系不变。
Pytorch实验
输入和卷积核都是
2
×
2
2\times 2
2×2 的张量
[
0
1
2
3
]
{\begin{bmatrix} 0&1\\ 2&3 \end{bmatrix}}
[0213]
import torch
x = torch.tensor([0.0,1.0,2.0,3.0]).reshape(1,1,2,2)
k = torch.tensor([0.0,1.0,2.0,3.0]).reshape(1,1,2,2)
tconv = torch.nn.ConvTranspose2d(1,1,kernel_size=(3,3),bias=False)
tconv.weight.data = k #实际卷积的时候要将k进行中心对称
Y = tconv(x)
print(Y)
输出:
tensor([[[[ 0., 0., 1.],
[ 0., 4., 6.],
[ 4., 12., 9.]]]], grad_fn=<SlowConvTranspose2DBackward0>)