PyTorch 第一个神经网络(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在人工智能领域,神经网络作为核心工具,正以前所未有的速度推动技术革新。对于编程爱好者和开发者而言,亲手搭建第一个神经网络不仅是一次技术实践,更是一次理解深度学习原理的绝佳机会。PyTorch 作为目前最受欢迎的深度学习框架之一,以其动态计算图和简洁的 API 设计,为开发者提供了友好的入门体验。本文将通过循序渐进的方式,带领读者从零开始构建第一个 PyTorch 神经网络,涵盖数据准备、模型设计、训练与评估等关键步骤,并通过具体案例帮助读者理解背后的逻辑。


为什么选择 PyTorch?

PyTorch 凭借其灵活的动态计算图(Dynamic Computation Graph)和直观的 API 设计,在开发者社区中广受欢迎。其核心优势包括:

  • 易学易用:通过 Python 风格的语法和直观的类库结构,降低学习门槛;
  • 动态计算图:支持实时修改网络结构,适合快速实验和调试;
  • 丰富的生态:拥有庞大的预训练模型库和社区资源,便于快速应用;
  • 高效性:底层基于高性能的 C++ 实现,同时提供 Python 接口。

对于初学者而言,PyTorch 的“边做边学”特性尤其重要。例如,开发者可以在模型训练过程中动态调整参数或结构,而无需从头重新设计整个流程,这种灵活性正是快速迭代的关键。


神经网络基础概念解析

神经网络的类比:人脑与信息处理

神经网络的核心灵感来源于人脑的神经元连接机制。想象大脑中的神经元通过突触传递信号,神经网络则通过“层”(Layers)和“神经元”(Neurons)模拟这一过程:

  • 输入层:接收原始数据(如图像像素值);
  • 隐藏层:通过加权和、激活函数等操作提取数据特征;
  • 输出层:生成最终预测结果(如分类标签)。

每个神经元通过“权重”(Weights)和“偏置”(Biases)调整信号强度,而激活函数(如 ReLU)则决定神经元是否“激活”以传递信息。这一过程类似于人类学习:通过不断调整参数,网络逐渐学会从数据中提取有效模式。

神经网络的核心组件

构建一个基础神经网络需要以下核心组件:
| 组件 | 作用描述 |
|--------------|--------------------------------------------------------------------------|
| 损失函数 | 量化模型预测与真实值之间的差异,指导参数调整(如交叉熵损失、均方误差); |
| 优化器 | 根据损失函数的梯度更新模型参数,寻找最优解(如 SGD、Adam); |
| 激活函数 | 引入非线性,使模型能够拟合复杂数据分布(如 ReLU、Sigmoid); |
| 批次训练 | 通过小批量数据迭代更新参数,平衡训练效率与内存占用; |


动手实践:构建你的第一个 PyTorch 神经网络

环境准备与数据加载

首先,确保已安装 PyTorch:

pip install torch torchvision

我们将以经典的 MNIST 手写数字分类任务为例。该数据集包含 60,000 张训练图像和 10,000 张测试图像,每张图像为 28×28 像素的灰度图,标签为 0-9 的数字。

import torch  
import torch.nn as nn  
import torch.optim as optim  
import torchvision  
from torchvision import datasets, transforms  

transform = transforms.Compose([  
    transforms.ToTensor(),  
    transforms.Normalize((0.1307,), (0.3081,))  
])  

train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)  
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)  

batch_size = 64  
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)  
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)  

模型设计:从输入到输出

接下来,定义一个简单的全连接神经网络(Multilayer Perceptron, MLP)。该网络包含:

  1. 输入层:接收展平后的 28×28=784 维向量;
  2. 隐藏层:256 个神经元,使用 ReLU 激活函数;
  3. 输出层:10 个神经元(对应 0-9 的数字),使用 Softmax 输出概率分布。
class Net(nn.Module):  
    def __init__(self):  
        super(Net, self).__init__()  
        self.flatten = nn.Flatten()          # 展平输入张量  
        self.linear_relu_stack = nn.Sequential(  
            nn.Linear(28*28, 256),          # 输入层到隐藏层  
            nn.ReLU(),                      # 激活函数  
            nn.Linear(256, 10),             # 隐藏层到输出层  
        )  

    def forward(self, x):  
        x = self.flatten(x)  
        logits = self.linear_relu_stack(x)  
        return logits  

model = Net()  
print(model)  

训练配置:损失函数与优化器

选择交叉熵损失(CrossEntropyLoss)作为分类任务的损失函数,并使用 Adam 优化器进行参数更新:

criterion = nn.CrossEntropyLoss()  
optimizer = optim.Adam(model.parameters(), lr=0.001)  

训练循环:迭代优化

训练过程的核心是通过反向传播(Backpropagation)不断调整模型参数以最小化损失:

def train(model, device, train_loader, criterion, optimizer, epoch):  
    model.train()  
    for batch_idx, (data, target) in enumerate(train_loader):  
        data, target = data.to(device), target.to(device)  
        optimizer.zero_grad()               # 清空梯度缓存  
        output = model(data)                # 前向传播  
        loss = criterion(output, target)    # 计算损失  
        loss.backward()                     # 反向传播  
        optimizer.step()                    # 更新参数  

        if batch_idx % 100 == 0:  
            print(f"Epoch {epoch} | Loss: {loss.item():.4f}")  

device = torch.device("cpu")  
model.to(device)  
for epoch in range(1, 6):  
    train(model, device, train_loader, criterion, optimizer, epoch)  

模型评估:验证预测效果

完成训练后,使用测试集评估模型性能:

def test(model, device, test_loader):  
    model.eval()  
    correct = 0  
    with torch.no_grad():  
        for data, target in test_loader:  
            data, target = data.to(device), target.to(device)  
            output = model(data)  
            pred = output.argmax(dim=1, keepdim=True)  
            correct += pred.eq(target.view_as(pred)).sum().item()  

    accuracy = 100. * correct / len(test_loader.dataset)  
    print(f"Test Accuracy: {accuracy:.2f}%")  

test(model, device, test_loader)  

关键知识点详解

1. 张量(Tensor)

PyTorch 的核心数据结构是张量,类似于多维数组,但支持 GPU 加速和自动求导。例如,输入图像的张量形状为 [batch_size, 1, 28, 28],其中 1 表示单通道灰度图。

2. 自动求导(Autograd)

PyTorch 的自动求导机制通过跟踪计算图(Computation Graph)自动计算梯度。例如,当执行 loss.backward() 时,框架会从损失反向传播,计算每个参数的梯度值。

3. 过拟合与正则化

在本例中,模型可能因复杂度过高而过度拟合训练数据。可通过添加 dropout 层或 L2 正则化来缓解:

self.linear_relu_stack = nn.Sequential(  
    nn.Linear(784, 256),  
    nn.ReLU(),  
    nn.Dropout(p=0.2),          # 添加 dropout 层  
    nn.Linear(256, 10)  
)  

扩展与优化建议

1. 提升模型性能

  • 增加隐藏层:尝试 2-3 个隐藏层以增强模型表达能力;
  • 调整学习率:使用学习率衰减策略(如 torch.optim.lr_scheduler);
  • 数据增强:通过旋转、平移等操作扩充训练数据。

2. 模型部署与保存

训练完成后,可通过以下方式保存模型:

torch.save(model.state_dict(), "mnist_cnn.pt")  
model = Net()  
model.load_state_dict(torch.load("mnist_cnn.pt"))  

结论

通过本文,读者已完成了从零开始构建第一个 PyTorch 神经网络的全流程实践。这一过程不仅涉及代码编写,更重要的是理解神经网络的核心逻辑:数据流动、参数优化与损失最小化。对于编程初学者,建议从简单案例入手,逐步尝试更复杂的网络结构(如卷积神经网络)或任务(如图像分类、文本生成)。随着实践的深入,开发者将逐渐掌握如何通过 PyTorch 实现个性化需求,甚至参与前沿研究。记住,深度学习的探索永无止境——每一次代码的迭代,都是一次向智能更近的跨越。


(全文约 1800 字)

最新发布