numpy中的dot-matmul-@-multiply-*

真的是要自己认认真真写个模型才会发现 好多小坑

np.dot、np.matmul、@、*、np.multiply

变量定义:

1
2
3
4
5
6
7
8
9
10
# 一维
a = np.arange(10)
a
b = np.arange(10,20)
b
# 二维
c = np.arange(9).reshape(3,3)
c
d = np.arange(9).reshape(3,3)
d

Out:

1
2
3
4
5
6
7
8
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])

一维的话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 与标量相乘
np.dot(a,3)

# 报错
#np.matmul(a,3)
#a@3

np.multiply(a,3)
a*3

out:
array([ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27])
array([ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27])
array([ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 一维是
# 相当于求解点积,内积
np.dot(a,b)
np.matmul(a,b)
a@b

# 相当于点乘,相应位置相乘
np.multiply(a,b)
a*b

out:
735
735
735
array([ 0, 11, 24, 39, 56, 75, 96, 119, 144, 171])
array([ 0, 11, 24, 39, 56, 75, 96, 119, 144, 171])

二维的话:

变量:

1
2
3
4
5
6
7
8
9
# 二维
# 叉乘,要求前者的列与后者的行相等
np.dot(c,d)
np.matmul(c,d)
c@d

# 点乘,要求维度完全相同
np.multiply(c,d)
c*d

Out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
array([[ 15,  18,  21],
[ 42, 54, 66],
[ 69, 90, 111]])
array([[ 15, 18, 21],
[ 42, 54, 66],
[ 69, 90, 111]])
array([[ 15, 18, 21],
[ 42, 54, 66],
[ 69, 90, 111]])
array([[ 0, 1, 4],
[ 9, 16, 25],
[36, 49, 64]])
array([[ 0, 1, 4],
[ 9, 16, 25],
[36, 49, 64]])

总结一下:

np.multiply与*等价,都是点乘

np.dot与@与np.matmul基本等价,但是只有np.dot可以用于矩阵与标量相乘,然后一维时是求内积,二维时是叉乘,两个参与运算的矩阵需要满足矩阵乘法的规则,但是官方更推荐使用np.matmul()和@用于矩阵乘法。

有博主这么说,倒也没毛病

当进行向量的内积运算时,可以通过np.dot()
当进行矩阵的乘法运算时,可以通过np.matmul()或者@
当进行标量的乘法运算时,可以通过np.multiply()或者*

np.dot()、np.multiply()、np.matmul()方法以及*和@运算符的用法总结):

权重与变量相乘:

1
2
3
4
5
6
a = np.arange(10)
a
b = np.arange(30).reshape(3,10)
b
a*b
np.multiply(a,b)

Out:

1
2
3
4
5
6
array([[  0,   1,   4,   9,  16,  25,  36,  49,  64,  81],
[ 0, 11, 24, 39, 56, 75, 96, 119, 144, 171],
[ 0, 21, 44, 69, 96, 125, 156, 189, 224, 261]])
array([[ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81],
[ 0, 11, 24, 39, 56, 75, 96, 119, 144, 171],
[ 0, 21, 44, 69, 96, 125, 156, 189, 224, 261]])

比较神奇的是,就是比如data 是3×10的,然后权重是1×10的,但是没关系,会自动得到1×3…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a = np.zeros((10,)) 
a.shape
a

(10,)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

b = np.ones((3,10))
b.shape
b

(3, 10)
array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])

(b@a)
array([0., 0., 0.])
0%