简体   繁体   English

2d 与 3d 之间的矩阵乘法?

[英]Matrix multiplication between 2d with 3d?

Here is the two matrixs:这是两个矩阵:
a's shape is (2, 2) and b's shape is (2, 2, 3) a的形状是(2, 2),b的形状是(2, 2, 3)
I want to get c whose shape is (2, 3)我想得到形状为 (2, 3) 的 c

How can I get c using a and b?如何使用 a 和 b 得到 c?


a = array([[0.5, 0.5],
           [0.6, 0.4]])

b = array([[[1, 2, 1],
            [1, 3, 1]],

           [[2, 1, 2],
            [3, 1, 3]]])

c = array([[1. , 2.5, 1. ],
           [2.4 , 1.2, 2.4 ]])

# c = [[0.5*1+0.5*1, 0.5*2+0.5*3, 0.5*1+0.5*1],
       [0.6*2+0.4*3, 0.6*1+0.4*1, 0.6*2+0.4*3]]

# [0.5, 0.5] * [[1, 2, 1],
                [1, 3, 1]]
# [0.6, 0.4] * [[2, 1, 2],
                [3, 1, 3]]

Using einsum使用 einsum

Try np.einsum ( documentation ).尝试np.einsum文档)。 If you want to know more about how np.einsum works, then check this old answer of mine which breaks down how its working -如果您想了解更多关于np.einsum工作原理,请查看我的这个旧答案,它分解了它的工作原理 -

np.einsum('ij,ijk->ik',a,b)

array([[1. , 2.5, 1. ],
       [2.4, 1. , 2.4]])

Using broadcasting使用广播

The einsum above is equivalent to the following multiply->reduce->transpose上面的einsum相当于下面的multiply->reduce->transpose

Note: a[:,:,None] adds an additional axis to matrix a such that (2,2) -> (2,2,1).注意: a[:,:,None]向矩阵a添加一个附加轴,使得 (2,2) -> (2,2,1)。 This allows it to be broadcasted in operations with b which is of the shape (2,2,3).这允许它在具有形状 (2,2,3) 的b的操作中被广播。

(a[:,:,None]*b).sum(1)

array([[1. , 2.5, 1. ],
       [2.4, 1. , 2.4]])

Using Tensordot使用 Tensordot

Check out tensordot documentation here 在此处查看 tensordot 文档

np.tensordot(a,b, axes=[1,1]).diagonal().T

array([[1. , 2.5, 1. ],
       [2.4, 1. , 2.4]])

The relatively new matmul is designed to handle 'batch' operations like this.相对较新的matmul旨在处理这样的“批处理”操作。 The first of 3 dimensions is the batch dimension, so we have to adjust a to be 3d. 3 个维度中的第一个是批量维度,因此我们必须将a调整为 3d。

In [156]: a = np.array([[0.5, 0.5],
     ...:            [0.6, 0.4]])
     ...: 
     ...: b = np.array([[[1, 2, 1],
     ...:             [1, 3, 1]],
     ...: 
     ...:            [[2, 1, 2],
     ...:             [3, 1, 3]]])
In [157]: (a[:,None]@b)[:,0]
Out[157]: 
array([[1. , 2.5, 1. ],
       [2.4, 1. , 2.4]])

In einsum terms this is在 einsum 术语中,这是

np.einsum('ilj,ijk->ik',a[:,None],b)

with the added l dimension (which is later removed from the result)添加了l维(稍后从结果中删除)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM