首页 > 技术文章 > Numpy广播与matmul()

Allen-mat 2020-08-28 00:57 原文

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。

对于加减运算和矩阵乘法,广播法则略有不同?td

广播在加减运算上的应用

广播原则:如果两个数组的后缘维度(即:从末尾开始算起的维度)的轴长相符或其中一方的长度为1,则认为它们是广播兼容的,广播会在缺失和(或)长度为1的轴上进行。

举几个例子:

例1:数组(array)与标量数字(scalar)的广播

image-20200828003521196

例2:2个不同形状的数组

image-20200828003557987

这里a的shape是(4,3),b的shape是(3),因为b是一个3D向量。触发广播,由于两个数组的最后一个维度的轴长相符,都是3。因此,广播会在缺失的轴上进行,将b的shape补成和a一样的(4,3)。

下面的图片展示了数组 b 如何通过广播来与数组 a 兼容。

截屏2020-08-28 上午12.19.01

实际上,4x3 的二维数组与长为 3 的一维数组相加,等效于把数组 b 在二维上重复 4 次再运算。

例3:三维数组的广播

截屏2020-08-28 上午12.21.04

根据广播原则分析:arr1的shape为(3,4,2),arr2的shape为(4,2),它们的后缘轴长度都为(4,2),所以可以在0轴进行广播,arr2的shape变为(3,4,2)。

matmul()及广播在matmul()中的应用

numpy.matmul 函数返回两个数组的矩阵乘积。

1.当两个数组都是一维数组(向量)的时候,就是向量的内积。

image-20200828004323759

2.当两个数组都是二维数组的时候,就是数学上的两个矩阵的乘积。

image-20200828004443282

3.矩阵与向量的矩阵乘法(或者说2D张量与1D张量(即nD向量)的matmul)

如果第一个参数(a或b)或者第二个参数是1 维的(不要理解成轴长是1了),它会提升该参数为矩阵(根据另一个参数的维数(也就是轴数),给该参数增加一个轴长为1的轴,使得矩阵乘法成立。)。矩阵相乘之后会将为轴长为1的轴去掉。

image-20200828004558389

上面这两种情况,会分别将b提升为(2x1)的矩阵和(1x2)的矩阵。

应用:pytorch构建CNN网络时,Linear layer(线性层)的实现本质上就是weight_matrix与一维的input_feature作matmul,得到out_feature。这点可以在nn.Linear模块源代码看到。

image-20200828082827210

4.如果某一个array是N(N>2) )维的,则被理解为一些矩阵(参数的最后两个维数为矩阵维数)的stack,而且计算时会相应的广播。

注:stack操作,也可以形象的理解为一些矩阵「叠加」在一起。

image-20200828004825179

a多维的数组,它就会被理解成两个(2x4)矩阵。(不太理解的话,可以参考上面「三维数组」的广播的图。)

b多维的数组,它就会被理解成两个(4x2)矩阵。

c多维的数组,它就会被理解成一个(4x2)矩阵

那么np.matmul(a,b)则会将a的第一个矩阵和b的第一个矩阵相乘,将a的第二个矩阵b 的第二个矩阵相乘,最终得到一个2×2×2 的结果。

np.matmul(a,c)的情况,由于c只有一个矩阵,所以它会广播出一个相同的矩阵c,分别与a的第一、第二个矩阵相乘。

参考:https://www.runoob.com/numpy/numpy-broadcast.html
https://www.cnblogs.com/yangmang/p/7125458.html
https://blog.csdn.net/yu_1628060739/article/details/102720385

推荐阅读