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

发布时间:2026/8/31 15:35:20
深度学习入门:PyTorch 环境搭建与 MNIST 手写数字识别 深度学习入门PyTorch 环境搭建与 MNIST 手写数字识别前言本文是“深度学习入门”系列的第二篇。上一篇我们学习了深度学习的基本概念包括神经网络结构、激活函数、损失函数、梯度下降和反向传播。本篇我们将正式进入代码实战从 PyTorch 的环境搭建开始通过 MNIST 手写数字识别任务完整实现一个多层感知机MLP的神经网络将理论知识付诸实践。目录一、PyTorch 简介二、PyTorch 环境搭建三、MNIST 数据集四、PyTorch 基础操作五、构建神经网络模型六、训练与测试七、运行结果八、总结一、PyTorch 简介1.1 什么是 PyTorchPyTorch 是一个开源的深度学习框架由 Meta原 Facebook的人工智能研究团队开发。它基于 Torch 库使用 Python 作为前端语言提供了灵活、高效的深度学习开发环境。1.2 为什么选择 PyTorch优点说明动态计算图代码即模型调试方便易于理解Python 风格与 NumPy 类似上手容易强大的 GPU 加速支持 CUDA 和 Apple SiliconMPS丰富的生态系统Torchvision、Torchaudio、Hugging Face 等学术与研究首选大多数顶会论文使用 PyTorch 实现二、PyTorch 环境搭建2.1 安装 AnacondaAnaconda 是一个开源的 Python 发行版用于科学计算和深度学习建议使用它来管理 Python 环境。2.2 创建虚拟环境# 创建名为 dl (自己取名)的虚拟环境指定 Python 版本为 3.11conda create-ndlpython3.11# 激活虚拟环境conda activate dl2.3 安装依赖包安装 PyTorch指定版本# 安装 PyTorch 2.1.0 CPU 版本pipinstalltorch2.1.0torchvision0.16.0torchaudio2.1.0# 或指定 CUDA 版本如 CUDA 11.8pipinstalltorch2.1.0torchvision0.16.0torchaudio2.1.0 --index-url https://download.pytorch.org/whl/cu118说明本系列统一使用 PyTorch 2.1.0 版本配套关系如下PyTorchTorchvisionTorchaudio2.1.00.16.02.1.0安装 NumPy保持 1.x 版本pipinstallnumpy2.0注意NumPy 2.0 版本引入了大量 API 变更与 PyTorch 2.1.0 存在兼容性问题2.3版本以上支持但audio在Windows没有2.3以上的。必须安装 NumPy 1.x 版本否则运行时会报错。使用numpy2.0可锁定最新 1.x 版本。2.4 验证安装pythonimporttorchimporttorchvisionimporttorchaudioimportnumpyasnpprint(fPyTorch:{torch.__version__})print(fTorchvision:{torchvision.__version__})print(fTorchaudio:{torchaudio.__version__})print(fNumPy:{np.__version__})print(fCUDA 可用:{torch.cuda.is_available()})输出示例 PyTorch: 2.1.0cpu Torchvision: 0.16.0cpu Torchaudio: 2.1.0cpu NumPy: 1.26.4 CUDA 可用: False三、MNIST 数据集3.1 什么是 MNISTMNISTModified National Institute of Standards and Technology是机器学习领域最经典的手写数字数据集。它包含 70,000 张手写数字图像60,000 张用于训练10,000 张用于测试数据集特点特点说明图像尺寸28 × 28 像素颜色通道灰度单通道像素范围0 ~ 255归一化后为 0 ~ 1类别数量10数字 0-93.2 下载与加载数据importtorchimporttorchvisionfromtorchvisionimportdatasetsfromtorchvision.transformsimportToTensorimportmatplotlib.pyplotasplt# 下载训练数据集training_datadatasets.MNIST(rootdata,# 数据存储目录trainTrue,# 加载训练集downloadTrue,# 自动下载transformToTensor()# 转换为张量并归一化到 [0,1])# 下载测试数据集test_datadatasets.MNIST(rootdata,trainFalse,# 加载测试集downloadTrue,transformToTensor())print(f训练集大小:{len(training_data)})print(f测试集大小:{len(test_data)})输出示例 训练集大小: 60000 测试集大小: 100003.3 可视化展示# 显示训练集中前 9 张图片及其标签figureplt.figure(figsize(8,8))foriinrange(9):img,labeltraining_data[i]figure.add_subplot(3,3,i1)plt.title(label)plt.axis(off)plt.imshow(img.squeeze(),cmapgray)plt.show()3.4 DataLoader 数据加载器DataLoader 用于将数据集分批加载减少内存压力提高训练速度。fromtorch.utils.dataimportDataLoader# 创建数据加载器每批 64 个样本train_dataloaderDataLoader(training_data,batch_size64,shuffleTrue)test_dataloaderDataLoader(test_data,batch_size64,shuffleFalse)# 检查一批数据的形状forX,yintest_dataloader:print(fShape of X [N, C, H, W]:{X.shape})print(fShape 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 加速。# 创建张量xtorch.tensor([1,2,3])print(x)# 零张量zerostorch.zeros(2,3)# 随机张量randomtorch.rand(2,3)4.2 设备DevicePyTorch 支持在不同设备上运行# 自动选择设备devicecudaiftorch.cuda.is_available()elsempsiftorch.backends.mps.is_available()elsecpuprint(fUsing{device}device)# 将张量移动到设备xtorch.tensor([1,2,3]).to(device)4.3 自动求导AutogradPyTorch 的自动求导功能可以自动计算梯度是反向传播的基础。# 创建需要梯度的张量wtorch.tensor([2.0],requires_gradTrue)xtorch.tensor([3.0])# 前向计算yw*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.flattennn.Flatten()# 全连接层线性层self.hidden1nn.Linear(28*28,128)# 784 - 128self.hidden2nn.Linear(128,256)# 128 - 256self.outputnn.Linear(256,10)# 256 - 10# 前向传播defforward(self,x):xself.flatten(x)# 展平xself.hidden1(x)# 第一层全连接xtorch.sigmoid(x)# 激活函数xself.hidden2(x)# 第二层全连接xtorch.sigmoid(x)# 激活函数xself.output(x)# 输出层returnx# 创建模型实例并移动到设备modelNeuralNetwork().to(device)print(model)输出示例 NeuralNetwork( (flatten): Flatten(start_dim1, end_dim-1) (hidden1): Linear(in_features784, out_features128, biasTrue) (hidden2): Linear(in_features128, out_features256, biasTrue) (output): Linear(in_features256, out_features10, biasTrue) )六、训练与测试6.1 定义损失函数和优化器# 损失函数: 交叉熵适用于多分类问题loss_fnnn.CrossEntropyLoss()# 优化器: 随机梯度下降SGD学习率 lr0.01optimizertorch.optim.SGD(model.parameters(),lr0.01)6.2 训练函数deftrain(dataloader,model,loss_fn,optimizer):model.train()# 切换到训练模式batch_count1forX,yindataloader:# 将数据移到设备X,yX.to(device),y.to(device)# 前向传播: 计算预测值predmodel(X)# 计算损失lossloss_fn(pred,y)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()# 每 100 批打印一次损失值ifbatch_count%1000:print(floss:{loss.item():7f}[批次:{batch_count}])batch_count16.3 测试函数deftest(dataloader,model,loss_fn):sizelen(dataloader.dataset)num_batcheslen(dataloader)model.eval()# 切换到评估模式test_loss,correct0,0withtorch.no_grad():# 禁用梯度计算节省内存forX,yindataloader:X,yX.to(device),y.to(device)predmodel(X)test_lossloss_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 开始训练epochs10# 训练轮数fortinrange(epochs):print(f\n第{t1}轮训练)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 numpy2.0NumPy 2.0 与 PyTorch 2.1.0 不兼容显存管理如果显存不足减小batch_size系列直达上篇深度学习入门初识深度学习本篇深度学习入门PyTorch 环境搭建与 MNIST 手写数字识别本文下篇敬请期待