矩阵和向量的卷积,即不同维度的输入
Convolution of a matrix and a vector i.e. inputs of different dimensions
这是this one的后续问题:
我有 Matlab 代码,我想将其转换为 Python,其中包括 conv2
。我可以在 Python 中模仿它的行为:
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)
如果我再打电话
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 的相同
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
也适用于一个参数是矢量的情况。例如,
conv2([[2,3,4];[1,6,7]], [9,1,0]', 'same')
给出:
11 57 67
1 6 7
不过我无法在 Python 中获得此输出,因为标准函数通常需要相同的输入维度。例如:
signal.convolve(f, [9, 1, 0])
产量
ValueError: in1 and in2 should have the same dimensionality
和
signal.convolve2d(f, [9, 1, 0])
ValueError: object of too small depth for desired array
如何为不同维度的输入实现相同的输出?
似乎最简单的解决方案就是使用例如numpy.expand_dims
然后传递一个二维输入。对于上面的示例,它将是:
g2 = np.array([9, 1, 0])
g2 = np.expand_dims(g2, 0)
然后
conv2(f, g2.transpose())
给我
array([[11, 57, 67],
[ 1, 6, 7]])
这与 Matlab 输出相同。
只需将一维数组转换为二维数组即可。
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]])
在 Octave 中,您的 [9,1,0]'
是一个列矩阵:
>> 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 中,一切都是二维的(或更高)。 numpy
允许一维数组。
应用于 h
的 np.rot90
与从 [[9,1,0]]
:
创建为二维数组的 h[None,:]
或 h
相同
In [76]: np.rot90(h[:,None])
Out[76]: array([[9, 1, 0]])
在 octave/matlab 中,您可以通过在开始处设置列矩阵来跳过转置:
conv2([[2,3,4];[1,6,7]], [9;1;0], 'same')
相当于 numpy 的是:
conv2(f,[[9],[1],[0]])
这是this one的后续问题:
我有 Matlab 代码,我想将其转换为 Python,其中包括 conv2
。我可以在 Python 中模仿它的行为:
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)
如果我再打电话
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 的相同
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
也适用于一个参数是矢量的情况。例如,
conv2([[2,3,4];[1,6,7]], [9,1,0]', 'same')
给出:
11 57 67
1 6 7
不过我无法在 Python 中获得此输出,因为标准函数通常需要相同的输入维度。例如:
signal.convolve(f, [9, 1, 0])
产量
ValueError: in1 and in2 should have the same dimensionality
和
signal.convolve2d(f, [9, 1, 0])
ValueError: object of too small depth for desired array
如何为不同维度的输入实现相同的输出?
似乎最简单的解决方案就是使用例如numpy.expand_dims
然后传递一个二维输入。对于上面的示例,它将是:
g2 = np.array([9, 1, 0])
g2 = np.expand_dims(g2, 0)
然后
conv2(f, g2.transpose())
给我
array([[11, 57, 67],
[ 1, 6, 7]])
这与 Matlab 输出相同。
只需将一维数组转换为二维数组即可。
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]])
在 Octave 中,您的 [9,1,0]'
是一个列矩阵:
>> 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 中,一切都是二维的(或更高)。 numpy
允许一维数组。
h
的 np.rot90
与从 [[9,1,0]]
:
h[None,:]
或 h
相同
In [76]: np.rot90(h[:,None])
Out[76]: array([[9, 1, 0]])
在 octave/matlab 中,您可以通过在开始处设置列矩阵来跳过转置:
conv2([[2,3,4];[1,6,7]], [9;1;0], 'same')
相当于 numpy 的是:
conv2(f,[[9],[1],[0]])