理解NumPy的卷积操作

94

在计算简单移动平均值时,使用numpy.convolve似乎可以完成任务。

问题:当您使用np.convolve(values, weights, 'valid')时,计算是如何进行的?

当文档中提到卷积乘积仅在信号完全重叠的点处给出时,这两个信号是指什么?

如果任何解释都包括示例和插图,则会非常有用。

window = 10
weights = np.repeat(1.0, window)/window
smas = np.convolve(values, weights, 'valid')

NumPy手册中的numpy.convolve以及底部的参考文献很好地解释了卷积和这个特定实现。 - rickhg12hs
2个回答

187

卷积是一种在信号处理中主要使用的数学运算符。Numpy只是使用这个信号处理术语来定义它,因此有"signal"的引用。在numpy中,数组就是一个信号。两个信号的卷积被定义为第一个信号的积分反转,扫过("卷积到")第二个信号并在重叠向量的每个位置上乘以标量积。当第一个信号是2-D矩阵时,通常称之为核心,特别是在图像处理或神经网络中,而反转则成为2-D镜像(不是转置)。可以使用维基百科上的动画更清楚地理解。

Convolutions的定义因上下文而异。有些在重叠开始时开始卷积,而有些则仅在重叠部分开始。在numpy的“valid”模式中,指定重叠始终是完整的。它称为“valid”,因为结果中给出的每个值都是不需要数据外推的。
例如,如果您的数组X长度为2,数组Y长度为4,则在“valid”模式下将X卷积到Y会给您一个长度为3的数组。
第一步,对于X = [4 3]Y = [1 1 5 5]:
[3 4]                   (X is reversed from [4 3] to [3 4], see note)
[1 1 5 5]
= 3 * 1 + 4 * 1 = 7

注意:如果X没有被反转,这个操作将被称为互相关而不是卷积。
第二步:
  [3 4]
[1 1 5 5]
= 3 * 1 + 4 * 5 = 23

第三步:
    [3 4]
[1 1 5 5]
= 3 * 5 + 4 * 5 = 35

对于模式“valid”的卷积结果将是[7 23 35]。
如果重叠被指定为一个单独的数据点(就像在模式“full”中的情况),则结果将给出长度为5的数组。第一步是:
[3 4]
  [1 1 5 5]
= 3 * undefined (extrapolated as 0) + 4 * 1 = 4

等等。还有更多的外推模式存在。


10
为了澄清一下:在所解释的卷积中,向量[2 3]被镜像为[3 2]。这是正确的。如果该向量没有被镜像,那么该操作将被称为交叉相关。这是由于卷积的数学定义所决定的。 - Soravux
卷积中的同一模式怎么样? - Heberto Mayorquin
3
@RamonMartinez 这种模式在numpy文档中有详细描述。基本上,它的运行方式与此处所解释的“full”模式相同,但结果将被截断(左右两端一样),以使其长度等于最长的输入信号长度。 - Soravux
3
不确定为什么这个答案还没有被接受为正确答案。 - godimedia
6
例子中的第一个参数是 [4,3] 而不是 [3,4],根据数学定义,卷积会反转第一个参数。 - Soravux
显示剩余3条评论

6
值得注意的是,卷积核在索引数组时是“居中”的,也就是说, 与数组中心元素相关的索引会被采用。换句话说,对于从0开始索引的数组(如Python中),函数B = np.convolve(A,K)计算的结果为: B[k] = \sum_i A[i]   K[k - i + m] 其中m = (len(K) - 1)//2 (整数除法),这是一个整数,即使len(K)为偶数时也一样。
该总和名义上涵盖了所有值i从-∞到∞,超出范围的A值假定为零。 卷积核的值也是同样处理。对于np.convolution2D,您可以使用mode、boundary和fillvalue选项指定如何处理超出范围的A值。
因此,例如,如果 K = np.array([1, 2, 3])K = np.array([1, 2, 3, 0, 0]),则np.convolve(A, K)将得到不同的答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接