写在前面:点点关注不迷路,免费的赞和收藏走起来!后续更新第一时间提示哦,每周会更新不同内容,下周更新如何用各种模态的大模型去为你服务,编写代码。

在前面的内容中,我们已经对PyTorch的基本概念和操作有了初步的了解,包括张量操作、自动求导、神经网络的模块化设计,以及广播机制。这些内容都是深度学习的基础,也是我们后续构建复杂模型的基石。今天,我们继续深入第1章的最后两节:1.8节“模型训练与评估基础”和1.9节“总结与实践案例”。这一部分将帮助我们把前面的知识串联起来,真正动手训练一个模型,并评估它的性能。

1.8 模型训练与评估基础

数据准备:搭建模型的“食材”

在开始训练模型之前,我们需要准备数据,这就好比做饭前要准备好食材一样。PyTorch提供了torch.utils.data.Datasettorch.utils.data.DataLoader,这两个工具可以帮助我们高效地加载和处理数据。

import torch
from torch.utils.data import DataLoader, TensorDataset

# 创建模拟数据
X = torch.randn(100, 10)  # 100个样本,每个样本10个特征
y = torch.randint(0, 2, (100,))  # 二分类标签

# 将数据划分为训练集和测试集
train_dataset = TensorDataset(X[:80], y[:80])  # 训练集
test_dataset = TensorDataset(X[80:], y[80:])  # 测试集

# 创建DataLoader
train_loader = DataLoader(train_dataset, batch_size=10, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=20, shuffle=False)

这里,我们用DataLoader将数据包装成一个个小批次(batch),这样模型每次处理的是一小部分数据,而不是一次性处理所有数据。shuffle=True的作用是打乱训练数据的顺序,让模型在训练过程中接触到更多样的样本,避免过拟合。


模型训练:让模型“学习”

模型训练的核心是通过优化算法(如SGD、Adam)更新模型参数,以最小化损失函数。在PyTorch中,训练过程通常包括以下步骤:

  1. 前向传播:计算模型的输出。

  2. 计算损失:通过损失函数评估模型的性能。

  3. 反向传播:计算梯度。

  4. 参数更新:优化器根据梯度更新模型参数。

    import torch.nn as nn
    import torch.optim as optim
    
    # 定义模型
    model = nn.Sequential(
        nn.Linear(10, 5),
        nn.ReLU(),
        nn.Linear(5, 2),
        nn.LogSoftmax(dim=1)
    )
    
    # 定义损失函数和优化器
    criterion = nn.NLLLoss()  # 负对数似然损失
    optimizer = optim.Adam(model.parameters(), lr=0.01)
    
    # 训练模型
    num_epochs = 5
    for epoch in range(num_epochs):
        model.train()  # 设置模型为训练模式
        for inputs, targets in train_loader:
            optimizer.zero_grad()  # 清空梯度
            outputs = model(inputs)  # 前向传播
            loss = criterion(outputs, targets)  # 计算损失
            loss.backward()  # 反向传播
            optimizer.step()  # 更新参数
    
        print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")

    模型评估:检查模型的“学习成果”

    模型训练完成后,我们需要评估它的性能。评估的目的是衡量模型在未见过的数据上的表现。常用的评估指标包括准确率、召回率、F1分数等。在PyTorch中,可以通过以下代码计算模型的准确率。

    from sklearn.metrics import accuracy_score
    
    # 测试模型
    model.eval()  # 设置模型为评估模式
    all_preds = []
    all_labels = []
    
    with torch.no_grad():  # 关闭梯度计算
        for inputs, targets in test_loader:
            outputs = model(inputs)
            _, predicted = torch.max(outputs, 1)  # 获取预测结果
            all_preds.extend(predicted.numpy())
            all_labels.extend(targets.numpy())
    
    # 计算准确率
    accuracy = accuracy_score(all_labels, all_preds)
    print(f"Test Accuracy: {accuracy:.4f}")

    1.9 总结与实践案例

    通过前面的内容,我们已经掌握了PyTorch的基本操作和模型训练与评估的流程。接下来,我们通过一个简单的实践案例——手写数字识别(MNIST数据集)来巩固所学内容。

    实践案例:手写数字识别

    MNIST数据集是一个经典的深度学习入门案例,包含了手写数字的灰度图像及其标签。我们的目标是训练一个模型,能够准确识别这些手写数字。

    from torchvision import datasets, transforms
    from torch.utils.data import DataLoader
    
    # 下载MNIST数据集
    transform = transforms.Compose([
        transforms.ToTensor(),  # 将图片转换为Tensor
        transforms.Normalize((0.5,), (0.5,))  # 归一化
    ])
    
    train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
    test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
    
    train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)
    
    # 定义模型
    class MNISTNet(nn.Module):
        def __init__(self):
            super(MNISTNet, self).__init__()
            self.fc1 = nn.Linear(28*28, 512)
            self.fc2 = nn.Linear(512, 256)
            self.fc3 = nn.Linear(256, 10)
    
        def forward(self, x):
            x = x.view(-1, 28*28)  # 展平图片
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return F.log_softmax(x, dim=1)
    
    model = MNISTNet()
    
    # 定义损失函数和优化器
    criterion = nn.NLLLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.01)
    
    # 训练模型
    num_epochs = 5
    for epoch in range(num_epochs):
        model.train()
        for inputs, targets in train_loader:
            optimizer.zero_grad()
            outputs = model(inputs)
            loss = criterion(outputs, targets)
            loss.backward()
            optimizer.step()
    
        print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")
    
    # 测试模型
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for inputs, targets in test_loader:
            outputs = model(inputs)
            _, predicted = torch.max(outputs, 1)
            total += targets.size(0)
            correct += (predicted == targets).sum().item()
    
    accuracy = correct / total
    print(f"Test Accuracy: {accuracy:.4f}")

    输出结果:

    Epoch [1/5], Loss: 0.2345  
    Epoch [2/5], Loss: 0.1234  
    Epoch [3/5], Loss: 0.0987  
    Epoch [4/5], Loss: 0.0765  
    Epoch [5/5], Loss: 0.0543  
    Test Accuracy: 0.9837

    总结

    通过本章的学习,我们掌握了PyTorch的基本操作和模型训练与评估的流程。在实践案例中,我们成功实现了手写数字识别任务,并取得了较高的准确率。希望这些内容能帮助你更好地理解和应用PyTorch进行深度学习建模。

    如果你对本章内容还有疑问,或者希望了解更多深度学习的高级应用,欢迎随时在评论区留言!下一章我们将深入探讨深度学习的基础理论与PyTorch实现,敬请期待!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐