pytorch进阶教程

进阶部分

Broadcasting:Expand/without copying data 广播机制

例如:unsqueeze 与 expand,详情见基础部分

import torch
a = torch.randn(4,32,14,14)# 在a上叠加b,改变b的维度使其符合a的标准
b = torch.randn(32,1,1)
#维度从右到左与a对齐
#(4,32,14,14)
#   (32,1,1)
b.unsqueeze(0).expand(4,32,14,14).shape
# torch.Size([4, 32, 14, 14])

为什么要用广播机制?

  • 实际需求。比如如下维度:[4,32,8],代表着[班级,人数,科目分数],也就是4个班,每个班32个人,每个人有着八个科目的分数,如果我们想为每个同学的每个科目都加五分,越往右维度越细化,[4,32,8]+[5.0] 符合转换需求,就可以自动变换。
  • 节省内存
    什么时候需要广播机制?
  • 从最后一个维度开始匹配,小维度指定,大维度随意。缺维度就增加一个维度,然后再扩张到正确的维度

在这里插入图片描述

import torch
c = torch.tensor([[0,0,0],[10,10,10],[20,20,20],[30,30,30]])
c
'''
tensor([[ 0,  0,  0],
        [10, 10, 10],
        [20, 20, 20],
        [30, 30, 30]])
'''
c2 = c + torch.tensor(5) # 0维,自动扩张
c2
'''
tensor([[ 5,  5,  5],
        [15, 15, 15],
        [25, 25, 25],
        [35, 35, 35]])
'''
c1 = c + torch.tensor([5])# 1维,自动扩张
c1
'''
tensor([[ 5,  5,  5],
        [15, 15, 15],
        [25, 25, 25],
        [35, 35, 35]])
'''
c2 = c + torch.tensor([0,1,2]) # 1维,但size必须为3,才能符合广播机制需求
c2
'''
tensor([[ 0,  1,  2],
        [10, 11, 12],
        [20, 21, 22],
        [30, 31, 32]])
'''
c3= torch.tensor([0,10,20,30]).view(4,1)
c3
'''
tensor([[ 0],
        [10],
        [20],
        [30]])
'''
c4 = torch.tensor([0,1,2])
c5 = c3+c4
c5
'''
tensor([[ 0,  1,  2],
        [10, 11, 12],
        [20, 21, 22],
        [30, 31, 32]])
'''

拼接与拆分

拼接:cat/stack

  • cat
a = torch.rand(4,32,8)
b = torch.rand(5,32,8)
#在0维上拼接,必须保证其他维度size一致
torch.cat([a,b],dim=0).shape
# torch.Size([9, 32, 8])
a = torch.rand(4,3,32,32)
b = torch.rand(5,3,32,32)
torch.cat([a,b],dim=0).shape
# torch.Size([9, 3, 32, 32])
a2 = torch.rand(4,1,32,32)
torch.cat([a2,a],dim=1).shape
# torch.Size([4, 4, 32, 32])
  • stack: create new dim
# 合并两个班的成绩单
a = torch.rand(32,8)
b = torch.rand(32,8)
torch.stack([a,b],dim=0).shape 
#各增加一个0维,size为1
# torch.Size([2, 32, 8])

拆分:split/chunk

  • split
c = torch.rand(2,32,8)
aa,bb=c.split([15,17],dim=1)
aa.shape,bb.shape
# (torch.Size([2, 15, 8]), torch.Size([2, 17, 8]))
aa,bb,cc=c.split([15,14,3],dim=1)
cc.shape
# torch.Size([2, 3, 8])
aa,bb=c.split(16,dim=1) #只有16可以,可以被32整除
aa.shape
# torch.Size([2, 16, 8])
  • chunk
aa,bb,cc,dd = c.chunk(4,dim=1)#拆成四份
dd.shape
# torch.Size([2, 8, 8])

基本运算

  • 加减乘除
a = torch.rand(3,4)
b =torch.rand(4)
torch.all(torch.eq(a+b,torch.add(a,b)))#加
torch.all(torch.eq(a-b,torch.sub(a,b)))#减
torch.all(torch.eq(a*b,torch.mul(a,b)))#乘
torch.all(torch.eq(a/b,torch.div(a,b)))#除
# tensor(True)
  • 2维矩阵相乘
a = torch.full((2,2),3)
b = torch.ones(2,2)
torch.mm(a,b) #only for 2 dim
a@b
'''
tensor([[6., 6.],
        [6., 6.]])
'''
#神经网络的线性层
a = torch.rand(4,784)
x = torch.rand(4,784)
w = torch.rand(512,784) #w惯用写法(channel_out,channel_in),所以要先将w转置
(x@ w.t()).shape
# torch.Size([4, 512])
#转置小tip
w = torch.rand(512,784,28,28) 
w.transpose(0,3).shape
#torch.Size([28, 784, 28, 512])
w.permute(3,2,0,1).shape
# torch.Size([28, 28, 512, 784])
  • 2维以上的矩阵乘法
a = torch.rand(4,3,28,64)
b = torch.rand(4,3,64,32)
torch.matmul(a,b).shape #后面两维做矩阵乘法
# torch.Size([4, 3, 28, 32])
a = torch.rand(4,3,28,64)
b = torch.rand(4,1,64,32)
torch.matmul(a,b).shape 
#既使用了矩阵相乘,又使用了广播机制,b的1维自动扩张
#torch.Size([4, 3, 28, 32])
  • 次方运算
a = torch.full([2,2],3)
a.pow(2),aa = a**2
'''
tensor([[9., 9.],
        [9., 9.]])
'''
  • 平方根
aa.sqrt() #平方根
'''
tensor([[3., 3.],
        [3., 3.]])
'''
aa.rsqrt() #返回平方根的倒数
'''
tensor([[0.3333, 0.3333],
        [0.3333, 0.3333]])
'''
  • e
a  = torch.exp(torch.ones(2,2)) #e^1
'''
tensor([[2.7183, 2.7183],
        [2.7183, 2.7183]])
'''
torch.log(a)#e为底
'''
tensor([[1.0000, 1.0000],
        [1.0000, 1.0000]])
'''
  • 近似值
a  = torch.tensor(3.14)
a.floor()#往下取整
a.ceil()#往上取整
a.trunc()#裁剪整数部分
a.frac()#裁剪小数部分
# (tensor(3.), tensor(4.), tensor(3.), tensor(0.1400))
a = torch.tensor(3.46)
a.round()
# tensor(3.)
a = torch.tensor(3.51)
a.round()
# tensor(4.)
  • 梯度裁剪clamp
grad = torch.rand(2,3)*15
grad
'''
tensor([[12.9732,  1.2229,  7.0443],
        [14.5265,  5.6721,  2.9501]])
'''
grad.max(axis = 1) # 按行
'''
torch.return_types.max(
values=tensor([12.9732, 14.5265]),-->值 value
indices=tensor([0, 0])) -->索引 index
'''
grad.median()
# tensor(5.6721)
grad.clamp(10)#最小值限定为10(min)
'''
tensor([[12.9732, 10.0000, 10.0000],
        [14.5265, 10.0000, 10.0000]])
'''
grad.clamp(0,10)#限定为 (min,max)
'''
tensor([[10.0000,  1.2229,  7.0443],
        [10.0000,  5.6721,  2.9501]])
'''

统计属性

  • norm 范数
a = torch.full([8],1)
b = a.view(2,4)
'''
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.]])
'''
c = a.view(2,2,2)
a.norm(1),b.norm(1),c.norm(1) #一范数,∑|x|
# (tensor(8.), tensor(8.), tensor(8.))
a.norm(2),b.norm(2),c.norm(2)#二范数,sqrt(∑|x|^2)
# (tensor(2.8284), tensor(2.8284), tensor(2.8284))
b.norm(1,dim=1)
# tensor([4., 4.])
b.norm(2,dim=1)
# tensor([2., 2.])
a = torch.arange(8).view(2,4).float()
a.min(),a.max(),a.mean(),a.prod()#累乘
# (tensor(0.), tensor(7.), tensor(3.5000), tensor(0.))
a.sum(),a.argmax(),a.argmin()
# (tensor(28.), tensor(7), tensor(0))
  • dim/keepdim
a  =torch.randn(4,10)
a.max(dim=1) #获得每一张照片的预测值和置信度 
'''
torch.return_types.max(
values=tensor([0.8487, 1.0158, 2.0120, 1.1418]),#置信度
indices=tensor([1, 4, 8, 3]))#预测值
'''
a.max(dim=1,keepdim=True)#保持二维
'''
torch.return_types.max(
values=tensor([[0.8487],
        [1.0158],
        [2.0120],
        [1.1418]]),
indices=tensor([[1],
        [4],
        [8],
        [3]]))
'''
a.max(dim=1,keepdim=False)
'''
torch.return_types.max(
values=tensor([0.8487, 1.0158, 2.0120, 1.1418]),
indices=tensor([1, 4, 8, 3]))
'''

topk/k-th

a  =torch.randn(4,10)
a.topk(3,dim=1) #1维上最大的三个
'''
torch.return_types.topk(
values=tensor([[0.8487, 0.5053, 0.4132],
        [1.0158, 0.6249, 0.5897],
        [2.0120, 0.7639, 0.5647],
        [1.1418, 0.9470, 0.5445]]),
indices=tensor([[1, 3, 7],
        [4, 1, 7],
        [8, 0, 5],
        [3, 6, 5]]))
'''
a.topk(3,dim=1,largest=False) #最小的三个
'''
torch.return_types.topk(
values=tensor([[-4.0843, -1.1895, -0.7910],
        [-0.9890, -0.9026, -0.8703],
        [-1.4781, -0.8836, -0.7796],
        [-1.6847, -1.4048, -0.7745]]),
indices=tensor([[0, 9, 5],
        [6, 0, 9],
        [1, 6, 2],
        [0, 7, 1]]))
'''
a.kthvalue(8,dim=1) #第八大
'''
torch.return_types.kthvalue(
values=tensor([0.4132, 0.5897, 0.5647, 0.5445]),
indices=tensor([7, 7, 5, 5]))
'''
  • compare
a>0, torch.gt(a,0)
#eq() equal()
'''
tensor([[False,  True, False,  True, False, False, False,  True,  True, False],
        [False,  True, False, False,  True, False, False,  True, False, False],
        [ True, False, False, False, False,  True, False, False,  True,  True],
        [False, False, False,  True,  True,  True,  True, False,  True, False]])
'''

高阶Operation

where

在这里插入图片描述torch.where(condition,x,y)–>Tensor

cond  = torch.tensor([[0.6769,0.7271],[0.8884,0.4163]])
cond
'''
tensor([[0.6769, 0.7271],
        [0.8884, 0.4163]])
'''
a = torch.zeros(2,2)
b = torch.ones(2,2)
torch.where(cond>0.5,a,b)#>0.5取a,<0.5取b
'''
tensor([[0., 0.],
        [0., 1.]])
'''

gather

torch.gather(input,dim,index,out=None)–> Tensor
各参数:
索引表:[0,1,2]–>[狗,猫,熊] #input
索引结果:[1,0,1,2] #index
输出结果:[猫,狗,猫,熊] #output

prob = torch.randn(4,10)

idx = prob.topk(dim=1,k=3) #每行前三
idx[1] #topk返回的是值和索引,所以是idx[1]
'''
tensor([[4, 1, 9],
        [8, 3, 9],
        [9, 1, 4],
        [6, 8, 2]])
'''

label = torch.arange(10)+100
label.expand(4,10)
'''
tensor([[100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
        [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
        [100, 101, 102, 103, 104, 105, 106, 107, 108, 109],
        [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]])
'''
#0-->100,1-->101,2-->102

torch.gather(label.expand(4,10),dim=1,index=idx[1])
'''
tensor([[104, 101, 109],
        [108, 103, 109],
        [109, 101, 104],
        [106, 108, 102]])
'''

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值