PyTorch 神经网络基础

PyTorch 神经网络基础

本教程聚焦于使用 PyTorch 构建和训练神经网络的基础,涵盖 torch.nn 模块、模型定义、前向传播、损失函数、优化器和训练流程。内容简洁实用,适合初学者或需要快速复习的用户。以下假设你已安装 PyTorch(参考 PyTorch 官网)并了解张量和自动求导基础。


1. 核心概念

PyTorch 的神经网络构建主要依赖 torch.nn 模块,结合 torch.optimtorch.utils.data 实现模型训练。核心组件包括:

  • 模型:继承 nn.Module 定义网络结构。
  • 前向传播:通过 forward 方法定义数据流。
  • 损失函数:衡量模型输出与真实标签的差异(如 nn.CrossEntropyLoss)。
  • 优化器:更新模型参数(如 optim.SGDoptim.Adam)。
  • 数据加载:使用 DataLoader 高效处理批量数据。

2. 定义神经网络

通过继承 nn.Module,可以灵活定义神经网络。

示例:简单全连接网络

import torch
import torch.nn as nn

class SimpleNN(nn.Module):
    def __init__(self, input_size=10, hidden_size=5, output_size=2):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)  # 第一层全连接
        self.relu = nn.ReLU()                          # 激活函数
        self.fc2 = nn.Linear(hidden_size, output_size) # 第二层全连接

    def forward(self, x):
        x = self.relu(self.fc1(x))  # 前向传播:输入 -> 隐藏层 -> ReLU -> 输出
        x = self.fc2(x)
        return x

# 实例化模型
model = SimpleNN()
print(model)
  • 说明
  • nn.Module:所有神经网络的基类,提供参数管理和前向传播。
  • nn.Linear(in_features, out_features):全连接层,计算 y = Wx + b
  • forward 方法:定义数据如何通过网络。

3. 数据准备

使用 torch.utils.data 模块加载和处理数据。

示例:创建模拟数据集

from torch.utils.data import DataLoader, TensorDataset

# 模拟数据:100 个样本,10 维特征,2 类标签
X = torch.randn(100, 10)
y = torch.randint(0, 2, (100,))
dataset = TensorDataset(X, y)
loader = DataLoader(dataset, batch_size=32, shuffle=True)

# 检查数据
for data, target in loader:
    print(data.shape, target.shape)  # [32, 10], [32]
    break
  • 关键点
  • TensorDataset:将特征和标签配对。
  • DataLoader:支持批量加载、打乱数据和多线程。

4. 训练神经网络

训练包括前向传播、计算损失、反向传播和参数更新。

示例:训练流程

import torch.optim as optim

# 初始化模型、损失函数和优化器
model = SimpleNN()
criterion = nn.CrossEntropyLoss()  # 分类任务的损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 移动到 GPU(如果可用)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)

# 训练循环
for epoch in range(5):  # 5 个 epoch
    running_loss = 0.0
    for data, target in loader:
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()      # 清零梯度
        output = model(data)       # 前向传播
        loss = criterion(output, target)  # 计算损失
        loss.backward()            # 反向传播
        optimizer.step()           # 更新参数
        running_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {running_loss / len(loader)}")
  • 关键步骤
  1. 清零梯度optimizer.zero_grad() 防止梯度累积。
  2. 前向传播:通过 model(data) 获取预测。
  3. 计算损失:使用损失函数比较预测和真实值。
  4. 反向传播loss.backward() 计算梯度。
  5. 更新参数optimizer.step() 调整模型权重。

5. 常用组件

损失函数

  • nn.MSELoss:均方误差,用于回归任务。
  • nn.CrossEntropyLoss:交叉熵损失,用于分类任务(包含 softmax)。
  • nn.BCELoss:二元交叉熵,用于二分类。

优化器

  • optim.SGD:随机梯度下降,支持动量。
  • optim.Adam:自适应优化器,适合大多数任务。
  • optim.RMSprop:适合非平稳目标。

激活函数

  • nn.ReLU:max(0, x),增加非线性。
  • nn.Sigmoid:输出 [0, 1],用于二分类。
  • nn.Softmax:输出概率分布(通常与 CrossEntropyLoss 一起使用)。

6. 模型评估

推理时,使用 model.eval() 切换到评估模式,禁用 Dropout 和 BatchNorm 的训练行为。

model.eval()
with torch.no_grad():  # 禁用梯度计算
    test_data = torch.randn(10, 10).to(device)
    predictions = model(test_data)
    print(predictions)

7. 保存和加载模型

# 保存模型参数
torch.save(model.state_dict(), 'model.pth')

# 加载模型参数
model = SimpleNN().to(device)
model.load_state_dict(torch.load('model.pth'))
model.eval()

8. 进阶提示

  • 卷积神经网络(CNN):使用 nn.Conv2d 构建图像处理模型。
  • 循环神经网络(RNN):使用 nn.LSTMnn.GRU 处理序列数据。
  • 预训练模型:通过 torchvision.models 加载 ResNet、VGG 等。
  • 调试:使用 torchsummary 查看模型结构,或打印 model.parameters() 检查权重。

9. 资源

  • 官方文档:https://pytorch.org/docs/stable/nn.html
  • 教程:https://pytorch.org/tutorials/beginner/basics/buildmodel_tutorial.html
  • 社区:在 X 平台搜索 #PyTorch 或 #DeepLearning 查看最新讨论。

示例:扩展到 CNN

以下是一个简单的卷积神经网络,用于图像分类(例如 MNIST):

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1)  # 输入 1 通道,输出 16 通道
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc = nn.Linear(16 * 14 * 14, 10)  # 假设输入图像 28x28

    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))  # 卷积 -> ReLU -> 池化
        x = x.view(-1, 16 * 14 * 14)  # 展平
        x = self.fc(x)
        return x

如果你需要更详细的代码(例如,CNN、RNN 或具体任务)、可视化训练过程(如损失曲线)或特定模块的讲解,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注