卷积、深度学习中的卷积和反卷积
1 信号处理中的卷积与互相关
1) 信号处理中的卷积操作
在信号处理中,对于信号
f
(
t
)
f(t)
f(t)和滤波器
g
(
t
)
g(t)
g(t)。
对信号进行滤波即对
f
(
t
)
f(t)
f(t)和
g
(
t
)
g(t)
g(t)执行卷积操作,卷积公式为:
f
(
t
)
∗
g
(
t
)
=
∫
−
∞
∞
f
(
τ
)
g
(
t
−
τ
)
d
τ
f(t)*g(t)=\int_{-\infty}^{\infty} f(\tau)g(t-\tau)\, d\tau
f(t)∗g(t)=∫−∞∞f(τ)g(t−τ)dτ
滤波器在卷积时先进行反转得到
g
(
−
τ
)
g(-\tau)
g(−τ),再位移
x
x
x得位移后的函数
g
(
t
−
τ
)
g(t-\tau)
g(t−τ)。
然后对信号
f
(
t
)
f(t)
f(t)滑动乘积,并对乘积进行积分或者累加得卷积结果。
由以上可以看出,信号处理中的卷积是对滤波器进行反转位移后,再沿轴滑动,每一个滑动位置相交区域的面积,即为该位置的卷积值。
2) 信号处理中的互相关
理解了卷积操作之后理解互相关更加简单,互相关是两个函数之间的滑动点击或滑动内积。相对于卷积操作来说,互相关中的滤波器
g
(
t
)
g(t)
g(t)不进行反转,直接沿轴滑动,同样每一个滑动位置处的卷积值为两函数相交区域的面积。
2 深度学习中的卷积操作
在深度学习中,卷积操作按理也是对信号进行卷积,那么滤波器就要反转再位移滑动进行积分。但是在实际应用中我们不将其反转,而是按照互相关的方式直接相乘然后积分,本质上是对信号按元素相乘累加得卷积值。例如对如下矩阵
[
1
1
1
0
0
0
1
1
1
0
0
0
1
1
1
0
0
1
1
0
0
1
1
0
0
]
\begin{bmatrix}1&1&1&0&0\\0&1&1&1&0\\0&0&1&1&1\\0&0&1&1&0\\0&1&1&0&0\end{bmatrix}
⎣⎢⎢⎢⎢⎡1000011001111110111000100⎦⎥⎥⎥⎥⎤,用3x3的卷积核
[
1
0
1
0
1
0
1
0
1
]
\begin{bmatrix}1&0&1\\0&1&0\\1&0&1\end{bmatrix}
⎣⎡101010101⎦⎤进行位移相乘然后累加9个数得到卷积值,对于第一个卷积值为矩阵
[
1
1
1
0
1
1
0
0
1
]
\begin{bmatrix}1&1&1\\0&1&1\\0&0&1\end{bmatrix}
⎣⎡100110111⎦⎤和卷积核对应元素相乘再累加的结果即
1
×
1
+
1
×
0
+
1
×
1
+
0
×
0
+
1
×
1
+
0
×
1
+
0
×
1
+
1
×
0
+
1
×
1
=
4
1\times1+1\times0+1\times1+0\times0+1\times1+0\times1+0\times1+1\times0+1\times1=4
1×1+1×0+1×1+0×0+1×1+0×1+0×1+1×0+1×1=4,其他卷积结果以此类推,得到卷积映射
[
4
3
4
2
4
3
2
3
4
]
\begin{bmatrix}4&3&4\\2&4&3\\2&3&4\end{bmatrix}
⎣⎡422343434⎦⎤
再以一个图来了解一些卷积的过程
由此可见深度学习中的卷积操作并不是信号处理中,那样严格意义上的卷积,而是互相关。那么大家就会有疑问,那这还能算卷积吗?答案是肯定的。对于信号处理中滤波器与信号的卷积,信号和滤波器都是确定的,也就是滤波器已经被认为设计好了,只需要进行卷积滤波就可以达到预期结果。而对于深度学习,一个卷积核也相当于一个滤波器,但是这个滤波器并没有被人工设计好,相反,它的初始化参数可以是随机的,而这些参数需要在不断的训练中进行优化更新,这一过程就是卷积的学习过程。经过不断地学习优化,滤波器才能达到理想地状态。那么假设此过程中的输入信号为上边的
f
(
t
)
f(t)
f(t),初始化滤波器为
g
′
(
t
)
g'(t)
g′(t),那么经过学习优化,最终得到的滤波器
g
′
(
t
)
g'(t)
g′(t)的参数与
g
(
t
)
g(t)
g(t)相同,即
g
′
(
t
)
=
g
(
t
)
g'(t)=g(t)
g′(t)=g(t)。如图所示,经过学习优化,滤波器自己调整参数转过来了。
3 反卷积
反卷积也可以称为卷积转置或转置卷积,但其并非卷积操作的反向操作。由上边的介绍可以指导,卷积操作会将输入映射到一个更小的featumap中,那么反卷积则可以将这个小的featumap映射为一个大的featuremap,但是切记,这不是卷积的反向操作,也不会得到与原始输入一样的输出,但是却保留了映射中相对位置关系的信息,我们可以将其理解为上采样。
从动图中可以看出,一个3x3的输入经过一个3x3的反卷积核的处理可以得到一个7x7的featumap。
那么这一操作是怎么实现的呢?这里就需要先理解一个概念——卷积矩阵,顾名思义就是把卷积操作写成一个矩阵的形式,通过一次矩阵乘法就可以完成整个卷积操作。卷积矩阵的构造是通过对卷积核的重排列构造的。例如对于3x3的卷积核
[
1
4
1
1
4
3
3
3
1
]
\begin{bmatrix}1&4&1\\1&4&3\\3&3&1\end{bmatrix}
⎣⎡113443131⎦⎤可以重排列为一个4x16的卷积矩阵
[
1
4
1
0
1
4
3
0
3
3
1
0
0
0
0
0
0
1
4
1
0
1
4
3
0
3
3
1
0
0
0
0
0
0
0
0
1
4
1
0
1
4
3
0
3
3
1
0
0
0
0
0
0
1
4
1
0
1
4
3
0
3
3
1
]
\begin{bmatrix}1&4&1&0&1&4&3&0&3&3&1&0&0&0&0&0\\0&1&4&1&0&1&4&3&0&3&3&1&0&0&0&0\\0&0&0&0&1&4&1&0&1&4&3&0&3&3&1&0\\0&0&0&0&0&1&4&1&0&1&4&3&0&3&3&1\end{bmatrix}
⎣⎢⎢⎡1000410014000100101041413414030130103341133401030030003300130001⎦⎥⎥⎤。这样对于一个4x4的输入矩阵就可以通过一次矩阵相乘得到卷积操作的结果。那难道是用4x4乘4x16得到一个4x16的结果吗。首先我们来看正常的卷积操作。设该输入矩阵为
[
4
5
8
7
1
8
8
8
3
6
6
4
6
5
7
8
]
\begin{bmatrix}4&5&8&7\\1&8&8&8\\3&6&6&4\\6&5&7&8\end{bmatrix}
⎣⎢⎢⎡4136586588677848⎦⎥⎥⎤,以1为步长没有填充,那么卷积结果为
[
122
148
126
134
]
\begin{bmatrix}122&148\\126&134\end{bmatrix}
[122126148134],这是一个2x2的矩阵,不是4x16的矩阵啊,那是哪里出了错误呢?错误就出在矩阵相乘的地方,这里不能直接用输入的4x4矩阵与卷积矩阵相乘,而是应该将输入矩阵转换为一个1x16的列向量,那么该列向量与卷积矩阵相乘会得到一个1x4的向量,再将该向量reshape为2x2的矩阵即为卷积结果。下面我们来看具体过程,1x16的列向量为
[
4
5
8
7
1
8
8
8
3
6
6
4
6
5
7
8
]
\begin{bmatrix}4&5&8&7&1&8&8&8&3&6&6&4&6&5&7&8\end{bmatrix}
[4587188836646578],与卷积矩阵相乘后得
[
122
148
126
134
]
\begin{bmatrix}122&148&126&134\end{bmatrix}
[122148126134],再reshape则结果为
[
122
148
126
134
]
\begin{bmatrix}122&148\\126&134\end{bmatrix}
[122126148134],与原始的卷积操作的结果是相同的。
到这里大家可能对反卷积或者是转置卷积有了一定想法,没错,此时就是要将卷积矩阵进行转置,那么就可以得到一个16x4的转置卷积矩阵,对于输出的2x2的featuremap,reshape为4x1,再将二者相乘即可得到一个16x1的转置卷积的结果,此时再reshape即可得到一个4x4的输出。
[
1
0
0
0
4
1
0
0
1
4
0
0
0
1
0
0
1
0
1
0
4
1
4
1
3
4
1
4
0
3
0
1
3
0
1
0
3
3
4
1
1
3
3
4
0
1
0
3
0
0
3
0
0
0
3
3
0
0
1
3
0
0
0
1
]
×
[
122
148
126
134
]
=
[
2
9
6
1
6
29
30
7
10
29
33
13
12
24
16
4
]
\begin{bmatrix}1&0&0&0\\4&1&0&0\\1&4&0&0\\0&1&0&0\\1&0&1&0\\4&1&4&1\\3&4&1&4\\0&3&0&1\\3&0&1&0\\3&3&4&1\\1&3&3&4\\0&1&0&3\\0&0&3&0\\0&0&3&3\\0&0&1&3\\0&0&0&1\end{bmatrix}\times\begin{bmatrix}122\\148\\126\\134\end{bmatrix}=\begin{bmatrix}2\\9\\6\\1\\6\\29\\30\\7\\10\\29\\33\\13\\12\\24\\16\\4\end{bmatrix}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡1410143033100000014101430331000000001410143033100000014101430331⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤×⎣⎢⎢⎡122148126134⎦⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡2961629307102933131224164⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤,将计算的列向量reshape可得
[
2
9
6
1
6
29
30
7
10
29
33
13
12
24
16
4
]
\begin{bmatrix}2&9&6&1\\6&29&30&7\\10&29&33&13\\12&24&16&4\end{bmatrix}
⎣⎢⎢⎡2610129292924630331617134⎦⎥⎥⎤,这样就通过转置卷积将2x2的矩阵反卷为一个4x4的矩阵,但是从结果也可以看出反卷积的结果与原始输入信号不同。只是保留了位置信息,以及得到了想要的形状。
反卷积可以应用在生成对抗网络(GAN),的生成器上,大家可以参考DCGAN进行理解。