Python中的数学运算

一、加减乘除运算

  1. 张量(数组)之间的+、-、*、/,在python支持自动Broadcast机制。不过不是所有的张量之间都支持,需要进行普适性判断
    Broadcasting普适性判断:
    首先将两个shape靠右对齐,
    对于长度为1的维度,默认这个数据普遍适合于当前维度的其他位置;
    对于不存在的维度,则在增加新维度后默认当前数据也是普适于新维度的,从而可以扩展为更多维度数、任意长度的张量形状。
    若对齐之后shape对应维度的值都大于1且不相等,则不满足。例如:
a.shape:(2,32,32,4),b.shape:(2,1,32,4),c.shape:(2,32,4),d.shape:(2,32,32,2)
a*b满足普适性 b会自动扩展为(2,32,32,4)
a*c不满足普适性
a*d不满足普适性
  1. 张量之间的加减乘除运算要求张量维度一样或者满足普适性原则(自动扩展后维度一样)
  2. 张量之间的加减乘除运算都是逐元素的,满足交换律
import numpu as np   
a = np.array([1,2,3]) 
b = np.array([2,2,3])
a*b:array([2, 4, 9])
b*a:array([2, 4, 9])
  1. 可以通过np.sum和运算符*实现向量投影
a = np.array([1,2,3]) 
b = np.array([2,2,3])
c = np.sum(a*b,0)/np.linalg.norm(b) # 向量a在向量b上的投影
  1. 可以通过np.sum和运算符*实现类似np.dot的效果,例如将多组向量批量旋转到世界坐标系
# dirs 是相机坐标系的多组向量构成的,dirs.shape:(1024,1024,3),即1024*1024组方向向量
# c2w 是由相机坐标系变换到世界坐标系的矩阵(视图矩阵的逆矩阵)
# c2w[:3, :3] 是视图矩阵中旋转矩阵的转置
world_dirs = np.sum(dirs[..., np.newaxis, :] * c2w[:3, :3], -1)
# 以上代码实现效果类似于c2w@dirs,但由于dirs.shape是(1024,1024,3),虽然意义上是1024*1024组方向向量
# 但实际存储是将dirs作为多维数组
# 所以c2w@dirs(属于下面⑤):(3,3)X(1024,1024,3)不满足普适性,不能用矩阵乘法

二、矩阵相乘运算

  1. 方式:可以通过@运算符;可以通过np.dot;可以通过tf.mutmul函数
  2. 通过上述方式进行运算时,若两个张量均是二维矩阵则即是普通的矩阵乘法,而其他类型有所不同,具体如下:
    np.dot(a,b)
    ①如果a、b均是1维数组,则为向量内积
    ②如果a、b均是2维数组,则均为矩阵乘法
    ③如果a或b是标量,则与上述运算符*相同
    ④如果a是N(>=2)维数组,b是1维数组,进行运算时,会首先将后面一项进行自动转置操作并将1维数组自动转换为矩阵,之后再进行矩阵乘法运算,最后结果还原成N阶向量
    注意不满足交换律,np.dot(a,b)和np.dot(b,a)结果都是N阶向量,但向量元素值不一样
    注意,在numpy中,若b.shape:(3,1)则代表b是一维矩阵,与向量不同,若此时a@b则属于第二类,是矩阵乘法,结果为(N,1)的矩阵
    ⑤如果a是N(N>2)维数组,b是M(M>=2)维数组,则采用批量方式,选择a和b的最后两个维度进行矩阵相乘,前面所有的维度都视作Batch维度。
    根据矩阵相乘的定义,𝑨和𝑩能够矩阵相乘的条件是:
    a的倒数第一个维度长度(列)和b的倒数第二个维度长度(行)必须相等
    示例:
import numpy as np
 
x = np.array([[1, 2, 3],
   			  [3, 4, 4],
   			  [0, 1, 1]])
y = np.array([1, 2, 3])
# x.shape:(3,3);y.shape:(1,3) => (3,1);矩阵乘法:(3,3)X(3,1) => (3,1) = >(3,)
result1 = np.dot(x, y) # 1×1 + 2×2 + 3×3 = 14(result1的第一个元素)
# x.shape:(3,3);y.shape:(1,3);矩阵乘法:(1,3)X(3,3) => (1,3) = >(3,)
result2 = np.dot(y, x) # 1×1 + 2×3 + 3×0 = 7 (result2的第一个元素)

a = np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])
b = np.array([[1,2],[3,4]])
# a.shape:(3,2,2);b.shape:(2,2);矩阵乘法:(2,2)X(2,2) => (2,2)
# result.shape:(3,2,2)
result3 = np.dot(a,b) # a的一个batch为[[1,2],[3,4]]
  1. 矩阵相乘同样自动支持Broadcast机制,但是普适性判断有点不同,两个shape的最后两个维度只需满足矩阵相乘的条件即可,而其他维度规则不变。

PS:建议不要将运算和点乘、叉乘的名称对应起来,向量的点乘、叉乘和矩阵的点乘、叉乘不一样,很绕。。。

参考

[1]np.dot()函数的用法详解
[2]向量和矩阵的点乘和叉乘
[3]Python 矩阵与矩阵以及矩阵与向量的乘法
[4]Tensorflow深度学习

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值