将不同维度的矩阵相乘

时间:2016-12-14 03:28:30

标签: python numpy matrix

我有两个不同维度的矩阵,我想用einsum numpy繁殖: C(24,79)和D(1,1,24,1)。我想获得具有维度(1,1,79,1)的矩阵。

我试图以两种方式将它们相乘:

tmp = np.einsum('px, klpj ->klxj', C, D)

tmp = np.einsum('xp, klpj ->klxj', C, D)

我获得了不同的结果。为什么?将这些矩阵相乘的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

由于单个维度不会真正导致sum-reduction,我们可以使用np.tensordotnp.dot引入矩阵乘法,以便有两种方法来解决它 -

np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2)

D.ravel().dot(C).reshape(1,1,C.shape[1],1)

验证结果 -

In [26]: tmp = np.einsum('px, klpj ->klxj', C, D)

In [27]: out = np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2) 

In [28]: np.allclose(out, tmp)
Out[28]: True

In [29]: out = D.ravel().dot(C).reshape(1,1,C.shape[1],1)

In [30]: np.allclose(out, tmp)
Out[30]: True

运行时测试 -

In [31]: %timeit np.einsum('px, klpj ->klxj', C, D)
100000 loops, best of 3: 5.84 µs per loop

In [32]: %timeit np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2)
100000 loops, best of 3: 18.5 µs per loop

In [33]: %timeit D.ravel().dot(C).reshape(1,1,C.shape[1],1)
100000 loops, best of 3: 3.29 µs per loop

使用更大的数据集,您会看到矩阵乘法的明显好处 -

In [36]: C = np.random.rand(240,790)
    ...: D = np.random.rand(1,1,240,1)
    ...: 

In [37]: %timeit np.einsum('px, klpj ->klxj', C, D)
    ...: %timeit np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2)
    ...: %timeit D.ravel().dot(C).reshape(1,1,C.shape[1],1)
    ...: 
1000 loops, best of 3: 182 µs per loop
10000 loops, best of 3: 84.9 µs per loop
10000 loops, best of 3: 55.5 µs per loop