最近感觉记性变得有点差,很多方法的使用经常记不住,虽然说现在已经是llm后时代了,但是感觉很多代码如果不是自己写的话会有一种无力感(笑),故在此记录一下pytorch常用的一些方法(其实也包括python方法,笔者的python基础也是一坨。。)

首先就是一些常用的创建张量的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import torch
# 个人习惯里面传入列表来创建张量
tensor1=torch.tensor()
# 按照一定的序列创建张量,和range用法差不多(比如输入3,10就会创建出一个(7,)的张量)
torch.arange(begin,end,step)
# 创建固定大小和值的张量
torch.full(size,fill_value)
# 创建全0张量
torch.zeros(size)
# 创建全1张量
torch.ones(size)
#通过已有张量创建全0或者全1张量
torch.ones_like(input_tensor)
torch.zeros_like(input_tensor)

当然了,我们在写模型和训练pipeline时不止要创造tensor,还要对其进行各种操作,这里我也会列出自己写模型中遇到的常见操作:

先从各种属性讲起吧

1
2
3
4
5
6
# 访问当前张量所在设备(默认是在CPU上)
tensor.device
# 访问当前张量的类型(pytorch中默认为torch.float32)
tensor.dtype
# 访问当前张量的形状(返回一个元组)
tensor.shape

对张量变换的各种方法(大部分都是numpy中已有的方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 迁移设备和转换类型
tensor.to(device or dtype)
# 分离张量,在多头注意力中经常使用
tensor.split(split_num,dim=dim)->torch.Tensor
'''
args:
split_num->分离的数量
dim->拆分的维度
'''
# 获取张量某一个维度的大小
tensor.size(dim)
# 改变张量的形状(一般都有参数keepdim)
tensor.transpose(size)
# 注意:此方法下张量元素在内存中必须是连续的,最好在使用之前用contiguous()进行重构
tensor.view(size)
tensor.reshape(size)
# 使用cat或者stack或者用了sum和mean之后我们往往不希望张量的维度发生变化(既希望保留原有的维度即使为1)
#保持原有维度
tensor.unsequeeze(dim)
#消除大小为1的维度
tensor.sequeeze(dim)
# 如果张量是二维的情况下可以直接对其进行转置
tensor.T
# 张量的拼接(两者都可以使用)
tensor.cat(size,dim,device)
tensor.stack(size,dim,device)

数学方法:

pytorch中有很多数学函数可以直接使用,与numpy不同的是需要输入张量

1
2
3
4
5
6
7
8
9
# 这里不一一举例了
torch.exp()
torch.log()
torch.sin()
# 这里特别介绍两个可能会使用的方法
# 计算两个向量的外积,所以输入必须是一维张量
torch.outer(tensor,tensor)
# 计算根号倒数
torch.rsqrt(tensor,dim)

其余常用方法:

pytorch中还提供了其它用于张量操作的方法:

1
2
3
4
5
6
7
8
# 对张量进行排列(指定某个维度以及是否降序),返回原索引和排序后的元素
torch.sort(tensor,descending=False,dim)
# 获取张量的累计和
torch.cumsum(tensor,dim)
# 采样函数(返回一个张量)
torch.multinomial(tensor,num_sample)
# 映射函数,根据当前索引映射回未排序之前的序列索引中,一般和torch.sort配合使用,返回一个索引
torch.gather(index_tensor,dim,index_current)