根据我个人的经验和偏好,理解数学概念的最好方式之一就是赋予其物理意义。把f(t)看做输入,g(t)看做系统的衰减系数,卷积就比较好理解了。
在某一时刻n,该系统对f(n)的响应值就是f(n)xg(0),但系统的总输出C(n),不仅跟当前输入的f(n)有关,还跟以往所有的输入f(0)~f(n-1)都有关,按上图的衰减函数特性,越久远的输入对当前的输出值贡献就越小。
很容易得出,C(n) = f(0)xg(n) + f(1)xg(n-1) + f(2)xg(n-2) + ... f(n-1)xg(1) + f(n)xg(0),也就是上面的离散卷积公式。
比如,在n=5时刻,系统的输出C(5) = f(0)xg(5) + f(1)xg(4) + ... + f(5)xg(0) = 10x0.3 + 15x0.4 + 4x0.6 + 12x0.8 + 10x0.9 + 17x1 = 47,可以看到f(t)*g(t)是一个交叉相乘再累加的过程。
我们继续看n=6时刻,C(6) = f(0)xg(6) + f(1)xg(5) + ... + f(6)xg(0),n=7时刻,C(7) = f(0)xg(7) + f(1)xg(6) + ... + f(7)xg(0),以此类推。
但是上图看着实在太别扭,对g(t)做一下变形,让卷积过程看起来更自然,如下图示。
g(-t) = g(t),两者互为镜像。接下来卷积就变成g(-t)的滑动对齐f(t)然后乘加的过程了。可以这么理解,镜像翻转和滑动体现了“卷”,而乘加体现了“积”。
C(5):
C(6):
C(7):
为了形象地展示卷积过程,把f(t)和g(t)做成一维滑窗的样子推演一遍。
再次说明,f(t)是信号输入,g(t)是系统响应,g(-t)是镜像响应函数。上图中,f(t)只在0~4有输入值,其他时刻可以认为都是0;而g(t)只在0~2有值,其他时刻都是0,这说明系统的“记忆”只有两拍,也就是说,某一时刻系统的输出只与当前输入,以及上次和上上次输入有关,这是网上很多博主没有提到的,然而理解这一点非常重要。
上图是一维full卷积过程,也就是f(t)输入g(t)系统后,在输出端得到什么输出。C(0) = f(0)xg(0),即0时刻系统输出只跟0时刻输入有关,因为在此之前的输入都是0;C(2) = f(0)xg(2) + f(1)xg(1) + f(2)xg(0),即2时刻系统输出是由0,1,2三个时刻的输入叠加而来的;C(6) = f(4)xg(2),6时刻虽然没有输入了,但是因为系统有两拍的“记忆”效应,所以此时仍残留有4时刻输入的影响。系统的“记忆”效应造成了输出比输入要长。
我们可以把f(t)叫做Feature(特征),把g(t)叫做Kernel(卷积核),那么有以下知识点:
1)卷积核的大小定义了卷积的视野,也就是系统的“记忆”有多长;
2)除了上面例子中的full卷积,还有其他类型的卷积方式,它们的区别包括步长(stride)和卷积范围(scope)。
有了一维卷积的基本概念,理解二维卷积也就变得容易了。