numpy当中常用的矩阵乘法有两种,numpy.dot和numpy.matmul
当对象是2D矩阵的时候,这两个函数都是进行最正常的矩阵乘法
import numpy as np
a = np.array( [ [ 1,2 ], [ 3,4 ] ] )
b = np.array( [ [ 1,2 ], [ 3,4 ] ] )
c = np.matmul( a,b )
d = np.dot(a,b)
print c
print d
结果是一样的
也就是常说的elementwise,需要两个矩阵的大小一样(如果不考虑broadcast的话),multiply函数将两个矩阵相同位置的元素分别相乘,或者直接使用*
import numpy as np
a = np.array( [ [ 1,2 ], [ 3,4 ] ] )
b = np.array( [ [ 1,2 ], [ 3,4 ] ] )
c = np.multiply( a,b )
d = a * b
print c
print d
如果两个矩阵(或者一个矩阵和一个标量)大小是不符合要求的话(比如大小不一样或者行和列的个数不满足要求),是不能进行运算的。但是在一定的规则下,numpy可以帮你进行broadcast。虽然我一开始对这种特性不以为然,但是后来发现,它对写vectorized的代码是非常有帮助的,而且往往计算效率会更高(因为所谓broadcast只是概念上的,真正运算的时候不会真占用那么多的空间)
当我们说一个标量或者向量要进行broadcast的时候,一定是指进行elementwise的操作,不会进行像矩阵乘法这样的操作
broadcast的原则是这样的,我们设两个向量A,B
A是一个 q * e * t的向量
B是一个 u * y * l的向量
那么这两个向量进行运算的时候
1. 要么某个维度上大小相等,比如q==u
2. 要么其中一个等于1
当等于1的时候,就会在那个方向上进行broadcast
import numpy as np
a = np.array( [ [ 1,2 ], [ 3,4 ] ] )
b = np.array( [ [ 1,2 ], [ 3,4 ] ] )
c = 3.0
d = 2.0
rst = a + c
rst1 = b * d
print rst
print rst1
在这个例子当中a是2 * 2的,c和d是1 * 1的,那么c就会在两个维度上broadcast,然后elementwise进行相加
import numpy as np
a = np.array( [ [ 1,2 ], [ 3,4 ], [5,6] ] )
b = np.array( [ [2], [1], [3] ] )
print b.shape
rst = a + b
print rst
在这个例子里面,a是3 * 2的, b是3 * 1的,那么b就会在axis=1这个维度上进行broadcast,然后相加
我们通常用到的例子还有,对于一个100 * 100 * 3的像素,如果要分别对rgb通道分别乘以一个scale的值,只需要对整张图片乘以一个 (3,)的向量,numpy就会自动处理成对每个点的三个通道分别操作
import numpy as np
a = np.array( [ [[ 1,2,3 ], [ 3,4,5 ], [5,6,7] ],
[[1, 2, 3], [3, 4, 5], [5, 6, 7]],
[[1, 2, 3], [3, 4, 5], [5, 6, 7]],
[[1, 2, 3], [3, 4, 5], [5, 6, 7]]] )
b = np.array( [1,2,3] )
rst = a * b
print rst