当矩阵a为二维矩阵而b为​​三维矩阵时,如何理解matmul函数?

时间:2018-11-04 10:21:02

标签: python numpy

a=np.arange(8).reshape(2,2,2)
b=np.arange(4).reshape(2,2)
print(np.matmul(a,b))

结果是: [[[2 3]   [6 11]]

[[10 19]   [14 27]] 如何理解结果?怎么来的

2 个答案:

答案 0 :(得分:1)

简短答案:它将第二个2d矩阵“广播”到3d矩阵,然后执行“映射”,因此,它将元素级子矩阵映射到结果中的新子矩阵。

正如documentation on np.matmul [numpy-doc]所说:

  

numpy.matmul(a, b, out=None)

     

两个数组的矩阵乘积。

     

行为通过以下方式取决于参数。

     
      
  1. 如果两个参数都是二维的,它们将像常规矩阵一样相乘。
  2.   
  3. 如果任意一个参数均为N-D,N> 2 ,则将其视为驻留在最后两个索引中的矩阵堆栈,并进行广播   相应地。
  4.   
  5. 如果第一个参数是1-D,则通过在其尺寸前面加1来将其提升为矩阵。矩阵相乘后   前面的1被删除。
  6.   
  7. 如果第二个自变量是1-D,则通过在其尺寸后附加1来将其提升为矩阵。矩阵相乘后   附加的1已删除。
  8.   

因此,此处第二项适用。因此,首先,第二个矩阵也被“广播”到3d变体,这意味着我们乘以:

array([[[0, 1],
        [2, 3]],

       [[4, 5],
        [6, 7]]])

具有:

array([[[0, 1],
        [2, 3]],

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

,我们将它们视为堆叠矩阵。所以首先我们乘以:

array([[0, 1],      array([[0, 1],
       [2, 3]])  x        [2, 3]])

这给了我们

array([[ 2,  3],
       [ 6, 11]])

,然后是元素第二子矩阵:

array([[4, 5],      array([[0, 1],
       [6, 7]])  x        [2, 3]])

这给了我们

array([[10, 19],
       [14, 27]])

因此,我们将它们堆叠到结果中,并获得:

>>> np.matmul(a, b)
array([[[ 2,  3],
        [ 6, 11]],

       [[10, 19],
        [14, 27]]])

尽管这样可以完美地定义行为,但是最好谨慎使用此功能,因为对于具有2d矩阵的3d矩阵,“矩阵乘积”的外观还有其他“感性”定义,因此在这里不使用。

答案 1 :(得分:1)

您可以更明确地将乘法视为求和。因此,如果a的尺寸为(i, j, k),而b的尺寸为(k, l),则结果的尺寸将为(i, j, l)

enter image description here

在代码中,可以这样写(非常明确):

def matmul(a, b):
  dim1, dim2, dim3 = a.shape
  dim4 = b.shape[1]
  c = np.zeros(shape=(dim1, dim2, dim4))
  for i in range(dim1):
    for j in range(dim2):
      for l in range(dim4):
        c[i, j, l] = sum(a[i, j, k] * b[k, l] for k in range(dim3))
  return c

如果您尝试从此matmul()函数中打印出结果,它将与numpy函数相同。

注意:该功能效率很低,并且仅在a具有3个维而b具有2个维时才可以使用,但是可以很容易地将其推广。