深度学习入门:PyTorch 环境搭建与 MNIST 手写数字识别
2026/8/31 15:35:18 网站建设 项目流程

深度学习入门:PyTorch 环境搭建与 MNIST 手写数字识别

前言:本文是“深度学习入门”系列的第二篇。上一篇我们学习了深度学习的基本概念,包括神经网络结构、激活函数、损失函数、梯度下降和反向传播。本篇我们将正式进入代码实战,从 PyTorch 的环境搭建开始,通过 MNIST 手写数字识别任务,完整实现一个多层感知机(MLP)的神经网络,将理论知识付诸实践。

目录

  • 一、PyTorch 简介
  • 二、PyTorch 环境搭建
  • 三、MNIST 数据集
  • 四、PyTorch 基础操作
  • 五、构建神经网络模型
  • 六、训练与测试
  • 七、运行结果
  • 八、总结

一、PyTorch 简介

1.1 什么是 PyTorch?

PyTorch 是一个开源的深度学习框架,由 Meta(原 Facebook)的人工智能研究团队开发。它基于 Torch 库,使用 Python 作为前端语言,提供了灵活、高效的深度学习开发环境。

1.2 为什么选择 PyTorch?

优点说明
动态计算图代码即模型,调试方便,易于理解
Python 风格与 NumPy 类似,上手容易
强大的 GPU 加速支持 CUDA 和 Apple Silicon(MPS)
丰富的生态系统Torchvision、Torchaudio、Hugging Face 等
学术与研究首选大多数顶会论文使用 PyTorch 实现

二、PyTorch 环境搭建

2.1 安装 Anaconda

Anaconda 是一个开源的 Python 发行版,用于科学计算和深度学习,建议使用它来管理 Python 环境。

2.2 创建虚拟环境

# 创建名为 dl (自己取名)的虚拟环境,指定 Python 版本为 3.11conda create-ndlpython=3.11# 激活虚拟环境conda activate dl

2.3 安装依赖包

安装 PyTorch(指定版本)

# 安装 PyTorch 2.1.0 CPU 版本pipinstalltorch==2.1.0torchvision==0.16.0torchaudio==2.1.0# 或指定 CUDA 版本(如 CUDA 11.8)pipinstalltorch==2.1.0torchvision==0.16.0torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu118

说明:本系列统一使用 PyTorch 2.1.0 版本,配套关系如下:

PyTorchTorchvisionTorchaudio
2.1.00.16.02.1.0

安装 NumPy(保持 1.x 版本)

pipinstall"numpy<2.0"

注意:NumPy 2.0 版本引入了大量 API 变更,与 PyTorch 2.1.0 存在兼容性问题,2.3版本以上支持,但audio在Windows没有2.3以上的。必须安装 NumPy 1.x 版本,否则运行时会报错。使用"numpy<2.0"可锁定最新 1.x 版本。

2.4 验证安装

python
importtorchimporttorchvisionimporttorchaudioimportnumpyasnpprint(f"PyTorch:{torch.__version__}")print(f"Torchvision:{torchvision.__version__}")print(f"Torchaudio:{torchaudio.__version__}")print(f"NumPy:{np.__version__}")print(f"CUDA 可用:{torch.cuda.is_available()}")
输出示例: PyTorch: 2.1.0+cpu Torchvision: 0.16.0+cpu Torchaudio: 2.1.0+cpu NumPy: 1.26.4 CUDA 可用: False

三、MNIST 数据集

3.1 什么是 MNIST?

MNIST(Modified National Institute of Standards and Technology)是机器学习领域最经典的手写数字数据集。它包含 70,000 张手写数字图像:

  • 60,000 张用于训练
  • 10,000 张用于测试

数据集特点

特点说明
图像尺寸28 × 28 像素
颜色通道灰度(单通道)
像素范围0 ~ 255(归一化后为 0 ~ 1)
类别数量10(数字 0-9)

3.2 下载与加载数据

importtorchimporttorchvisionfromtorchvisionimportdatasetsfromtorchvision.transformsimportToTensorimportmatplotlib.pyplotasplt# 下载训练数据集training_data=datasets.MNIST(root='data',# 数据存储目录train=True,# 加载训练集download=True,# 自动下载transform=ToTensor()# 转换为张量并归一化到 [0,1])# 下载测试数据集test_data=datasets.MNIST(root='data',train=False,# 加载测试集download=True,transform=ToTensor())print(f"训练集大小:{len(training_data)}")print(f"测试集大小:{len(test_data)}")
输出示例: 训练集大小: 60000 测试集大小: 10000

3.3 可视化展示

# 显示训练集中前 9 张图片及其标签figure=plt.figure(figsize=(8,8))foriinrange(9):img,label=training_data[i]figure.add_subplot(3,3,i+1)plt.title(label)plt.axis('off')plt.imshow(img.squeeze(),cmap='gray')plt.show()

3.4 DataLoader 数据加载器

DataLoader 用于将数据集分批加载,减少内存压力,提高训练速度。

fromtorch.utils.dataimportDataLoader# 创建数据加载器,每批 64 个样本train_dataloader=DataLoader(training_data,batch_size=64,shuffle=True)test_dataloader=DataLoader(test_data,batch_size=64,shuffle=False)# 检查一批数据的形状forX,yintest_dataloader:print(f"Shape of X [N, C, H, W]:{X.shape}")print(f"Shape of y:{y.shape}{y.dtype}")break
输出示例: Shape of X [N, C, H, W]: torch.Size([64, 1, 28, 28]) Shape of y: torch.Size([64]) torch.int64

四、PyTorch 基础操作

4.1 张量(Tensor)

张量是 PyTorch 的基本数据结构,类似于 NumPy 的 ndarray,但支持 GPU 加速。

# 创建张量x=torch.tensor([1,2,3])print(x)# 零张量zeros=torch.zeros(2,3)# 随机张量random=torch.rand(2,3)

4.2 设备(Device)

PyTorch 支持在不同设备上运行:

# 自动选择设备device="cuda"iftorch.cuda.is_available()else"mps"iftorch.backends.mps.is_available()else"cpu"print(f"Using{device}device")# 将张量移动到设备x=torch.tensor([1,2,3]).to(device)

4.3 自动求导(Autograd)

PyTorch 的自动求导功能可以自动计算梯度,是反向传播的基础。

# 创建需要梯度的张量w=torch.tensor([2.0],requires_grad=True)x=torch.tensor([3.0])# 前向计算y=w*x# 反向传播y.backward()# 查看梯度print(w.grad)# 输出: tensor([3.])

五、构建神经网络模型

5.1 模型架构

本案例使用一个三层全连接神经网络(多层感知机 MLP):

输入层: 784 个节点 (28x28 展平) ↓ 隐藏层1: 128 个节点 + Sigmoid 激活函数 ↓ 隐藏层2: 256 个节点 + Sigmoid 激活函数 ↓ 输出层: 10 个节点 (对应数字 0-9)

5.2 完整代码

importtorchfromtorchimportnn# 定义神经网络模型classNeuralNetwork(nn.Module):def__init__(self):super().__init__()# 展平层: 将 28x28 的图像展平为 784 维向量self.flatten=nn.Flatten()# 全连接层(线性层)self.hidden1=nn.Linear(28*28,128)# 784 -> 128self.hidden2=nn.Linear(128,256)# 128 -> 256self.output=nn.Linear(256,10)# 256 -> 10# 前向传播defforward(self,x):x=self.flatten(x)# 展平x=self.hidden1(x)# 第一层全连接x=torch.sigmoid(x)# 激活函数x=self.hidden2(x)# 第二层全连接x=torch.sigmoid(x)# 激活函数x=self.output(x)# 输出层returnx# 创建模型实例并移动到设备model=NeuralNetwork().to(device)print(model)
输出示例: NeuralNetwork( (flatten): Flatten(start_dim=1, end_dim=-1) (hidden1): Linear(in_features=784, out_features=128, bias=True) (hidden2): Linear(in_features=128, out_features=256, bias=True) (output): Linear(in_features=256, out_features=10, bias=True) )

六、训练与测试

6.1 定义损失函数和优化器

# 损失函数: 交叉熵(适用于多分类问题)loss_fn=nn.CrossEntropyLoss()# 优化器: 随机梯度下降(SGD),学习率 lr=0.01optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

6.2 训练函数

deftrain(dataloader,model,loss_fn,optimizer):model.train()# 切换到训练模式batch_count=1forX,yindataloader:# 将数据移到设备X,y=X.to(device),y.to(device)# 前向传播: 计算预测值pred=model(X)# 计算损失loss=loss_fn(pred,y)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()# 每 100 批打印一次损失值ifbatch_count%100==0:print(f"loss:{loss.item():>7f}[批次:{batch_count}]")batch_count+=1

6.3 测试函数

deftest(dataloader,model,loss_fn):size=len(dataloader.dataset)num_batches=len(dataloader)model.eval()# 切换到评估模式test_loss,correct=0,0withtorch.no_grad():# 禁用梯度计算(节省内存)forX,yindataloader:X,y=X.to(device),y.to(device)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/=sizeprint(f"测试结果: 准确率:{(100*correct):.2f}%, 平均损失:{test_loss:.4f}")

6.4 开始训练

epochs=10# 训练轮数fortinrange(epochs):print(f"\n第{t+1}轮训练")print("="*40)train(train_dataloader,model,loss_fn,optimizer)print("\n训练完成!")test(test_dataloader,model,loss_fn)

七、运行结果

7.1 训练过程输出

第 1 轮训练 ======================================== loss: 2.300284 [批次: 100] loss: 2.292170 [批次: 200] loss: 2.303720 [批次: 300] loss: 2.307772 [批次: 400] ... loss: 1.222957 [批次: 900] 第 10 轮训练 ======================================== loss: 1.221065 [批次: 100] ... loss: 1.083294 [批次: 600] loss: 1.182948 [批次: 700] loss: 0.891334 [批次: 800] loss: 1.086440 [批次: 900] 训练完成! 测试结果: 准确率: 72.19%, 平均损失: 0.9466

八、总结

核心知识点速查

知识点关键概念
PyTorch开源的深度学习框架,支持动态计算图
CondaPython 虚拟环境管理工具
张量PyTorch 的基本数据结构,支持 GPU 加速
DeviceGPU/CUDA、MPS、CPU 设备管理
MNIST手写数字数据集,共 70,000 张图片
DataLoader数据分批加载工具
nn.Module所有神经网络模型的基类
前向传播forward()定义数据流向
反向传播loss.backward()自动计算梯度
交叉熵损失nn.CrossEntropyLoss()多分类标准损失

注意事项

要点说明
设备一致性模型和数据必须在同一设备上
model.train()vsmodel.eval()训练时用train(),测试时用eval()
torch.no_grad()测试时禁用梯度计算,节省内存
optimizer.zero_grad()每次更新前必须清零梯度
数据归一化ToTensor()自动将像素值归一化到 [0,1]
NumPy 版本必须使用 1.x 版本pip install "numpy<2.0"),NumPy 2.0 与 PyTorch 2.1.0 不兼容
显存管理如果显存不足,减小batch_size

系列直达

  • 上篇:深度学习入门:初识深度学习
  • 本篇:深度学习入门:PyTorch 环境搭建与 MNIST 手写数字识别(本文)
  • 下篇:敬请期待

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询