最近在研究卷积,发现深度学习中的卷积和数学中的卷积存在差异,这里记录下数学中的一维离散线性卷积。
一、数学公式
一维离散线性卷积的计算公式如下:
(1)卷积运算满足交换律,即a和v的顺序可以颠倒。
(2)计算时,v(m)先反转到v(-m),再平移到v(a-m)。
二、numpy库convolve函数
numpy.convolve(a, v, mode='full')
假定序列a长度为N,序列b长度为M,则有
-
mode=full,则结果序列长度=N+M-1,包括重合的端点处的卷积结果,有边界效应。
-
mode=same,则结果序列长度=max(N,M),有边界效应。
-
mode=valid,则结果序列长度=max(N,M)-min(N,M)+1,只返回卷积核和输入序列完全重合时的结果,没有边界效应。
说明:真正计算时,需要序列a的长度大于序列v的长度,否则,numpy内部自动交换顺序。
三、离线线性卷积的计算过程
计算步骤如下:
-
步骤1:先对卷积核v/g(x)做180度旋转。
-
步骤2:对旋转后的卷积核,从左向后不断滑动,起始时刻重合位置数目为1,右滑动过程中重合位置数目不断增大,再继续右滑动,重合位置数目降低到1时结束滑动。
-
步骤3:每一步滑动之后,对应位置相乘再求和。
图例如下:
a记做f(x),v记做g(x),a是输入序列,v是卷积核(滤波器)。
注意点:在计算时候,如果卷积核的有效下标不存正负数,当下标为负数时卷积核值为0。
补充说明:输入序列f(x)和卷积核(滤波器)g(x)中的x物理意义是不同的。
(1)对于f(x),x是时间步,f(x)是在不同时间步上的取值;
(2)对于g(x),x代表在一个窗口大小的时长内相距初始时刻的距离,x越大,g(x)代表越靠近当前时间步的f(x)权重。
四、python代码实现
import numpy as np
# nunpy自带的一维线性卷积
r2 = np.convolve(v, a, mode="full")
print(r2)
# 自行实现
r = []
a = dict(enumerate(a))
v = dict(enumerate(v))
for i in range(len(a) + len(v) - 1):
s = 0
for j in range(len(a)):
s += a[j] * v.get(i - j, 0) # 卷积核下标不存在时返回0
r.append(s)
r = np.array(r)
print(r)
结果如下,和numpy自带的卷积函数结果一致,验证代码正确性。
[0. 1. 2.5 4. 5.5 7. 2.5]
[0. 1. 2.5 4. 5.5 7. 2.5]
更多学习笔记可以关注我的微信公众号「kelly学技术」,欢迎交流。