参考自numpy帮助文档
numpy.matmul
原型: numpy.matmul(a, b, out=None)
两个numpy数组的矩阵相乘
(1). 如果两个参数
a
,
b
a,b
a,b都是
2
2
2维的,做普通的矩阵相乘。
import numpy as np
a = [[1, 0], [0, 1]]
b = [[4, 1], [2, 2]]
np.matmul(a, b)
array([[4, 1],
[2, 2]])
(2). 如果某一个参数是 N ( N > 2 ) N(N>2) N(N>2)维的,该参数被理解为一些矩阵(参数的最后两个维数为矩阵维数)的stack,而且计算时会相应的广播
a = np.arange(2*2*4).reshape((2,2,4))
b = np.arange(2*2*4).reshape((2,4,2))
c = np.arange(1*2*4).reshape((1,4,2))
np.matmul(a,b)
np.matmul(a,c)
out:
[[[ 28 34]
[ 76 98]]
[[428 466]
[604 658]]]
[[[ 28 34]
[ 76 98]]
[[124 162]
[172 226]]]
首先,对于 a a a,它会被理解成两个 2 × 4 2\times4 2×4的矩阵的stack
[[[ 0 1 2 3]
[ 4 5 6 7]]
[[ 8 9 10 11]
[12 13 14 15]]]
同样对于 b b b,它会被理解成两个 4 × 2 4\times2 4×2的矩阵的stack
[[[ 0 1]
[ 2 3]
[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]
[12 13]
[14 15]]]
- 那么
np.matmul(a,b)
则会将 a a a的第一个矩阵和 b b b的第一个矩阵相乘,将 a a a的第二个矩阵 b b b的第二个矩阵相乘,最终得到一个 2 × 2 × 2 2\times2\times2 2×2×2的结果 - 同理,同样对于
c
c
c,它会被理解成一个
4
×
2
4\times2
4×2的矩阵的stack,对于
np.matmul(a,c)
,则会广播 c c c的一个矩阵,将 a a a的第一个矩阵和第二个矩阵分别与 c c c的一个矩阵相乘最终得到一个 2 × 2 × 2 2\times2\times2 2×2×2的结果
(3). 如果第一个参数或者第二个参数是 1 1 1维的,它会提升该参数为矩阵(根据另一个参数维数,给该参数增加一个为1的维数)。矩阵相乘之后会将为1的维数去掉。
import numpy as np
a = [[1, 0], [0, 1]]
b = [1, 2]
np.matmul(a, b)
np.matmul(b, a)
array([1, 2])
array([1, 2])
上述两种情况在计算矩阵相乘时,会分别将
b
b
b提升为
2
×
1
2\times1
2×1的矩阵和
1
×
2
1\times2
1×2的矩阵。
(4). 乘一个标量是不被允许的,用
∗
*
∗代替。
np.matmul([1,2], 3)
ValueError: Scalar operands are not allowed, use '*' instead
matmul
与dot
的差异主要在两个方面:
(1)不允许乘标量
(2)stack的矩阵将矩阵按元素对待被一起广播