目录
所有代码操作都默认在Jupyter notebook中实现,如果在其他IDE,输出需要使用print函数。
2.1 张量的数据类型
在torch中CPU和GPU张量分别有8种类型:
数据类型 | dtype | CPU tensor | GPU tensor |
32位浮点型 | torch.float32或torch.float | torch.FloatTensor | torch.cuda.FloatTensor |
64位浮点型 | torch.float64或torch.double | torch.DoubleTensor | torch.cuda.DoubleTensor |
16位浮点型 | torch.float16或torch.half | torch.HalfTensor | torch.cuda.HalfTensor |
8位无符号整型 | torch.unit8 | torch.ByteTensor | torch.cuda.ByteTensor |
8位有符号整型 | torch.int8 | torch.CharTensor | torch.cuda.CharTensor |
16位有符号整型 | torch.int16或torch.short | torch.ShortTensor | torch.cuda.ShortTensor |
32位有符号整型 | torch.int32或torch.int | torch.IntTensor | torch.cuda.IntTensor |
64位有符号整型 | torch.int64或torch.long | torch.LongTensor | torch.cuda.LongTensor |
默认32位浮点型;修改数据类型:
improt torch # 导入需要的库
torch.tensor().dtype # 获得张量的数据类型
torch.set_default_tensor_type(torch.DoubleTensor) # 设置为64位浮点型
.long() # 设置为torch.int64
.int() # 设置为torch.int32
.float() # 设置为torch.float32
torch.set_default_tensor_type(torch.FloatTensor) # 设置为默认的32位浮点型
torch.get_default_tensor_type() # 获取默认的数据类型
2.2 张量的生成
(1)使用torch.tensor()函数生成张量
A = torch.tensor([[1, 1], [2, 2]]) # 将python的列表转化为张量
A.shape # 获取张量的维度
A.size() # 获取张量的形状大小
A.numel() # 计算张量中包含的元素个数
# 参数dtype指定张量的数据类型;requires_grad参数指定张量是否需要求梯度
B = torch.tensor([1, 2, 3], dtype=torch.float32, requires_grad=True)
计算梯度:只有浮点数类型数据才能计算梯度
## 计算张量B的 sum(B^2)在每个元素上的大小:
y = B.pow(2).sum()
y.backward()
B.grad
##(out: tensor([2., 4., 6.])) 2*B
(2) torch.Tensor()函数
C = torch.Tensor([1, 2, 3, 4]) # 根据已有数据创建张量
D = torch.Tensor(2, 3) # 指定形状,随机生成2*3的张量
torch.**_like() # 指定生成张量维度相同、性质相似的张量。
torch.ones_like(D) # 生成与D维度完全相同、全为1的张量
torch.zeros_like(D) # 生成与D维度完全相同、全为0的张量
torch.rand_like(D) # 生成与D维度完全相同的随机张量
D.new_**() # 根据创建好的张量创建新的张量
E = [[1, 2], [3, 4]] # 创建一个列表
E = D.new_tensor(E) # 将E转化为和D数据类型相似,值不同的张量
表1 D.new_**()系列函数
函数 | 描述 |
---|---|
D.new_full((3, 3),fill_value = 1) | 3*3使用1填充的张量 |
D.new_zeros((3, 3)) | 3*3的全0张量 |
D.new_empty((3, 3)) | 3*3的空张量 |
D.new_ones((3, 3)) | 3*3的全1张量 |
(3)张量和Numpy数据相互转换
a) 将Numpy数组转换为PyTorch张量:torch.as_tensor() \torch.from_numpy()
import numpy as np
F = np.ones((3, 3)) # 利用Numpy生成3*3全1数组
##使用torch.as_tensor()函数
Ftensor = torch.as_tensor(F)
##使用torch.from_numpy()函数
Ftensor = torch.from_numpy(F)
b ) .numpy()函数: 将Pytorch中的张量转化为Numpy数组
Ftensor.numpy()
(4)随机数生成张量
通过相关随机数生成张量,指定生成随机数的分布。
a) torch.manual_seed()函数:指定生成随机数的种子,用于保证随机数是可重复出现的
b) torch.normal()函数:生成服从正态分布的随机数,mean=随机数的均值,std=随机数的标准差
torch.manual_seed(123) #生成随机数种子
A = torch.normal(mean=0, std=torch.tensor(1)) # 生成一个服从(0, 1)分布的随机数
A = torch.normal(mean = 0, std = torch.arange(1, 5)) #生成均值为0,标准差为1,2,3,4的随机数
#分别指定每个随机数的均值和方差。
A=torch.normal(mean=torch.arange(1, 5), std=troch.arange(1, 5)) ##mean=1,2,3,4;std=1,2,3,4
c) torch.rand()函数: 在[0,1]区间上生成服从均匀分布的张量
torch.manual_seed(123)
B = torch.rand(2, 3) # 生成2*3的均匀分布的张量
d) torch.rand_like()函数: 根据其他维度张量,生成维度相同的随机数张量
torch.manual_seed(123)
C = torch.ones(2, 3) # 生成2*3的全1张量
D = torch.rand_like(C) # 生成与C维度相同的随机数张量
e)torch.randn() \torch.randn_like() :生成服从标准正态分布的随机数张量
f) torch.randperm(n)函数:将0~n(不包含n)之间的整数进行随机排序后输出:
torch.maual_seed(123)
torch.randperm(10) # 将0~9十个数字重新随机排序后输出。
(5)其他生成张量的函数
a) torch.arange(start=开始, end=结束(不包含), step=步长)
torch.arange(start=0, end=10, step=2)
b) torch.linspace(start=开始, end=结束(包含), steps=个数)函数:在范围内生成固定数量的等间隔张量。
torch.linspace(start=1, end=10, steps=5)
c) torch.logspace(): 可生成以对数为间隔的张量
torch.logspace(start=0.1, end=1.0, steps=5)
输出结果和10**(touch.linspace(start=0.1, end=1, steps=5))结果等价。
函数 | 描述 |
---|---|
torch.zeros(3,3) | 3*3全0张量 |
torch.ones(3, 3) | 3*3全1张量 |
torch.eye(3) | 3*3的单位张量 |
torch.full((3, 3), fill_value=0.25) | 3*3使用0.25填充的张量 |
torch.empty(3, 3) | 3*3的空张量 |
2.3 张量操作
(1) 改变张量的形状
a).reshape()\ tensor.reshape() :设置张量形状的大小
A = tensor.arange(12).reshape(3, 4) # 将1*12转换成3*4的张量
B = tensor.reshape(input=A, shape=(2,-1)) # 将3*4转换成2*6 (-1 表示自动计算的列数)
b) tensor.resize_(): 针对输入的形状大小对张量形状进行修改
A.resize_(2,6)
c) A.resize_as_(B): 将A的张量形状尺寸设置成与B相同的形状尺寸。
d) torch.unsqueeze()函数:在张量的制定维度插入新的维度得到维度提升的张量。
e) torch.squeeze()函数:移除指定或者所有维度大小为1 的维度,得到维度减小的新张量
A = torch.arange(12).reshape(2,6)
f) .expand(): 对维度进行拓展
g) A.expand_as(C) :按C张量的形状和大小拓展A
A = torch.arange(3)
B = A.expand(3,3)
C = torch.arange(12).reshape(2,6)
B = A.expand_as(C) ## B的torch.size([2,3])
h) .repeat() :将张量看作一个整体,根据指定的形状进行重复填充
# 拓展维度大于B的维度,则将B的0维拓展为1维,其他维度对应复制:B[2,3]-->[1,2,3]-->[1,4,6]
D = B.repeat(1,2,2)
D.shape # torch.size([1,4,6])
(2)获取张量中的元素(需要细化)
和numpy中的方法一样
A = torch.arange(12).reshape(1,3,4)
A[0]
tensor
(3)拼接和拆分(需要细化)
可以利用Pytorch中的函数将多个张量拼接为一个张量、将大的张量拆分为多个小的张量。
a) torch.cat():将多个张量在指定维度进行拼接。
A = torch.arange(6.0).reshape(2, 3)
B = torch.linspace(0, 10, 6).reshape(2, 3)
# 在0维度连接张量
C = torch.cat((A, B), dim=0)
# 在0维度连接三个张量
D = torch.cat((A[:,0:2],A,B),dim=1)
# 在1维度连接三个张量
D = torch.cat((A[:,1:2],A,B),dim=1)
b) torch.stack(),将多个张量按照指定维度进行拼接
# 沿新维度连接张量
F = torch.stack((A,B),dim=0)
c) torch.chunk()将张量分割成特定数量的块
# 在行上将张量E分割为两块
torch.chunk(E,2,dim=0)
# 在列上将张量D 分割为两块
D1,D2 = torch.chunk(D,2,dim=1)
# 如果沿给定维度dim的张量大小不能被块整除,最后一块将最小
d)torch.split()在将张量分割成特定数量的块时,可以指定每个块的大小
# 将张量切分为块,指定每个块的大小
D1,D2,D3 = torch.split(D,[1,2,3],dim=1)
2.4 张量计算
(1)比较大小(需要细化)
函数 | 功能 |
---|---|
torch.allclose() | 比较两个元素是否相近 |
torch.eq() | 逐元素比较是否相等 |
torch.equal() | 判断两个张量是否具有相同的形状和元素 |
torch.ge() | 逐元素比较大于等于 |
torch.gt() | 逐元素比较大于 |
torch.le() | 逐元素比较小于等于 |
torch.lt() | 逐元素比较小于 |
torch.ne() | 逐元素比较不等于 |
torch.isnan() | 判断是否为缺失值 |
(2)基本运算
逐元素之间的运算:四则运算、幂运算、平方根、对数、数据裁剪 ;
矩阵之间的运算:矩阵相乘、矩阵的转置、矩阵的迹
a) 逐元素之间的运算
a. 逐元素的四则运算
## 同型矩阵矩阵逐元素相乘
A * B
## 同型矩阵矩阵逐元素相除
A / b
## 同型矩阵矩阵逐元素相加减
A + B
A - B
## 同型矩阵矩阵逐元素整除
A // B
b. torch.pow()函数 \ **运算符 :计算张量的幂
torch.pow(A,3)
A ** 3
c. torch.exp()函数: 计算张量的指数
torch.exp(A)
d. torch.log() :计算张量的对数
torch.log(A)
e. torch.sqrt() :计算张量的平方根
torch.sqrt(A)
f. torch.rsqrt() : 计算张量的平方根倒数
torch.rsqrt(A)
1 / (A ** 0.5)
g. torch.clamp_max(): 根据最大值裁剪
h. torch,clamp_min(): 根据最小值裁剪
i. torch.clamp() :根据范围裁剪
A = torch.arange(6).reshape(2,-1)# A = tensor([[0.,1.,2.],[3.,4.,5.]])
## 最大值裁剪 大于指定数的都转为指定数
torch.clamp_max(A, 4) #out:tensor([[0.,1.,2.],[3.,4.,4.]])
## 最小值裁剪 小于指定数的都转为指定数
torch.clamp_min(A, 3) #out:tensor([[3.,3.,3.],[3.,4.,5.]])
## 范围裁剪
torch.clamp(A, 2.5, 4) #out:tensor([[2.5,2.5,2.5],[3.,4.,4.]])
b) 张量矩阵运算
a. torch.t(): 计算矩阵的转置
b. torch.matmul(): 输出两个矩阵的乘积(行列+广播机制)
torch.mm():矩阵相乘(行列)
torch.mul():对位相乘(广播机制)
## 矩阵的转置
C = torch.t(A)
## 矩阵相乘,A的行数乘以C的列数
A.matul(C)
## 两个三维矩阵相乘
A = torch.arange(12).reshape(2,2,3)
B = torch.arange(12).reshape(2,3,2)
AB = torch.matmul(A,B)
## 矩阵相乘只计算最后面的两个维度的乘法
print(AB[0].eq(torch.matul(A[0],B[0])))
print(AB[1].eq(torch.matul(A[1],B[1])))
c. torch.inverse()函数: AXB=I, I为单位矩阵,则可A和B互为逆矩阵,计算矩阵的逆矩阵使用该函数。
d. torch.trace()函数: 计算对角线元素的和(即矩阵的迹)
## 计算矩阵的逆
C = torch.rand(3,3)
D = torch.inverse(C)
torch.mm(C,D)
## 计算张量矩阵的迹,对角线元素之和
torch.trace(torch.arange(9.0).reshape(3,3))
(3) 统计相关的计算
a) torch.max(): 计算张量中的最大值
b) torch.argmax() : 输出最大值所在的位置
c) torch.min(): 计算张量中的最大值
d) torch.argmin(): 输出最小值所在的位置
## 一维张量的最大值与最小值
A = torch.arange(12)
## 最大值与最大值位置
print("最大值:",A.max())
print("最大值位置:",A.argmax())
## 最小值及其位置
print("最小值:",A.min())
print("最小值:",A.argmin())
##二维张量的最大值与最小值
B = A.reshape(3,4)
print("2D张量B:\n",B)
## 最大值及其位置(每行)
print("最大值:\n",B.max(dim=1))
print("最大值位置:\n",B.argmax(dim=1))
## 最小值及其位置(每列)
print("最小值:\n",B.minx(dim=0))
print("最小值位置:\n",B.argmin(dim=0))
e) torch.sort() : 对一维张量进行排序,对高维指定维度排序,输出排序结果、对应值原始位置索引
f) torch.topk(): 根据k值,计算出张量中取值为第k大的数值和位置
g) torch.kthvalue() :根据k值,计算出张量中取值为第k小的数值与位置
## 获得张量前几个大的数值
h) torch.mean(): 根据指定的维度计算均值
i) torch.sum(): 根据指定的维度求和
j) torch.cumsum(): 根据指定的维度计算累加和
k) torch.median(): 根据指定的维度计算中位数
l) torch.cumprod(): 根据指定的维度计算累乘积
m) torch.std() 计算张量的标准差