pytorch基本函数练习

基础操作

数据类型

pytorch常用的数据类型如下:

描述数据类型CPU张量GPU张量
16位半浮点torch.halftorch.HalfTensortorch.cuda.HalfTensor
32位浮点torch.floattorch.FloatTensortorch.cuda.FloatTensor
64位浮点torch.doubletorch.DoubleTensortorch.cuda.DoubleTensor
8位无符号整型torch.uint8torch.ByteTensortorch.cuda.ByteTensor
8位整型torch.int8torch.CharTensortorch.cuda.CharTensor
16位整型torch.int16 or torch.shorttorch.ShortTensortorch.cuda.ShortTensor
32位整型torch.int32 or torch.inttorch.IntTensortorch.cuda.IntTensor
64位整型torch.int64 or torch.longtorch.LongTensortorch.cuda.LongTensor

a.type() 查看变量类型;a.cuda() CPU—>GPU;a.cpu() GPU—>CPU;len(a) 返回a的第一维
a.dim() 或 len(a.shape) 返回张量维度;a.size() 或 a.shape 返回张量大小;a.numel() 返回元素个数

数据生成

数据转换

方法一:

# 直接转换
a = a.long(),a.int(),a.float(), a.double()...

方法二:

# 直接转换
a = a.type(torch.FloatTensor),a.type(torch.DoubleTensor)...

方法三:

# 将a转换为与b的类型相同
a = torch.randint(1,6,[2,3])    # torch.LongTensor
b = torch.rand(4,3) # torch.FloatTensor
a = a.type_as(b)
print(a.type())   # torch.FloatTensor

索引和切片

维度变换

(1)变形
a.view() 函数和a.reshape() 函数两者没有区别,但是要注意view()之后之前的维度就没有了,所以要根据自己的需求判断是否要存储之前的维度。

a = torch.rand(6,7,3)
print(a.reshape(3,6,7).shape)  # torch.Size([3, 6, 7])
print(a.view(2,3,7,3,1).shape)  # torch.Size([2, 3, 7, 3, 1])

(2)插入/压缩维度
a.unsqueeze() 函数 / a.squeeze() 函数
unsqueeze()参数范围从0~a.dim()+1
squeeze()只能压缩等于1的维度,若不给参数则压缩所有等于1的维度

# eg1:为[4,32,14,14]张量加上bias
a = torch.rand(32)
print(a.unsqueeze(0).unsqueeze(2).unsqueeze(3).shape) # torch.Size([1, 32, 1, 1]), 之后再用expand()函数
# eg2:压缩
f = torch.rand(1,32,1,14)
print(f.squeeze().shape) # torch.Size([32, 14]), 不给参数,压缩所有等于1的维度
print(f.squeeze(dim=0).shape) # torch.Size([32, 1,14])
print(f.squeeze(dim=1).shape) # torch.Size([1, 32, 1, 14]), 只能压缩等于1的维度

(3)转置
a.t() 函数,a.transpose() 函数,a.permute() 函数

# t()函数 只适用于2D张量
a = torch.rand(32,21)
print(a.t().shape)  # torch.Size([21, 32])

# transpose(dim1,dim2) 交换dim1和dim2
a = torch.rand(4,3,32,21)
print(a.transpose(0,3).shape) # torch.Size([21, 3, 32, 4])

# permute(, 对应a的维度个数a.dim() , ,) 交换任意维度
a = torch.rand(4,3,32,21)
print(a.permute(1,0,3,2).shape) # torch.Size([3, 4, 21, 32]) 
# 把a的第1维放在第0维,第0维放在第一维,以此类推

(4)扩张
a.expand() 函数(推荐):节省内存,更快速。只能为等于1的维度扩张,-1表示维度不变。
a.repeat() 函数:会把所有的维度都真实copy一遍,参数表示在每个维度上copy几次,1表示维度不变,可以随意复制(更自由)

# 接上面,为[4,32,14,14]张量加上bias
a = torch.rand(32)
b = a.unsqueeze(0).unsqueeze(2).unsqueeze(3)
print(b.expand([4,-1,14,14]).shape) # torch.Size([4, 32, 14, 14]), 参数-1表示维度不变
print(b.repeat([4,1,14,14]).shape) # torch.Size([4, 32, 14, 14]), 参数1表示维度不变
print(b.repeat([4,2,14,14]).shape) # torch.Size([4, 64, 14, 14])

进阶操作

boardcast机制

当两个维度不同的张量进行运算时,pytorch会自动调用boardcast机制对张量先进行变形再运算。例如需求:一个学校有6个年级,每个年级7个班,每个学生都有3门课程,案例如下

#eg1: 对全校所有学生的所有课程都加5分
a = torch.rand(6,7,3)
b = torch.tensor(5)
print((a+b).shape) # torch.Size([6, 7, 3])

#eg2: 对学生的每个课程加不同的分数
a = torch.rand(6,7,3)
b = torch.rand(1,3)
print((a+b).shape) # torch.Size([6, 7, 3])

#eg3: 学校偏心,对每个班的加分不同
a = torch.rand(6,7,3)
b = torch.rand(7,1)
print((a+b).shape) # torch.Size([6, 7, 3])

#eg4: 极端例子,展示的boardcast机制的使用限制
a = torch.rand(2,1,7,3)
b = torch.rand(6,1,3)
print((a+b).shape) # torch.Size([2, 6, 7, 3])

如eg4所示,限制有以下两点:
1. 两个张量从最后一维开始,向前匹配
2. 只有某维度的大小是0或者1时,才能进行扩张

合并和分割

(1)合并
torch.cat() 函数,需保证除了合并维度外的其他维度size一致,默认dim=0

a = torch.rand(2,7,4,2)
b = torch.rand(2,7,3,2)
print(torch.cat([a,b],dim=2).shape) # torch.Size([2, 7, 7, 2])

(2)分割
torch.stack() 函数,保证两个合并张量size完全一致

a = torch.rand(2,7,4,2)
b = torch.rand(2,7,4,2)
c = torch.stack([a,b],dim=2)
print(c.shape) # torch.Size([2, 7, 2, 4, 2])
print(torch.all(torch.eq(c[:,:,0,:,:],a)))  # True
print(torch.all(torch.eq(c[:,:,1,...],b)))  # True

数学运算

(1)运算
加减乘除

符号运算
+ 等价于 torch.add()加法
- 等价于 torch.sub()减法
* 等价于 torch.mul()乘法
/ 等价于 torch.div()除法
**乘方
@ 等价于 torch.matmul()矩阵乘
torch.exp(a)e a
torch.log(a)ln(a)

比较大小

符号运算
a>0等价于torch.gt(a,0)大于
==等价于torch.eq(),torch.equal()等于
>= !=(都可以用符号表示)大于等于,不等于…

torch.eq()和torch.equal()区别如下:

a = torch.randint(1,9,[2,4])    # torch.LongTensor
b = torch.randint(1,9,[2,4])
print(torch.eq(a,b)) # 返回矩阵
# tensor([[ True, False, False, False],
#        [False, False, False, False]])
print(torch.equal(a,b))	# 返回一个值
# False

(2)近似
round() 四舍五入,trunc() 截取整数部分,frac() 截取小数部分

a = torch.tensor(3.14159)
print('floor:%f,ceil:%f,round:%f,trunc:%f,frac:%f'%(a.floor(),a.ceil(),a.round(),a.trunc(),a.frac()))
# 输出 floor:3.000000,ceil:4.000000,round:3.000000,trunc:3.000000,frac:0.141590

(3)裁剪
a.clamp(min,max) 函数,保证a的值在min~max之间

a = torch.randint(1,10,[3,4])
print(a)
print(a.clamp(5))
print(a.clamp(3,6))

输出:

tensor([[6, 1, 1, 5],
        [5, 6, 5, 2]])
tensor([[6, 5, 5, 5],
        [5, 6, 5, 5]])
tensor([[6, 3, 3, 5],
        [5, 6, 5, 3]])

统计属性

(1) 范数
a.norm(几范数,dim=) 对a的第几维求几范数

a = torch.randint(1,6,[2,3])    # torch.LongTensor
a = a.float() #转为float才能求范数
print(a) 
# tensor([[4., 3., 1.],
        #[5., 4., 5.]])
print(a.norm(2)) # tensor(9.5917)
print(a.norm(1,dim=0))  # tensor([9., 7., 6.])

这里注意一点,a是2*3的矩阵,dim=0时消掉第0维,也就是获得3列的一范数。(这里我也很晕@@,有时候是对着那一维求解,有时候是消去,应该是需要死记硬背吧,下面介绍的这些统计函数都是消去)

(2)平均、累加乘
a.mean() 平均; a.sum() 累加; a.prod() 累乘

a = torch.randint(1,6,[2,3])    # torch.LongTensor
a = a.float()
print(a)
# tensor([[4., 3., 4.],
#        [4., 3., 1.]])
print(a.mean(dim=0))  #tensor([4.0000, 3.0000, 2.5000])
print(a.sum(dim=0))  #tensor([8., 6., 5.])
print(a.norm(1,dim=0)) #tensor([8., 6., 5.])
print(a.prod()) #tensor(576.)

NOTE: dim=规则同上

(3)最大最小
a.max() 最大值,a.min() 最小值,a.argmin() 最大值的索引,a.argmax() 最小值的索引,a.tpok() 前k个最大值/最小值,a.kthvalue() 第k个最小的值。

值,索引=a.max(dim=),当输出为两个参数时,必须要加dim否则报错

a = torch.randint(1,9,[2,3])    # torch.LongTensor
print(a)
# tensor([[8, 2, 4],
#        [7, 2, 2]])
print(a.max())  # tensor(8)
print(a.max(dim=1))
#values=tensor([8, 7]),
#indices=tensor([0, 0]))
value,index = a.max(dim=1)  
print(value,index) # tensor([8, 7]) tensor([0, 0])

值,索引=a.max(dim=,keepdim=True) 用于设置保持维度。

print(a)
#tensor([[1, 7, 2],
#        [7, 3, 3]])
value,index = a.min(dim=1)
print(value) #tensor([1, 3])
value,index = a.min(dim=1,keepdim=True)		#保持维度
print(value) # tensor([[1],
             # [3]])

a.argmax() 求最大值的索引

print(a.argmax()) #tensor(1)
print(a.argmax(dim=1)) #tensor([1, 0])

值,索引=a.topk(n,dim=,largest=True) 求前n个最大T/最小值F,默认largest=True求最大

# tensor([[7, 8, 7],
#        [4, 4, 8]])
print(a.topk(2,dim=1))
# torch.return_types.topk(values=tensor([[8, 7],[8, 4]]),indices=tensor([[1, 0], [2, 0]]))
print(a.topk(2,dim=1,largest = False))
# torch.return_types.topk(values=tensor([[7, 7],[4, 4]]),indices=tensor([[0, 2],[0, 1]]))

值,索引=a.kthvalue(n,dim=1) 求第n个小的值,默认dim=1

a = torch.randint(1,9,[3,6])    # torch.LongTensor
print(a)
# tensor([[3, 2, 4, 8, 2, 7],
#         [6, 5, 3, 4, 4, 2],
#         [2, 7, 6, 2, 4, 6]])
print(a.kthvalue(2))
# torch.return_types.kthvalue(
# values=tensor([2, 3, 2]),
# indices=tensor([4, 2, 3]))

高阶操作

(1)torch.where(condition,x,y)
官网介绍:
若condition==T则取x,否则取y
在这里插入图片描述

a = torch.randint(1,9,[2,4])    # torch.LongTensor
b = torch.randint(1,9,[2,4])

print(a)
#tensor([[2, 7, 3, 8],
#        [6, 8, 3, 8]])
print(b)
#tensor([[1, 2, 1, 1],
#        [1, 2, 2, 3]])
print(torch.where(a>3,a,b))
#tensor([[1, 7, 1, 8],
#        [6, 8, 2, 8]])

(2)torch.gather(input,dim,index,out=None)
根据index索引值选取input中的元素,按dim组成新的张量,新张量的大小与index大小相同。

a = torch.tensor([[7, 1, 6],
                  [8, 4, 4]])
print(torch.gather(a,0,torch.tensor([[0,1,0], [1,0,1]])))
#tensor([[7, 4, 6],    第一行是a[0][0],a[1][2],a[0][3] 
#        [8, 1, 4]])   第二行是a[1][1],a[0][2],a[1][3]
# dim=0时,第一维是index;第二维是列索引
print(torch.gather(a,1,torch.tensor([[0,0,1], [1,0,2]])))  # dim=1按行选取
#tensor([[7, 7, 1],    第一行是a[0][0],a[0][0],a[0][1] 
#        [4, 8, 4]])   第二行是a[1][1],a[1][0],a[1][2]
# dim=1时,第一维是行索引;第二维是index

Note: input和index的维度一致,但是index.size(d) <= input.size(d)

持续更新。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值