文章目录
PyTorch框架认识
PyTorch是一个由Facebook人工智能研究院(FAIR)在2016年发布的开源深度学习框架,专为GPU加速的深度神经网络(DNN)编程而设计。它以其简洁、灵活和符合Python风格的特点,在科研和工业生产中得到了广泛应用。
1. Tensor张量
在PyTorch中,张量(Tensor)是核心数据结构,它是一个多维数组,用于存储和变换数据。张量类似于Numpy中的数组,但具有更丰富的功能和灵活性,特别是在支持GPU加速方面。
定义与特性
- 多维数组:张量可以看作是一个n维数组,其中n可以是任意正整数。它可以是标量(零维数组)、向量(一维数组)、矩阵(二维数组)或具有更高维度的数组。
- 数据类型统一:张量中的元素具有相同的数据类型,这有助于在GPU上进行高效的并行计算。
- 支持GPU加速:PyTorch中的张量可以存储在CPU或GPU上,通过将张量转移到GPU上,可以利用GPU的强大计算能力来加速深度学习模型的训练和推理过程。
创建方式
- 直接使用torch.tensor():根据提供的Python列表或Numpy数组创建张量。
- 下载数据集时:transform=ToTensor()直接将数据转化为Tensor张量类型。
2. 下载数据集
在PyTorch中,有许多封装了很多与图像相关的模型、数据集,那么如何获取数据集呢?
导入datasets模块:
from torchvision import datasets #封装了很多与图像相关的模型,数据集
以datasets模块中的MNIST数据集为例,包含70000张手写数字图像:60000张用于训练,10000张用于测试。图像是灰度的,28*28像素,并且居中的,以减少预处理和加快运行。
下载测试
我们来下载MNIST数据集:
from torchvision.transforms import ToTensor # 数据转换,张量,将其他类型数据转换为tensor张量 """-----下载训练集数据集-----""" training_data = datasets.MNIST( root="data", train=True,# 取训练集 download=True, transform=ToTensor(),# 张量,图片是不能直接传入神经网络模型的 ) # 对于pytorch库能够识别的数据,一般是tensor张量 """-----下载测试集数据集-----""" test_data = datasets.MNIST( root="data", train=False, download=True, transform=ToTensor(), )# numpy数组只能在CPU上运行,Tensor可以在GPU上运行,这在深度学习中可以显著提高计算速度
下载完成之后可在project栏查看。
展现下载内容
我们来查看部分图片(第59000张到第59009张):
"""-----展现手写字图片-----""" # tensor -->numpy 矩阵类型数据 from matplotlib import pyplot as plt figure = plt.figure() # 创建一个新的图形 for i in range(9): img,label = training_data[i+59000] #提取第59000张图片 figure.add_subplot(3,3,i+1) #图像窗口中创建多个小窗口,小窗口用于显示图片 plt.title(label) plt.axis("off")# 关闭当前轴的坐标轴 plt.imshow(img.squeeze(),cmap="gray") a = img.squeeze()# squeeze()从张量img中去掉维度为1的。如果该维度不为1则张量不会改变 plt.show()
图片信息获取时,得到的张量数据类型是这样的:
我们通过squeeze()函数,去掉维度为1的。这样我们就可以得到图片的高宽大小,将它展现出来:
3. 创建DataLoader(数据加载器)
在PyTorch中,创建DataLoader的主要作用是将数据集(Dataset)加载到模型中,以便进行训练或推理。DataLoader通过封装数据集,提供了一个高效、灵活的方式来处理数据。
DataLoader通过batch_size参数将数据集自动划分为多个小批次(batch),每一批次的放入模型训练,减少内存的使用,提高训练速度。
import torch from torch.utils.data import DataLoader """ 创建数据DataLoader(数据加载器) batch_size:将数据集分成多份,每一份为batch_size(指定数值)个数据。 优点:减少内存的使用,提高训练速度 """ train_dataloder = DataLoader(training_data,batch_size=64)# 64张图片为一个包 test_datalodar = DataLoader(test_data,batch_size=64) # 查看打包好的数据 for x,y in test_datalodar: #x是表示打包好的每一个数据包 print(f"Shape of x [N, C, H, W]:{
x.shape}") print(f"Shape of y:{
y.shape} {
y.dtype}") break ----------------------- Shape of x [N, C, H, W]:torch.Size([64, 1, 28, 28]) Shape of y:torch.Size([64]) torch.int64
4. 选择处理器
我们知道,电脑中的处理器有CPU和GPU两种,CPU擅长执行复杂的指令和逻辑操作,而GPU则擅长处理大量并行计算任务。
所以,在可以的条件下,我们选择使用GPU处理器来学习深度学习,因为计算量比较大:
"""---判断当前设备是否支持GPU,其中mps是苹果m系列芯片的GPU""" device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" print(f"Using {
device} device") ---------------- Using cuda device
5. 神经网络模型
通过调用类的形式来使用神经网络,神经网络的模型:nn.module。
构建模型
我们在构建时,得明确神经网络模型的结构:输入层–隐藏层–输出层,而在每一个隐藏层进入下一层时,都会有一个激活函数计算,所以我们也按着这个架构层次定义函数:
class NeuralNetwork(nn.Module): #通过调用类的形式来使用神经网络,神经网络的模型:nn.module def __init__(self): # self类自己本身 super().__init__() #继承的父类初始化 self.flatten = nn.Flatten()# 输入层,展开一个对象flatten self.hidden1 = nn.Linear(28*28,256)# 隐藏层,第1个参数:有多少神经元传入进来;第二个参数,有多少数据传出去 self.hidden2 = nn.Linear(256,128) self.hidden3 = nn.Linear(128,64) self.hidden4 = nn.Linear(64,32) self.out = nn.Linear(32,10)#输出层,输出必须与类别数量相同,输入必须是上一层的个数 def forward(self,x): #前向传播(该名字不要轻易改),告诉它数据的流向 x = self.flatten(x) x = self.hidden1(x) x = torch.sigmoid(x) #激活函数 x = self.hidden2(x) x = torch.sigmoid(x) x = self.hidden3(x) x = torch.sigmoid(x) x = self.hidden4(x) x = torch.sigmoid(x) x = self.out(x) return x model = NeuralNetwork().to(device) #将刚刚创建的模型传入到GPU print(model) ----------------------- NeuralNetwork( (flatten): Flatten(start_dim=1, end_dim=-1) (hidden1): Linear(in_features=784, out_features=256, bias=True) (hidden2): Linear(in_features=256, out_features=128, bias=True) (hidden3): Linear(in_features=128, out_features=64, bias=True) (hidden4): Linear(in_features=64, out_features=32, bias=True) (out): Linear(in_features=32, out_features=10, bias=True) )
6. 训练数据
训练数据时,需要注意的参数:
- optimizer优化器:
在PyTorch中,创建Optimizer的主要作用是管理并更新模型中可学习参数(即权重和偏置)的值,以便最小化某个损失函数(loss function)。
- 梯度清零:在每次迭代开始时,Optimizer会调用.zero_grad()方法来清除之前累积的梯度,这是因为在PyTorch中,梯度是累加的,如果不清零,则下一次的梯度计算会包含前一次的梯度,导致错误的更新。
- 梯度计算:在模型进行前向传播(forward pass)和损失计算之后,Optimizer并不直接参与梯度的计算。梯度的计算是通过调用损失函数的.backward()方法完成的,该方法会计算损失函数关于模型中所有可学习参数的梯度,并将这些梯度存储在相应的参数对象中。
- 参数更新:在梯度计算完成后,Optimizer会调用.step()方法来根据计算得到的梯度以及选择的优化算法(如SGD、Adam等)来更新模型的参数。这一步骤是优化过程中最关键的部分,它决定了模型学习的方向和速度。
optimizer = torch.optim.Adam(model.parameters(),lr=0.001)
- loss_fn损失函数:
在PyTorch中,nn.CrossEntropyLoss()是一个常用的损失函数,它结合了 nn.LogSoftmax() 和 nn.NLLLoss()(负对数似然损失)在一个单独的类中。
loss_fn = nn.CrossEntropyLoss()
训练集数据
from torch import nn #导入神经网络模块 def train(dataloader,model,loss_fn,optimizer): model.train()# 设置模型为训练模式 batch_size_num =1# 迭代次数 for x,y in dataloader: x,y = x.to(device),y.to(device) # 将数据和标签发送到指定设备 pred = model.forward(x) # 前向传播 loss = loss_fn(pred,y) # 计算损失 optimizer.zero_grad() # 清除之前的梯度 loss.backward() # 反向传播 optimizer.step() # 更新模型参数 loss_value = loss.item() # 获取损失值 if batch_size_num %200 == 0: # 每200次迭代打印一次损失 print(f"loss:{
loss_value:>7f} [number:{
batch_size_num}]") batch_size_num += 1 ------------------------ loss:1.039446 [number:200] loss:0. [number:400] loss:0. [number:600] loss:0. [number:800]
测试集数据
def test(dataloader,model,loss_fn): size = len(dataloader.dataset) # 获取测试集的总大小。 num_batches = len(dataloader) # 计算数据加载器中的批次数量。 model.eval() # 将模型设置为评估模式。 test_loss,correct = 0,0 # 初始化总损失和正确预测的数量。 with torch.no_grad(): for x,y in dataloader: x,y = x.to(device),y.to(device) pred = model.forward(x) test_loss += loss_fn(pred,y).item() correct += (pred.argmax(1) == y).type(torch.float).sum().item() a = (pred.argmax(1) == y) b = (pred.argmax(1) == y).type(torch.float) test_loss /= num_batches correct /= size correct = round(correct, 4) print(f"Test result: \n Accuracy:{
(100*correct)}%,Avg loss:{
test_loss}") --------------------- Test result: Accuracy:89.96%,Avg loss:0.092506
我们可以看到,这个模型的正确率不是特别的高,那么接下来我们来提高模型的学习率。
7. 提高模型学习率
遍历了指定的训练周期(epochs)数,并在每个周期中调用 train 函数来训练模型。
"""-----调整学习率-----""" epochs = 10 for t in range(epochs): print(f"Epoch {
t+1} \n-------------------------") train(train_dataloder,model,loss_fn,optimizer) print("Done!") test(test_datalodar,model,loss_fn) --------------- 仅展示优化后的结果: Test result: Accuracy:97.001%,Avg loss:0.
总结
本篇介绍了:
- PyTorch的框架
- 数据类型张量,数据集的获取
- 如何构建对应神经网络的模型
- 如何优化算法:一、修改optimizer优化器的算法;二、遍历合适的训练周期(epochs)数
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rgzn-ptkj/5027.html