目录
mean/sum/max/min/argmin/argmax
broadcast广播机制
广播机制跟expand效果一样,但是它是自动扩展,不需要用torch.unsqueeze(index)进行维度增加,能够节省内存,思路如下:
主要思想就是低维度tensor添加一个size=1的维度,然后对所有size=1的维度扩展,其余维度不变。
输入:
a=torch.rand(4,32,14,14)
b=torch.rand(1,32,1,1)
c=torch.rand(32,1,1)
输出:
torch.Size([4, 32, 14, 14])
torch.Size([4, 32, 14, 14])
合并与分割
cat拼接
输入:
# 两个班级a和b,各有32个学生,8门成绩。
a = torch.rand(4, 32, 8)
b = torch.rand(5, 32, 8)
# 按照班级进行合并起来,dim=n表示在n维度进行拼接,即对应维度数值相加
print(torch.cat([a, b], dim=0).shape)
输出:
torch.Size([9, 32, 8])
stack创建新维度
输入:
a1 = torch.rand(4, 3, 32, 32) a2 = torch.rand(4, 3, 32, 32) print(torch.cat([a1, a2], dim=1).shape) print('====================================') print(torch.stack([a1, a2], dim=1).shape) # 各自创建一个新的维度。然后concat a = torch.rand(32, 8) b = torch.rand(32, 8) print(torch.stack([a, b], dim=0).shape)
输出:
torch.Size([4, 6, 32, 32])
====================================
torch.Size([4, 2, 3, 32, 32]) # 各自创建一个新的维度。然后concat
torch.Size([2, 32, 8])
例子:两个班,每个班有32个人,每个人有8门成绩,现在要将两个班成绩合并成一张表,显然不能直接用cat拼接即64个学生,每个学生有8门成绩,应该是有两个班,每个班32名学生,每个学生8门成绩,即[2, 32, 8]
split按长度拆分和chunk按数量拆分
tensor.split(n,dim),n表示拆分后的长度,dim表示要拆分的维度。
输入:
c = torch.rand(3, 32, 8)
aa, bb = c.split([2, 1], dim=0)
print(aa.shape)
print(bb.shape)
print('====================================')
aa, bb = c.split(2, dim=0)
print(aa.shape)
print(bb.shape)
输出:
torch.Size([2, 32, 8])
torch.Size([1, 32, 8])
====================================
torch.Size([2, 32, 8])
torch.Size([1, 32, 8])
tensor.chunk(n,dim),n表示要拆分成几部分,dim表示要拆分的维度。
输入:
c = torch.rand(6, 32, 8)
aa, bb, cc= c.chunk(3, dim=0) # 第1个参数要拆分后的数量
print(aa.shape)
print(bb.shape)
print(cc.shape)
输出:
torch.Size([2, 32, 8])
torch.Size([2, 32, 8])
torch.Size([2, 32, 8])
数学运算
add/sub/mul/div加减乘除
输入:
a = torch.rand(3, 4)
b = torch.rand(4)
print(a)
print(b)
print(a+b)
print(torch.mul(a,b))
print(torch.all(torch.eq(a-b, torch.sub(a, b))))
print(torch.all(torch.eq(a*b, torch.mul(a, b))))
print(torch.all(torch.eq(a/b, torch.div(a, b))))
输出:
tensor([[0.9546, 0.8925, 0.8478, 0.8498],
[0.5096, 0.6845, 0.3661, 0.5274],
[0.4793, 0.2723, 0.4199, 0.0719]])
tensor([0.4801, 0.9741, 0.0383, 0.6885])
tensor([[1.4347, 1.8666, 0.8861, 1.5383],
[0.9898, 1.6585, 0.4044, 1.2159],
[0.9595, 1.2463, 0.4582, 0.7604]])
tensor([[0.4583, 0.8694, 0.0325, 0.5851],
[0.2447, 0.6667, 0.0140, 0.3631],
[0.2302, 0.2652, 0.0161, 0.0495]])
tensor(True)
tensor(True)
tensor(True)
matmul矩阵相乘
注意:torch.mm只适用于2D,一般使用torch.matmul,@符号等同于troch.matmul
输入:
a = torch.tensor([[3., 3.], [3., 3.]])
b = torch.ones(2, 2)
print(torch.mm(a, b))
print(torch.matmul(a, b))
print(a@b)
输出:
tensor([[6., 6.],
[6., 6.]])
tensor([[6., 6.],
[6., 6.]])
tensor([[6., 6.],
[6., 6.]])
对于3D和4D矩阵相乘
输入:
a = torch.rand(4, 3, 28, 64)
b = torch.rand(4, 3, 64, 32)
# 这就是4D的tensor矩阵相乘,这种规则是符合实际规则的。
# 这其实就是支持多个矩阵对并行相乘。
# 只取低的维度(右边)参与运算,就是[28,64]@[64,32]
print(torch.matmul(a, b).shape)
print('================================')
c = torch.rand(4, 1, 64, 32) # 这里使用使用broadcasting机制,把dim的size为1的变为一致。
print(torch.matmul(a, c).shape)
输出:
torch.Size([4, 3, 28, 32])
================================
torch.Size([4, 3, 28, 32])
pow矩阵的次方以及sqrt/rsqrt/exp/log
pow(tensor, 次方)第一个参数为Tensor,第二个参数表示次方,比如2次方,三次方,四次方等等。
输入:
a =torch.full([2, 2], 3) # 使用torch.full函数创建一个shape[2, 2],元素全部为3的张量
print(a.pow(2))
print(torch.pow(a, 2))
print(a**2)
print('=============================')
b = a**2
print(b.sqrt())
print(b.rsqrt()) # 平方根的导数
c = torch.exp(torch.ones(2, 2))
print(c)
print(torch.log(c)) # 默认以e为底,使用2为底或者其他的,自己设置.
输出:
tensor([[9, 9],
[9, 9]])
tensor([[9, 9],
[9, 9]])
tensor([[9, 9],
[9, 9]])
=============================
tensor([[3., 3.],
[3., 3.]])
tensor([[0.3333, 0.3333],
[0.3333, 0.3333]])
tensor([[2.7183, 2.7183],
[2.7183, 2.7183]])
tensor([[1., 1.],
[1., 1.]])
round矩阵近似运算
输入:
a = torch.tensor(3.14)
# .floor()向下取整,.ceil()向上取整,.trunc()截取整数,.frac截取小数。
print(a.floor(), a.ceil(), a.trunc(), a.frac())
print(a.round())
b = torch.tensor(3.5)
print(b.round())
输出:
tensor(3.) tensor(4.) tensor(3.) tensor(0.1400)
tensor(3.)
clamp(裁剪)
a.clamp(min):
表示tensor a中小于10的都赋值为10,表示最小值为10;
输入:
grad = torch.rand(2, 3)*15 print(grad) print(grad.max(), grad.median(), grad.min()) print('============================================') print(grad.clamp(10)) # 最小值限定为10,小于10的都变为10; print(grad.clamp(8, 15)) print(torch.clamp(grad, 8, 15))
输出:
tensor([[ 4.9132, 11.6007, 8.3476],
[11.6155, 2.1120, 4.3543]])
tensor(11.6155) tensor(4.9132) tensor(2.1120)
============================================
tensor([[10.0000, 11.6007, 10.0000],
[11.6155, 10.0000, 10.0000]])
tensor([[ 8.0000, 11.6007, 8.3476],
[11.6155, 8.0000, 8.0000]])
tensor([[ 8.0000, 11.6007, 8.3476],
[11.6155, 8.0000, 8.0000]])
统计属性
norm范数,prod张量元素累乘(阶乘)
输入:
a = torch.full([8], 1)
b = a.view(2, 4)
c = a.view(2, 2, 2)
print(a, '\n', b,'\n', c)
print('=============================================')
print(a.norm(1), b.norm(1), c.norm(1))
print(a.norm(2), b.norm(2), c.norm(2))
print('=============================================')
print(b.norm(1, dim=1))
print(b.norm(2, dim=1))
print('=============================================')
print(c.norm(1, dim=0))
print(c.norm(2, dim=0))
print(torch.norm(c, p=2, dim=0)) # 同一个表达,p=2可以省略,默认就是2
输出:
tensor([1., 1., 1., 1., 1., 1., 1., 1.])
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.]])
tensor([[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]]])
=============================================
tensor(8.) tensor(8.) tensor(8.)
tensor(2.8284) tensor(2.8284) tensor(2.8284)
=============================================
tensor([4., 4.])
tensor([2., 2.])
=============================================
tensor([[2., 2.],
[2., 2.]])
tensor([[1.4142, 1.4142],
[1.4142, 1.4142]])
tensor([[1.4142, 1.4142],
[1.4142, 1.4142]])
mean/sum/max/min/argmin/argmax
输入:
a = torch.rand(2, 4)
print(a)
print(a.max(), a.min(), a.mean())
print(a.prod()) # 最大值,最小值,均值,prod表示累乘也就是阶乘。
print(a.sum()) # 累加操作。
print(a.argmax(), a.argmin())
输出:
tensor([[0.6793, 0.8178, 0.2579, 0.8237],
[0.3547, 0.0144, 0.6213, 0.8617]])
tensor(0.8617) tensor(0.0144) tensor(0.5538)
tensor(0.0003)
tensor(4.4306)
tensor(7) tensor(5)
kthvalue()和topk()
注意:topk(3, dim=1)
(最大的3个)返回结果如下图所示,如果把largest设置为False就是默认最小的几个。kthvalue(k,dim=1)
表示第k小的(默认表示小的)。下面图中的一共10中可能,第8小就是表示第3大。
输入:
a = torch.rand(5, 10)
print(a.topk(3, dim=1)) # 最大的3个元素,和对应的index
print('==========================================================')
print(a.topk(3, dim=1, largest=False)) # 最小的3个元素,和对应的index
print('==========================================================')
print(a.kthvalue(3))
print(a.kthvalue(3,dim=1))
输出:
torch.return_types.topk(
values=tensor([[0.9602, 0.9356, 0.8556],
[0.8850, 0.8361, 0.7804],
[0.9984, 0.9755, 0.9478],
[0.9764, 0.8199, 0.7747],
[0.9959, 0.9958, 0.8644]]),
indices=tensor([[7, 9, 4],
[8, 7, 6],
[8, 6, 5],
[2, 9, 3],
[6, 3, 9]]))
==========================================================
torch.return_types.topk(
values=tensor([[0.0910, 0.1869, 0.2590],
[0.0592, 0.0888, 0.2776],
[0.0441, 0.1750, 0.2086],
[0.0238, 0.2317, 0.2618],
[0.0161, 0.1566, 0.2587]]),
indices=tensor([[0, 3, 2],
[0, 5, 4],
[9, 0, 7],
[5, 8, 4],
[1, 2, 8]]))
==========================================================
torch.return_types.kthvalue(
values=tensor([0.2590, 0.2776, 0.2086, 0.2618, 0.2587]),
indices=tensor([2, 4, 7, 4, 8]))
torch.return_types.kthvalue(
values=tensor([0.2590, 0.2776, 0.2086, 0.2618, 0.2587]),
indices=tensor([2, 4, 7, 4, 8]))
比较运算符号>,>=,<,<=,!=,==
输入:
a = torch.rand(5, 5)
print(a>0.2)
print(torch.gt(a, 0.2))
print(a!=0)
输出:
tensor([[ True, True, True, False, True],
[False, False, False, False, True],
[ True, True, True, True, True],
[ True, True, True, True, False],
[ True, True, True, False, False]])
tensor([[ True, True, True, False, True],
[False, False, False, False, True],
[ True, True, True, True, True],
[ True, True, True, True, False],
[ True, True, True, False, False]])
tensor([[True, True, True, True, True],
[True, True, True, True, True],
[True, True, True, True, True],
[True, True, True, True, True],
[True, True, True, True, True]])
高阶操作where和gather
torch.where
torch.where(condition,x,y)-->tensor 表示如果满足condition则返回x,否则返回y
输入:
cond=torch.tensor([[0.66,0.77],[0.56,0.423]])
a=torch.tensor([[0.,0.],[0.,0.]])
b=torch.tensor([[1.,1.],[1.,1.]])
print(torch.where(cond>0.6,a,b))
输出:
tensor([[0., 0.],
[1., 1.]])