Pytorch官网tutorial快速入门教程(1)Quickstart

Quickstart的网址:点击进入
以下是内容笔记和相关翻译:

快速开始

本节介绍了机器学习中常见任务的API。请参阅各部分中的链接,以深入了解更多内容。

数据处理

PyTorch提供了两个基本工具来处理数据:torch.utils.data.DataLoader和torch.utils.data.Dataset。Dataset用于存储样本及其对应的标签,而DataLoader则将其包装成可迭代对象

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

PyTorch提供了面向特定领域的库,例如TorchText、TorchVision和TorchAudio,其中包括很多数据集。在本教程中,我们将使用TorchVision数据集。

torchvision.datasets模块包含许多真实世界视觉数据集,例如CIFAR、COCO(完整列表在此)。在本教程中,我们将使用FashionMNIST数据集。每个TorchVision数据集都包含两个参数:transform和target_transform,分别用于修改样本和标签。

# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data", #指定数据集的本地保存路径为"data"文件夹。
    train=True, #表示下载训练数据集。
    download=True, #表示从网络上下载数据集
    transform=ToTensor(), #将每个图像样本转换为PyTorch张量=
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False, #与训练数据集不同的是,这里的train参数设置为False,表示下载测试数据集。
    download=True,
    transform=ToTensor(),
)

在下载完数据后,training_data和test_data变量中存储的是FashionMNIST类型的数据集对象,其中包含图像数据(转换为PyTorch张量)和对应的标签。这样就可以将数据用于后续的模型训练和测试中。

我们将Dataset作为参数传递给DataLoader。DataLoader通过对数据集进行包装,创建了一个可迭代对象,支持自动批处理、采样、洗牌和多进程数据加载。在这里,我们定义了批处理大小为64,也就是说,迭代器中的每个元素将返回一个包含64个特征和标签的批次。

batch_size = 64

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")
    break

创建模型

为了在PyTorch中定义一个神经网络,我们创建一个继承自nn.Module的类。我们在_ _init_ _函数中定义网络的层,并在forward函数中指定数据如何通过网络传递。为了加速神经网络的操作,我们可以将其移动到GPU或者MPS(如果可用)上执行。

# Get cpu, gpu or mps device for training.
device = (
    "cuda"
    if torch.cuda.is_available()  # 如果GPU可用,则使用GPU
    else "mps"
    if torch.backends.mps.is_available()  # 如果MPS可用,则使用MPS
    else "cpu"  # 否则使用CPU
)
print(f"Using {device} device")  # 打印使用的设备

# Define model
class NeuralNetwork(nn.Module):  # 创建一个继承自nn.Module的神经网络类
    def __init__(self):  # 实现神经网络的构造函数
        super().__init__()  # 继承父类的构造函数
        self.flatten = nn.Flatten()  # 创建一个Flatten层,用于将图像展开成一维向量
        self.linear_relu_stack = nn.Sequential(  # 创建一个nn.Sequential对象,用于包装一组线性层、ReLU激活函数层和Dropout层
            nn.Linear(28*28, 512),  # 输入层(28*28维)到隐层(512维)的线性变换层
            nn.ReLU(),  # 隐层的激活函数,使用ReLU
            nn.Linear(512, 512),  # 隐层到输出层的线性变换层
            nn.ReLU(),  # 输出层的激活函数,使用ReLU
            nn.Linear(512, 10)  # 最后一层是输出层,有10个输出单元,对应10个数字的类别
        )

    def forward(self, x):  # 实现神经网络的正向传播函数,即前向计算过程
        x = self.flatten(x)  # 将输入张量展开成一维张量
        logits = self.linear_relu_stack(x)  # 将展开后的向量经过神经网络的所有层,得到最终的输出向量
        return logits  # 返回输出向量

# Move model to the selected device
model = NeuralNetwork().to(device)  # 创建一个神经网络的实例,并将其移动到指定的设备上执行
print(model)  # 打印神经网络的结构信息

在代码中,NeuralNetwork类继承自nn.Module,通过重写init方法和forward方法定义了一个简单的神经网络模型。这个模型包含了一个flatten层用于将输入图片展平成一维向量,以及一个由三个线性层和ReLU激活函数组成的linear_relu_stack序列层。这个神经网络模型可以通过调用to(device)方法将模型移动到指定的设备上执行。

优化模型参数

为了训练一个模型,我们需要一个损失函数和一个优化器。

loss_fn = nn.CrossEntropyLoss() #这行代码创建了一个交叉熵(CrossEntropy)损失函数的实例,用于度量模型输出与真实标签之间的差异。交叉熵损失函数通常用于多分类问题的训练,它可以帮助我们评估模型在给定输入上的预测的准确性。
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3) #这行代码创建了一个随机梯度下降(Stochastic Gradient Descent,SGD)优化器的实例。model.parameters()表示获取模型中所有需要优化的参数,然后将其传递给优化器。lr=1e-3表示学习率的设置,即优化器在每次更新参数时应该乘以的比例因子。学习率决定了参数更新的速度和方向。

在单个训练循环中,模型对训练数据集进行预测(按批次输入),然后通过反向传播将预测误差反馈给模型的参数以进行调整。

def train(dataloader, model, loss_fn, optimizer): #这段代码是一个训练函数,用于在给定数据集、模型、损失函数和优化器的情况下执行训练过程
    size = len(dataloader.dataset)  # 获取数据集的大小,用来计算进度
    model.train()  # 将模型设置为训练模式
    for batch, (X, y) in enumerate(dataloader):  # 遍历数据集的批次,其中batch是当前批次的索引,X是输入数据,y是对应的真实标签。
        X, y = X.to(device), y.to(device)  # 将数据和标签转移到设备上(如GPU)

        # Compute prediction error
        pred = model(X)  # 输入数据进行前向传播,得到预测结果
        loss = loss_fn(pred, y)  # 计算预测结果与真实标签之间的损失

        # Backpropagation
        loss.backward()  # 反向传播,计算损失相对于模型参数的梯度
        optimizer.step()  # 根据梯度更新模型参数
        optimizer.zero_grad()  # 清零梯度,为下一次迭代做准备

        if batch % 100 == 0:  # 每经过100个批次输出一次训练进度和损失
            loss, current = loss.item(), (batch + 1) * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")

我们还要对模型在测试数据集上的性能进行评估,以确保模型的学习效果。

def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset) #这行代码获取了测试数据集的大小,用于计算评估指标时的归一化。
    num_batches = len(dataloader) #这行代码获取了测试数据集的批次数量,用来计算平均测试损失。
    model.eval() # 这行代码将模型设置为评估模式,以便在评估过程中禁用特定的训练行为(如Dropout)。
    test_loss, correct = 0, 0 #这行代码初始化测试损失和正确预测数为0。
    with torch.no_grad(): # 这个上下文管理器指定在评估过程中不需要计算梯度,以节省内存和计算资源。
        for X, y in dataloader: # 遍历测试数据集
            X, y = X.to(device),  y.to(device)  # 将数据和标签转移到设备上(如GPU)
            pred = model(X)  # 输入数据进行前向传播,得到预测结果
            test_loss += loss_fn(pred, y).item() # 计算预测结果与真实标签之间的损失
            correct += (pred.argmax(1) == y).type(torch.float).sum().item() # 统计正确预测的数量,通过将预测结果与真实标签比较,并将结果转换为浮点型后求和。
    test_loss /= num_batches # 计算预测结果与真实标签之间的损失,将测试损失除以批次数量。
    correct /= size # 计算正确预测的比例,将正确预测的数量除以测试数据集的大小。
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n") #这行代码将测试过程中的评估指标进行打印输出,包括准确率(以百分数形式显示)和平均测试损失。

训练过程进行了多个迭代(epochs)。在每个epoch中,模型学习参数以做出更好的预测。我们在每个epoch打印模型的准确率和损失;我们希望看到准确率增加,损失减少。

epochs = 5 #设置了总共的训练迭代次数为5。
for t in range(epochs): #使用range(epochs)创建了一个从0到(epochs-1)的迭代器,用于遍历每个epoch。
    print(f"Epoch {t+1}\n-------------------------------") #这行代码打印当前epoch的编号,并打印分隔线。
    train(train_dataloader, model, loss_fn, optimizer) #这行代码调用了train函数来进行模型的训练,使用了训练数据集train_dataloader、模型model、损失函数loss_fn和优化器optimizer。
    test(test_dataloader, model, loss_fn) # 这行代码调用了test函数来对模型进行评估,使用了测试数据集test_dataloader、模型model和损失函数loss_fn。
print("Done!") #所有的epochs迭代结束后,打印"Done!"表示训练过程完成。

保存模型

torch.save(model.state_dict(), "model.pth")
print("Saved PyTorch Model State to model.pth")

加载模型

model = NeuralNetwork().to(device)
model.load_state_dict(torch.load("model.pth"))
classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
] #这段代码定义了一个包含了10个类别标签的列表,用于将模型的预测结果转换为具体的类别。
model.eval() #这行代码将模型设置为评估模式。在评估模式下,模型的参数不会被更新,并且会更节省内存。
x, y = test_data[0][0], test_data[0][1] #这行代码从测试数据集中获取第一个样本的输入特征(x)和对应的真实标签(y)。
with torch.no_grad(): #语句块内的代码将在不进行梯度计算的情况下运行。
    x = x.to(device)
    pred = model(x) #这行代码将输入特征传递给模型进行预测,得到预测结果。
    predicted, actual = classes[pred[0].argmax(0)], classes[y]#这行代码将预测结果转换为具体的类别标签。
    print(f'Predicted: "{predicted}", Actual: "{actual}"') #这行代码打印预测的类别和真实的类别。使用
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值