关于python:矩阵和向量的卷积,即不同维度的输入

Convolution of a matrix and a vector i.e. inputs of different dimensions

这是此问题的后续问题:

我确实有要转换为包含conv2的Python的Matlab代码。 我可以模仿它在Python中的行为:

1
2
3
4
5
import numpy as np
from scipy import signal

def conv2(x, y, mode='same'):
    return np.rot90(signal.convolve2d(np.rot90(x, 2), np.rot90(y, 2), mode=mode), 2)

如果我再打电话

1
2
3
4
5
f = [[2, 3, 4], [1, 6, 7]]
g = [[9, 1, 0], [2, 5, 8], [1, 3, 3]]

print conv2(f, g)
print conv2(g, f)

它给我的输出与Matlab的输出相同

1
2
conv2([[2,3,4];[1,6,7]], [[9,1,0];[2,5,8];[1,3,3]], 'same')
conv2([[9,1,0];[2,5,8];[1,3,3]], [[2,3,4];[1,6,7]], 'same')

但是,当一个参数是向量时,Matlab的conv2也可以工作。 例如,

1
conv2([[2,3,4];[1,6,7]], [9,1,0]', 'same')

给出:

1
2
   11   57   67
    1    6    7

我无法在Python中获得此输出,因为标准函数通常需要相同的输入尺寸。 例如:

1
signal.convolve(f, [9, 1, 0])

产量

ValueError: in1 and in2 should have the same dimensionality

1
signal.convolve2d(f, [9, 1, 0])

ValueError: object of too small depth for desired array

如何为不同尺寸的输入获得相同的输出?


只需将一维数组变成二维数组即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
In [71]: f = np.array([[2, 3, 4], [1, 6, 7]])
    ...: g = np.array([[9, 1, 0], [2, 5, 8], [1, 3, 3]])
In [72]: h = np.array([9,1,0])
In [73]: conv2(f,g)
Out[73]:
array([[ 71, 108,  51],
       [ 26,  71, 104]])
In [74]: conv2(f, h[:,None])
Out[74]:
array([[11, 57, 67],
       [ 1,  6,  7]])
In [75]: h[:,None]
Out[75]:
array([[9],
       [1],
       [0]])

在八度中,您的[9,1,0]'是列矩阵:

1
2
3
4
5
6
7
8
9
10
>> conv2([[2,3,4];[1,6,7]], [9,1,0]', 'same')
ans =
   11   57   67
    1    6    7

>> [9,1,0]'

ans =
   9
   1
   0

在MATLAB中,所有内容均为2d(或更高)。 numpy允许一维数组。

应用于hnp.rot90与从[[9,1,0]]创建为2d数组的h[None,:]h相同:

1
2
In [76]: np.rot90(h[:,None])
Out[76]: array([[9, 1, 0]])

在octave / matlab中,您可以通过在开始时制作列矩阵来跳过转置:

1
conv2([[2,3,4];[1,6,7]], [9;1;0], 'same')

numpy等效项是:

1
conv2(f,[[9],[1],[0]])


似乎最简单的解决方案就是使用例如 numpy.expand_dims,然后传递二维输入。 对于上面的示例,它将是:

1
2
g2 = np.array([9, 1, 0])
g2 = np.expand_dims(g2, 0)

然后

1
conv2(f, g2.transpose())

给我

1
2
array([[11, 57, 67],
       [ 1,  6,  7]])

与Matlab输出相同。