Pytorch是研究深度学习的一种得力工具,相当于机器学习中numpy和sklearn的地位。它将数据封装成张量(Tensor)来进行处理。PyTorch 中的张量就是元素为同一种数据类型的多维矩阵。在 PyTorch 中,张量以 "类" 的形式封装起来,对张量的一些运算、处理的方法也被封装在类中。
1. 张量的创建
python
import torch
torch.tensor(数据) # 根据指定数据创建张量
torch.Tensor(形状号[或数据]) #根据形状创建张量, 其也可用来创建指定数据的张量
# 创建指定类型的张量
torch.ShortTensor(形状号或[数据]) # int16
torch.IntTensor(形状号或[数据]) # int32
torch.LongTensor(形状号或[数据]) # int64
torch.FloatTensor(形状号或[数据]) # float32
torch.DoubleTensor(形状号或[数据]) # float64
# 创建线性张量
torch.arange(start, end, step) # 不包右,在指定区间按照步长生成元素
torch.linspace(start, end, num) #包右,在指定区间按照元素个数生成
# 创建随机张量
torch.random.init_seed() #查看随机数种子
torch.random.manual_seed(num) #手动设置随机数种子
torch.randn(形状号) # 创建服从正态分布的随机张量
# 创建指定值张量
torch.ones(形状号) #创建指定形状全0张量
torch.ones_like(要形状相似的张量) #根据张量形状创建全0张量
torch.zeros(形状号) #创建指定形状全0张量
torch.zeros_like(要形状相似的张量) #根据张量形状创建全0张量
torch.full(形状号) #创建指定形状全为指定值张量
torch.full_like(要形状相似的张量) #根据张量形状创建全为指定值张量
2. 张量的类型转换
python
# 将张量中的元素转换为指定类型
张量data.type(torch.DoubleTensor) # 将张量中的元素转换为指定类型(方法类)
张量data.double() # 将张量中的元素转换为指定类型(方法类)
# 和数组转换
# 数组到张量
torch.from_numpy(数组数据) #可以将 ndarray 数组转换为 Tensor,默认共享内存 使用 数组的.copy() 函数避免共享
torch.tensor(数组数据) #默认不共享内存
# 张量到数组
Tensor数据.numpy() #将张量转换为 ndarray 数组,但是共享内存 使用 数组的.copy() 函数避免共享
# 和标量数字的转换
torch.tensor(标量数字或列表) # 数字转张量
张量.item() # 张量转数字
3. 张量数值计算
python
#基本运算 也是元素运算
# 带下划线的版本会修改原数据(给到第一个张量)
# 加 +
张量.add(数或张量)
张量.add_(数或张量)
#减 -
张量.sub(数或张量)
张量.sub_(数或张量)
#乘 其他基本运算也可以同样的方法写 *
张量.mul(数或张量)
张量.mul_(数或张量)
张量1*数或张量2
torch.mul(张量1,张量2)
# 除 /
张量.div(数或张量)
张量.div_(数或张量)
# 取负
张量.neg()
张量.neg_()
#矩阵乘法
#输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
torch.matmul(data1, data2)
data1 @ data2
4. 张量运算函数
python
张量.mean(dim=0) #按列计算均值 不写dim求所有数的均值 tensor 必须为 Float 或者 Double 类型
张量.sum(dim=0) # 按列计算求和,不写dim求所有数的求和
# 下面内容也是元素运算
torch.pow(张量,n) # 求张量元素的n次方
张量.sqrt() # 求各元素的平方根
张量.exp() #求e为底,元素次方
张量.log() #每个元素的取对数,e为底
张量.log2() #每个元素的取对数,2为底
张量.log10() #每个元素的取对数,10为底
5. 张量索引操作
python
# 返回 (0, 1)、(1, 2) 两个位置的元素
print(data[[0, 1], [1, 2]])
# 返回 0、1 行的 1、2 列共4个元素
print(data[[[0], [1]], [1, 2]])
# 第三列大于5的行数据
print(data[data[:, 2] > 5])
# 其余的用法和numpy中数组索引一致
6. 张量形状操作
python
data.shape #获取张量的形状
data.size() #获取张量的形状,与numpy和pandas中的size属性不同(数字元素数量)
张量.reshape(形状号1,形状2) #在保证张量数据不变的前提下改变数据的形状
张量.view(形状号1,形状2) #修改张量的形状,只能用于存储在整块内存中的张量
张量.is_contiguous() #看张量 是否连续存储
张量.contiguous() #将张量变连续存储
张量.squeze() #删除形状为 1 的维度
张量.unsqueeze(dim=-1) #在指定维度添加形状为1的维度
torch.transpose(张量,维度索引1,维度索引2) #交换指定维度
张量.permute([交换后的维度索引号顺序]) #一次交换指定维度
7. 张量拼接操作
python
torch.cat([data1, data2], dim=1) #将两个张量根据指定的维度拼接起来,其他维度形状要一致
8. 自动微分模块
python
# 按常用流程书写的
w = 创建张量方法(requires_grad=True, dtype=torch.float32)#设置需求参数,requires_grad要不要计算梯度
z = x * w + b #所有内容都为张量
# 计算损失
loss = torch.nn.MSELoss()
loss = loss(z, y)
loss.backward() #反向传播,计算微分
w.grad #看梯度值
w.detach() #看w的值
9. 适用案例
使用该案例来模拟SGD回归的实现
python
import torch
from sklearn.datasets import make_regression
from torch.utils.data import TensorDataset,DataLoader
from torch import nn
from torch import optim
import matplotlib.pyplot as plt
# 构建数据集
def creat_data():
x,y,coef =make_regression(n_samples=100,n_features=1,coef=True,bias=1.5,noise=13)
return torch.tensor(x),torch.tensor(y),torch.tensor(coef)
x,y,coef = creat_data()
dataset=TensorDataset(x,y)
dataloader =DataLoader(dataset=dataset,batch_size=16,shuffle=True)
# 模型
model =nn.Linear(in_features=1,out_features=1)
# 设置损失和优化器
loss = nn.MSELoss()
optimizer = optim.SGD(params=model.parameters(),lr=0.001)
# 模型训练(循环)
loss_list=[]
train_loss = 0.0
iter_num = 0.
# 遍历每个轮次
for _ in range(100):
# 遍历每个批次
for train_x,train_y in dataloader:
# 模型预测
y_pred=model(train_x.type(torch.float32))
# 损失计算
loss_values = loss(y_pred,train_y.reshape(-1,1).type(torch.float32))
train_loss+=(loss_values.item())
iter_num+=len(train_y)
# 梯度清零
optimizer.zero_grad()
# 反向传播
loss_values.backward()
# 参数更新
optimizer.step()
loss_list.append(train_loss/(iter_num+0.001))
plt.plot(range(100),loss_list)
plt.grid()
plt.show()
plt.scatter(x,y)
x_list =torch.linspace(x.min(),x.max(),1000)
y_list = torch.tensor([coef*v + 1.5 for v in x_list])
y_list2 = torch.tensor([model.weight*v + model.bias for v in x_list])
plt.plot(x_list,y_list,'r')
plt.plot(x_list,y_list2,'g')
plt.grid()
plt.show()