pytorch高阶操作

目录

broadcast广播机制

合并与分割

cat拼接

stack创建新维度

split按长度拆分和chunk按数量拆分

数学运算

add/sub/mul/div加减乘除

matmul矩阵相乘

pow矩阵的次方以及sqrt/rsqrt/exp/log

round矩阵近似运算

clamp(裁剪)

统计属性

norm范数,prod张量元素累乘(阶乘)

mean/sum/max/min/argmin/argmax

kthvalue()和topk()

比较运算符号>,>=,<,<=,!=,==

 高阶操作where和gather

torch.where

torch.gather


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.]])
 

torch.gather

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值