【实战教程】PyTorch初学者指南:基本概念、数据处理、模型训练集评估
《------往期经典推荐------》
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
《------正文------》
目录
引言
如果你想知道如何构建和训练深度学习模型,PyTorch是你可以使用的最初学者友好和强大的框架之一。在本中,我们不仅要构建一个项目,还要深入研究PyTorch的概念,解释每一行代码及其意义。
我们将处理的项目是使用著名的MNIST数据集的数字分类器,本文将训练一个简单的神经网络来识别手写数字(0-9)。最后,您将了解PyTorch的核心思想,以及它们如何结合在一起,从而使深度学习变得高效。
为什么是PyTorch?
在进入项目之前,让我们来谈谈为什么PyTorch已经成为许多研究人员和开发人员的首选框架:
- 动态计算图:与TensorFlow的早期版本不同,PyTorch在运行时动态构建计算图。这意味着您可以使用标准Python工具调试模型,使其非常直观。
- Pythonic Python:PyTorch与Python无缝集成,使任何熟悉该语言的人都易于学习和使用。
- 多功能性:PyTorch支持从小规模原型到大规模生产的一系列任务,并且可以轻松处理CPU和GPU。
- 强大的社区:PyTorch是开源的,其充满活力的社区已经开发了无数的库和教程来帮助您入门。
项目名称:Digit Classification
在这个项目中,我们将:
- 构建一个简单的前馈神经网络。
- 在MNIST数据集上训练它来分类手写数字。
- 测试模型在未知数据上的性能。
- 保存训练好的模型以供重用。
我们将涵盖从加载数据到优化模型的过程的每一个细节。
步骤1:配置环境
首先,您需要安装PyTorch和Torchvision(用于处理数据集)。您可以使用pip安装它们:
pip install torch torchvision
验证安装:
import torch
print(torch.__version__)
如果没有错误发生,就可以开始了!
步骤2:数据集介绍
MNIST数据集包括:
- 60000张训练图像和10000张测试图像
- 每个图像是28 x28像素,代表一个手写数字。
- 每个图像都是灰度的,这意味着它只有一个颜色通道。
- 标签是从0到9的整数。
步骤3:加载MNIST数据集
为了处理数据集,PyTorch提供了torchvision库。这个库包括用于加载和预处理数据的实用程序。
关键方法
- transforms:应用于数据的预处理步骤(例如,标准化,n)。
- DataLoader:一个PyTorch类,用于批处理和混洗数据以进行有效的训练。
让我们加载MNIST数据集并对其进行预处理:
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# Transformations: This step here converts images to tensors and normalize pixel values
transform = transforms.Compose([
transforms.ToTensor(), # Converts image to tensor
transforms.Normalize((0.5,), (0.5,)) # Normalizes pixel values to (-1, 1)
])
# Loads training and testing datasets
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
# Creates DataLoaders for batching and shuffling
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
解释说明:
transforms.ToTensor()
:将图像转换为形状为(1,28,28)的
PyTorch张量,并将像素值缩放到范围[0,1]
。transforms.Normalize((0.5,), (0.5,))
:通过减去平均值(0.5)并除以标准差(0.5)将像素值调整到范围[-1,1]
。- DataLoader:自动对数据进行批处理(这里每批64张图像),并对训练数据集进行洗牌以防止过度拟合。
步骤4:构建神经网络
神经网络通过多层互连的神经元处理数据。下面是我们要构建的架构:
- 输入层:采用28 x28扁平化输入(784个值)。
- 隐藏层:包含权重、偏置和激活函数的中间层。
- 输出层:生成10个类的概率(数字0-9)。
让我们在PyTorch中定义模型:
import torch.nn as nn
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128) # Input to hidden
self.relu = nn.ReLU() # Activation function
self.fc2 = nn.Linear(128, 64) # Hidden to hidden
self.fc3 = nn.Linear(64, 10) # Hidden to output
self.softmax = nn.Softmax(dim=1) # Convert outputs to probabilities
def forward(self, x):
x = x.view(-1, 28 * 28) # Flatten the 28x28 image
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return self.softmax(x)
逐层解释
**nn.线性**
:应用y=Wx+by = Wx + by =Wx+B的全连接层。- ReLU(Rectified Linear Unit):引入非线性,使模型能够学习复杂的模式。
- Softmax:将输出转换为概率,其中所有类的和等于1。
步骤5:训练模型
为了训练模型,我们需要:
- 损失函数:测量预测与实际标签的距离。我们将使用
CrossEntropyLoss
,通常用于分类任务。 - 优化器:更新模型权重以最小化损失。我们将使用
Adam
,它结合了SGD的优点和自适应学习率。
下面是训练代码:
import torch.optim as optim
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = SimpleNN().to(device)
criterion = nn.CrossEntropyLoss() # Loss function
optimizer = optim.Adam(model.parameters(), lr=0.001) # Optimizer
epochs = 5
for epoch in range(epochs):
model.train() # Setting the model to training mode
running_loss = 0.0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad() # Reset gradients
outputs = model(images) # Forward pass
loss = criterion(outputs, labels) # Compute loss
loss.backward() # Backward pass
optimizer.step() # Update weights
running_loss += loss.item()
print(f"Epoch [{epoch+1}/{epochs}], Loss: {running_loss/len(train_loader):.4f}")
解释说明:
- Forward Pass:数据流经网络以生成预测。
- 损失计算:将预测与实际标签进行比较。
- 反向传递:计算权重相对于损失的梯度。
- 权重更新:优化器调整权重以最小化损失。
本步骤中的概念解释
1.安装和设置优化器:
import torch.optim as optim
- ***什么是优化器?***优化器是PyTorch中的一种工具,它在训练过程中调整模型的权重,以最小化损失函数(即,使模型更好地完成任务)。可以将其视为更新模型中的“旋钮”以提高性能的机制。
- ***为什么
选择Torch.Optim
?***PyTorch提供torch.optim
模块,其中包括常用的优化器,如SGD、Adam和RMSprop。
2.设置device:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
- ***为什么要检查
CUDA
?***此行检查GPU(支持CUDA)是否可用。如果是,则将设备
设置为GPU(cuda
);否则,默认为CPU。 - ***我们为什么需要这个?***GPU在深度学习任务中比CPU快得多。但是,如果GPU不可用,代码仍将在CPU上运行而不会崩溃。
3.初始化模型、损失函数和优化器:
model = SimpleNN().to(device)
*SimpleNN()*
创建了我们之前定义的神经网络的一个实例。*.to(device)*
将模型移动到GPU(如果可用)。这是必要的,因为在训练期间,模型和数据都需要在同一个设备上。
criterion = nn.CrossEntropyLoss() # Loss function
- **什么是损失函数?**损失函数衡量模型的预测与实际标签的距离。这是模型在训练过程中用来改进的信号。
- 为什么
选择CrossEntropyLoss
? *CrossEntropyLoss*
通常用于分类问题,其中输出是多个类的概率分布(如MNIST中的数字分类)。- 它结合了LogSoftmax(将模型输出转换为概率)和负对数似然损失(惩罚错误的预测)。
optimizer = optim.Adam(model.parameters(), lr=0.001)
- **Adam是什么?**Adam(Adaptive Moment Estimation的缩写)是一个高级优化器。它动态调整每个参数的学习率,使其既快速又高效。
- **为什么要传递
model.parameters()
?**优化器需要知道在训练过程中要更新哪些参数(权重和偏置)。model.parameters()
提供了这些信息。 - **学习率(
lr
):**学习率决定了更新模型参数时步长的大小。较小的学习率意味着更精确,但更慢的训练。
4.重置参数:
optimizer.zero_grad()
- **为什么要把所有的梯度都归零?**在PyTorch中,默认情况下,梯度(用于更新权重)会累积。如果我们在每个批处理开始时不清除它们,它们将干扰新的梯度,导致不正确的更新。
5.训练的核心:
a)前向传递(输出=模型(图像)
):
- 输入数据(一批图像)通过模型传递。
- 每一层都使用其权重和偏置来处理数据,最终产生一个输出(logits)。此输出表示模型对每个类的预测。
B)计算损失( loss = criterion(outputs, labels)
):
- 使用损失函数(例如,
CrossEntropyLoss
)。 - 损失量化了预测与地面事实的距离。损耗越高,性能越差;损耗越低,性能越好。
(c)反向传递(loss.backward()
):
- 该步骤使用反向传播计算损失相对于模型参数(权重和偏差)的梯度(偏导数)。
- 参数表示为减少损失而需要对每个参数进行的改变的方向和幅度。
d)参数更新(optimizer.step()
):
- 优化器使用计算的梯度来调整模型的参数。此步骤微调权重和偏差,以改善模型对下一批的预测。
- 例如,在Adam优化器中,这涉及到基于学习率和动量项更新参数。
步骤6:模型评估
测试评估了模型在看不见的数据上的准确性。代码如下:
model.eval() # Setting the model to evaluation mode
correct = 0
total = 0
with torch.no_grad(): # Disabling gradient computation
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1) # Getting the class with highest score
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"Test Accuracy: {100 * correct / total:.2f}%")
步骤7:保存并加载模型
保存训练好的模型以备将来用途:
torch.save(model.state_dict(), 'simple_nn.pth')
加载保存的模型:
model.load_state_dict(torch.load('simple_nn.pth'))
model.eval()
理解概念
- 张量:PyTorch表示数据的方式,类似于NumPy数组,但针对GPU进行了优化。
- Autograd:自动计算反向传播的梯度。
- 模块:可重用组件,如层(
nn.Linear
)和激活(nn.ReLU
)。 - DataLoader:有效地处理重排序和洗牌。
- 设备管理:在CPU和GPU之间无障碍切换。
结论
这个项目是理解PyTorch的基础步骤。通过构建这个简单的数字分类器,您已经学会了如何:
- 加载和预处理数据。
- 构建和训练神经网络。
- 评估和保存模型。
你在这里掌握的基础知识将为你探索更高级的主题,如卷积神经网络(CNN),递归神经网络(RNN)或Transformer。
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!
原文地址:https://blog.csdn.net/qq_42589613/article/details/144329263
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!