【问题标题】:Convolution of a matrix and a vector i.e. inputs of different dimensions矩阵和向量的卷积,即不同维度的输入
【发布时间】:2017-09-28 05:09:36
【问题描述】:

那是this one的后续问题:

我确实有想要转换为 Python 的 Matlab 代码,其中包括 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 和 in2 应该具有相同的维度

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

ValueError:所需数组的深度太小

如何为不同维度的输入实现相同的输出?

【问题讨论】:

  • MATLAB 没有“向量”,至少在 numpy 的一维数组的意义上没有。 MATLAB 中的最小维度是 2d,因此它始终适用于矩阵。这是在比较 MATLAB 和 numpy 代码时需要牢记的根本区别。但是您可以使用[:,np.newaxis]reshape 在numpy 中轻松添加维度。

标签: python matlab scipy convolution code-conversion


【解决方案1】:

只需将 1d 数组转换为 2d 数组即可。

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 中,一切都是 2d(或更高)。 numpy 允许一维数组。

应用于hnp.rot90h[None,:]h[[9,1,0]] 创建为二维数组相同:

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]])

【讨论】:

  • 是的,添加一个额外的维度也是我使用np.expand_dims 的结果(见我的回答)。感谢您的详细解释(赞成并接受)。
【解决方案2】:

似乎最简单的解决方案就是使用例如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 输出相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 2017-07-03
    • 1970-01-01
    • 2013-05-23
    相关资源
    最近更新 更多