当前位置: 首页 > news >正文

深度学习实战:基于 PyTorch 的 MNIST 手写数字识别

一、前言

MNIST 手写数字数据集是深度学习领域的 “Hello World”,非常适合入门者学习深度学习模型的构建与训练。本文将结合 PyTorch 框架,带大家完整走一遍从数据准备到模型训练、评估的流程。

二、数据准备

(一)导入工具库

首先,我们需要导入一系列必要的库,包括用于数值计算的numpy,PyTorch 相关的模块(用于构建模型、数据处理、优化等),以及用于数据可视化的matplotlib

python

运行

import numpy as np
import torch
from torchvision.datasets import MNIST
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
from torch import nn
from torch.utils.tensorboard import SummaryWriter
import matplotlib.pyplot as plt
%matplotlib inline

(二)定义超参数

超参数会影响模型的训练过程和性能,这里定义了批次大小、学习率和训练轮数。

python

运行

train_batch_size = 64
test_batch_size = 128
learning_rate = 0.01
num_epochs = 20

(三)数据预处理与加载

使用transforms对数据进行预处理,将图像转换为张量并进行归一化。然后利用MNIST数据集类下载并加载数据,通过DataLoader创建数据迭代器,方便批量处理数据。

python

运行

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.5], [0.5])])train_dataset = MNIST('../data/', train=True, transform=transform, download=True)
test_dataset = MNIST('../data/', train=False, transform=transform)train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=test_batch_size, shuffle=False)

(四)数据可视化

为了直观了解数据,我们从测试集中取出一批数据并可视化其中的部分图像及其真实标签。

python

运行

examples = enumerate(test_loader)
batch_idx, (example_data, example_targets) = next(examples)fig = plt.figure()
for i in range(6):plt.subplot(2, 3, i + 1)plt.tight_layout()plt.imshow(example_data[i][0], cmap='gray', interpolation='none')plt.title("Ground Truth: {}".format(example_targets[i]))plt.xticks([])plt.yticks([])

运行这段代码,会看到 6 张手写数字图像,每张图像上方标注了其真实的数字标签,能让我们对 MNIST 数据有更直观的认识。

三、构建模型

我们定义一个包含两个隐藏层的神经网络模型,使用ReLU作为激活函数,输出层使用Softmax函数将输出转换为类别概率分布。

python

运行

class Net(nn.Module):def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):super(Net, self).__init__()self.flatten = nn.Flatten()self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1), nn.BatchNorm1d(n_hidden_1))self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2), nn.BatchNorm1d(n_hidden_2))self.out = nn.Sequential(nn.Linear(n_hidden_2, out_dim))def forward(self, x):x = self.flatten(x)x = F.relu(self.layer1(x))x = F.relu(self.layer2(x))x = F.softmax(self.out(x), dim=1)return x

这里,nn.Flatten用于将输入的二维图像(28×28)展平为一维向量,方便全连接层处理;BatchNorm1d用于对隐藏层的输出进行批量归一化,有助于加速模型训练和提升性能;ReLU激活函数引入非线性,增强模型的表达能力;Softmax函数则将最后一层的输出转换为各个类别的概率。

四、模型训练与评估

(一)实例化模型、定义损失函数和优化器

根据硬件情况选择使用 GPU 或 CPU,实例化模型并将其移动到相应设备上。损失函数选择交叉熵损失,优化器使用带动量的随机梯度下降(SGD)。

python

运行

lr = 0.01
momentum = 0.9device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = Net(28 * 28, 300, 100, 10)
model.to(device)criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

(二)训练模型

训练过程包括多轮迭代(epoch),每轮迭代中遍历训练数据,进行前向传播、计算损失、反向传播和参数更新,同时记录训练损失和准确率。每轮结束后,在测试集上评估模型性能。还采用了动态调整学习率的策略,在训练到一定轮数后减小学习率,以提高模型收敛精度。

python

运行

losses = []
acces = []
eval_losses = []
eval_acces = []
writer = SummaryWriter(log_dir='logs', comment='train-loss')for epoch in range(num_epochs):train_loss = 0train_acc = 0model.train()if epoch % 5 == 0:optimizer.param_groups[0]['lr'] *= 0.9print("学习率:{:.6f}".format(optimizer.param_groups[0]['lr']))for img, label in train_loader:img = img.to(device)label = label.to(device)out = model(img)loss = criterion(out, label)optimizer.zero_grad()loss.backward()optimizer.step()train_loss += loss.item()writer.add_scalar('Train', train_loss / len(train_loader), epoch)_, pred = out.max(1)num_correct = (pred == label).sum().item()acc = num_correct / img.shape[0]train_acc += acclosses.append(train_loss / len(train_loader))acces.append(train_acc / len(train_loader))eval_loss = 0eval_acc = 0model.eval()for img, label in test_loader:img = img.to(device)label = label.to(device)img = img.view(img.size(0), -1)out = model(img)loss = criterion(out, label)eval_loss += loss.item()_, pred = out.max(1)num_correct = (pred == label).sum().item()acc = num_correct / img.shape[0]eval_acc += acceval_losses.append(eval_loss / len(test_loader))eval_acces.append(eval_acc / len(test_loader))print('epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'.format(epoch, train_loss / len(train_loader), train_acc / len(train_loader),eval_loss / len(test_loader), eval_acc / len(test_loader)))

在训练过程中,model.train()将模型设置为训练模式,启用 dropout 和 batch normalization 的训练行为;model.eval()则将模型设置为评估模式,关闭 dropout 等,使用 batch normalization 的已学参数。动态调整学习率是因为在训练初期,较大的学习率可以加快模型收敛速度,而到了训练后期,减小学习率有助于模型更精确地收敛到最优解。

(三)可视化训练损失

训练完成后,我们可以可视化训练损失的变化趋势,直观地观察模型的训练过程。

python

运行

plt.title('train loss')
plt.plot(np.arange(len(losses)), losses)
plt.legend(['Train Loss'], loc='upper right')

运行这段代码,会得到一张训练损失随训练轮数变化的折线图,能看到损失逐渐下降,说明模型在不断学习和优化。

五、总结

通过本次基于 PyTorch 的 MNIST 手写数字识别实战,我们完整地经历了深度学习项目的主要流程:数据准备与预处理、模型构建、模型训练与评估。在这个过程中,我们还应用了一些技巧,比如动态调整学习率来优化模型训练,使用批量归一化提升模型性能等。MNIST 作为入门数据集,让我们很好地理解了深度学习的基本概念和方法,为后续处理更复杂的深度学习任务打下了基础。

http://www.dtcms.com/a/477925.html

相关文章:

  • 字符串逆序的优雅实现:双指针法的巧妙应用
  • [GO]golang接口入门:从一个简单示例看懂接口的多态与实现
  • 文章管理系统CMS的XSS注入渗透测试(白盒)
  • 主机做网站服务器吗成都网站建设服务功能
  • 北京网站关键词优化南昌网站建设哪家比较好
  • 前端Vue 后端ASP.NET Core WebApi 本地调试交互过程
  • KeepMouseSpeedOK:专业鼠标速度调节工具
  • leetcode 169. 多数元素
  • 沟通交流类网站有哪些ui外包网站
  • LeetCode——双指针(进阶)
  • SQL Server 2019实验 │ 安装及其管理工具的使用
  • RAGE框架:确保AI Prompt高效率高质量输出
  • aspcms 你的网站未安装 请先安装qq wordpress登陆
  • 广州白云做网站的公司百度推广有哪些形式
  • C++(Qt)软件调试---binutils工具集详解(39)
  • Qt 项目国际化从零到一:用 Qt Linguist 实现多语言动态切换(含源码与踩坑指南)
  • GitPuk入门到实战(8) - 使用GitPuk + Arbess进行CICD自动化部署
  • 网站后台登录地址修改怎么查询一个网站有没有做竞价
  • 《Qt应用开发》笔记p5
  • 【AI4S】AI设计小分子药物的三大底层逻辑
  • 网站建设费入什么科目2018把网站做静态化是什么意思
  • Node.js 事件循环(Event Loop)
  • C语言结构体详解:从定义、内存对齐到位段应用
  • 单片机进入 B. 中断无限循环异常解决方法
  • 探索Apache APISIX:动态高性能API网关
  • 【储能学习】电力基础知识
  • 2025 年项目管理转型白皮书:AI 驱动下的能力重构与跨域突破
  • linux网站建设技术指南台州 网站建设
  • AI超级智能体学习笔记
  • 海量域名SSL证书的免费批量签发