张量数值运算
张量基本运算
- PyTorch 里张量(Tensor)的加减乘除、取负运算
- 核心区分:
不带下划线 = 返回新张量,不改动原张量;带下划线_= 原地运算,直接修改原张量
add():不修改原数据,返回新张量
- add_() 原地加法!直接修改原张量 data
- sub / mul / div / neg
每个元素减100
每个元素*100,生成新张量
每个元素*100,生成新张量
每个元素取相反数,生成新tensor
重点
- 后缀下划线
_= in-place 原地操作,直接修改调用这个方法的张量,没有返回新张量;- 不带下划线的版本,原张量保持不变,返回计算后的新张量;
- 支持张量和标量运算,也支持同形状张量之间两两元素运算
(不是矩阵乘法!矩阵乘法是@/torch.matmul);- 写法等价:
a.add(b)⇔a + b;a.add_(b)⇔a += b按元素相乘运算
哈达玛积
哈达玛积(Hadamard Product,按元素相乘)
(1)哈达玛积不是矩阵乘法!要求两个张量形状完全相同,对应位置元素直接相乘
区分重点:
*/torch.mul:哈达玛积,逐元素相乘
@/torch.matmul:标准矩阵乘法
data1=torch.tensor([[1,2],[3,4]]) data2=torch.tensor([[5,6],[7,8]])方式1
#方式1:torch.mul() data3=torch.mul(data1,data2) print(data3)方式2 : 直接用 * 运算符
data4=data1*data2 print(data4)
矩阵乘法运算
- PyTorch 矩阵乘法
@/torch.matmul
区别于逐元素相乘 *,这个是数学上的矩阵乘法
二维矩阵
A=torch.randn(3,4) B=torch.randn(4,5) C=A@B # 等价于 torch.matmul (A,B) print(C.shape) # torch.Size([3, 5])高维张量
batch 矩阵乘法,深度学习最常用
规则:只看最后两个维度做矩阵相乘,前面的维度是 batch 维度,支持广播
容易混淆的点
(1)torch.matmul/@:矩阵乘法,遵循上面这套规则
(2)*/torch.mul:逐元素相乘 ,要求两个张量 shape 完全一样
(3)torch.mm:仅限二维矩阵 ,不支持高维 batch,高维用matmul总结
(1)二维:A 列 = B 行;
(2)高维:最后一维 A 的末尾 = B 倒数第二维,前面 batch 维度广播。
# data1 shape:(3,2) 3行2列 data1=torch.tensor([[1,2],[3,4],[5,6]]) # data2 shape:(2,2) 2行2列 data2=torch.tensor([[5,6],[7,8]]) # 方式1:@ 运算符,矩阵乘法 data3=data1@data2 print("data3: ",data3) # data3: tensor([[19, 22], # [43, 50], # [67, 78]]) # 方式2:torch.matmul,和 @ 完全等价 data4=torch.matmul(data1,data2) print("data4: ",data4) # data4: tensor([[19, 22], # [43, 50], # [67, 78]])核心规则:
矩阵乘法,用第一个矩阵的行,点乘第二个矩阵的列,得到结果对应位置的值
张量运算函数
常见运算函数
聚合类函数(sum /mean/max /min)
dim 小口诀:dim=0 压缩行(纵向),dim=1 压缩列(横向)
幂、平方根
注意:负数开根号会得到 nan,0 开根号是 0
指数 对数
重点坑:对数的输入不能小于等于 0,0 会输出 -inf,负数会得到 nan
总结
(1)sum/mean/max/min:聚合运算 ,可以指定维度 dim,压缩张量;
(2)pow/sqrt/exp/log/log2/log10:逐元素运算 ,张量每个元素单独计算,输出 shape 和输入一致。
注意:mean() 均值运算要求张量类型是 float / double,整型 tensor 不能直接求均值。
代码
均值 mean
data = torch.tensor([[4., 0., 7.], [6., 3., 5.]], dtype=torch.float64) print(data) print("全局均值:",data.mean()) print("按列均值 dim=0:",data.mean(dim=0)) print("按行均值 dim=1: ",data.mean(dim=1))求和 sum
data = torch.tensor([[4., 0., 7.], [6., 3., 5.]], dtype=torch.float64) print(data) # 2. 求和 sum print("全局求和:",data.sum()) print("按列求和 (dim=0): ",data.sum(dim=0)) print("按行求和 (dim=1): ",data.sum(dim=1))平方 pow
data = torch.tensor([[4., 0., 7.], [6., 3., 5.]], dtype=torch.float64) print(data) # 3. 平方 pow print("平方:\n",torch.pow(data,2))平方根 sqrt
data = torch.tensor([[4., 0., 7.], [6., 3., 5.]], dtype=torch.float64) print(data) # 4. 平方根 sqrt print("平方根:\n",data.sqrt())指数 exp
data = torch.tensor([[4., 0., 7.], [6., 3., 5.]], dtype=torch.float64) print(data) # 5. 指数 exp print("e^x: \n",data.exp())对数
data = torch.tensor([[4., 0., 7.], [6., 3., 5.]], dtype=torch.float64) print(data) # 6. 对数 print("ln(x): \n",data.log()) print("log2(x): \n",data.log2()) print("log10(x): \n",data.log10())
张量索引操作
简单行、列索引
data=torch.tensor([ [0,7,6,5,9], [6,8,3,1,0], [6,3,8,7,3], [4,9,5,3,1] ]) print(data) print(data[0]) print(data[:,0])(1)
data[0]:取第 0 行 →tensor([0, 7, 6, 5, 9])(2)
data[:, 0]:
:代表该维度全部选取,所有行,只取第 0 列 →tensor([0, 6, 6, 4])
*























