一个简单的一维示例,显示卷积与相关性以测试可交换/关联属性

问题描述

因此,我知道一个事实,即卷积具有交换/关联属性,而关联却没有但从来没有真正写出一个简单的例子来测试这一点。 (在那里存在等式形式的证明)

我只是尝试这个简单的例子:

Image : [1 0 -1 0 1 0 1 1]
A kernel = [-1 0 1]
B kernel = [-1 0 1]

使用卷积,I *(A * B)应该等于(I * A)* B,但是当我尝试这样做时,它们并不相等..这让我很困惑。谁能帮忙?也许我在计算时犯了一个人为错误..但是它们应该是对的吗? (假设边界被视为0)

使用相关性,正如我所理解的那样,它们不应该相等。但是,我的卷积也不是那么大声笑(但应该如此!)

任何帮助将不胜感激。

另外, A * B(卷积)为[0 -2 0]对吗? 和AxB(互相关)是否为[0 2 0]?

解决方法

卷积运算符是可交换的。因此,I*(A*B)应该等于(I*A)*B是正确的。让我们首先将其转换为矩阵形式。内核A的卷积可以通过以下卷积矩阵C转换为乘法:

C=
 [-1  0  1  0  0  0  0  0]
 [ 0 -1  0  1  0  0  0  0]
 [ 0  0 -1  0  1  0  0  0]
 [ 0  0  0 -1  0  1  0  0]
 [ 0  0  0  0 -1  0  1  0]
 [ 0  0  0  0  0 -1  0  1]
 [ 1  0  0  0  0  0 -1  0]
 [ 0  1  0  0  0  0  0 -1]

我们采用了内核[-1 0 1],并在第一行中用5个零对它进行了零填充。然后,下面的每一行是前一行右侧的1个位置的循环移位。 因此,如果我们想用I计算内核A的卷积:

I = [1 0 -1 0 1 0 1 1]

我们只需计算矩阵向量乘法:

C*I^T

(其中I ^ T是转置向量)。

按照上述公式,我们得到:

I*(A*B) = (C*C)*I^T

计算C * C,您将得到以下矩阵:

C^2=
 [ 1  0 -2  0  1  0  0  0]
 [ 0  1  0 -2  0  1  0  0]
 [ 0  0  1  0 -2  0  1  0]
 [ 0  0  0  1  0 -2  0  1]
 [ 1  0  0  0  1  0 -2  0]
 [ 0  1  0  0  0  1  0 -2]
 [-2  0  1  0  0  0  1  0]
 [ 0 -2  0  1  0  0  0  1]

和:

I*(A*B) = (C*C)*I^T = 
 [ 4]
 [ 0]
 [-2]
 [ 1]
 [ 0]
 [-2]
 [-2]
 [ 1]

(I*A)*B在矩阵公式C*(C*I^T)中,根据矩阵关联性,它等于I*(A*B)=(C*C)*I^T

您可以通过运行以下numpy代码来验证此结果:

import numpy as np
C = [[-1,1,0]]
for k in range(7):
    C.append(np.roll(C[0],k+1))
C = np.array(C)
#print(C)
I = np.transpose(np.array([[1,-1,1]]))

print(f'C=\n{C}\n')
print(f'C^2=\n{C@C}\n')

print(f'(C*C)*I=\n{(C@C)@I}\n')
print(f' C*(C*I)=\n{C@(C@I)}\n')

运行以上代码的结果是:

C=
[[-1  0  1  0  0  0  0  0]
 [ 0 -1  0  1  0  0  0  0]
 [ 0  0 -1  0  1  0  0  0]
 [ 0  0  0 -1  0  1  0  0]
 [ 0  0  0  0 -1  0  1  0]
 [ 0  0  0  0  0 -1  0  1]
 [ 1  0  0  0  0  0 -1  0]
 [ 0  1  0  0  0  0  0 -1]]

C^2=
[[ 1  0 -2  0  1  0  0  0]
 [ 0  1  0 -2  0  1  0  0]
 [ 0  0  1  0 -2  0  1  0]
 [ 0  0  0  1  0 -2  0  1]
 [ 1  0  0  0  1  0 -2  0]
 [ 0  1  0  0  0  1  0 -2]
 [-2  0  1  0  0  0  1  0]
 [ 0 -2  0  1  0  0  0  1]]

(C*C)*I=
[[ 4]
 [ 0]
 [-2]
 [ 1]
 [ 0]
 [-2]
 [-2]
 [ 1]]

 C*(C*I)=
[[ 4]
 [ 0]
 [-2]
 [ 1]
 [ 0]
 [-2]
 [-2]
 [ 1]]

所以您可以看到获得了相同的结果。

请注意,A*B不是[0 -2 0]而是[1 0 -2 0 1],因为您采用A = [-1 0 1](将其两边都加2的零填充为零)并在B = [-1 0 1]上将其作为滑动窗口移动,因此首先您将得到:[-1 -1,0 -1 + -1 0,- 1 1 + 0 0 + 1 -1,1 0 + 0 1,1 1] = [1 0 -2 0 1]。宽度为n的2个内核的卷积结果将为长度2 n-1。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...