尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
PyTorch入门实战:从环境搭建到MNIST手写数字识别
我最近在教一个朋友入门深度学习他上来就问“PyTorch怎么装装完怎么跑一个神经网络”。说实话这个问题问得特别好——PyTorch是目前最流行的深度学习框架之一学会用它搭建第一个神经网络是理解后续所有模型的基础。这篇文章我会按照我实际摸索过的路径从环境搭建、基础原理到一步步写出一个能跑的手写数字识别模型把思路和坑都讲清楚。1. 环境准备与PyTorch安装先把地基打牢1.1 版本选择别盲目装最新版很多新手上来就pip install torch然后装完发现各种报错。老手都知道PyTorch的版本跟Python版本、CUDA版本、操作系统都有对应关系。官方提供了一套版本对应表但更省心的做法是去PyTorch官网的选择页面根据自己的操作系统和包管理工具pip / conda生成安装命令。如果你用的是Anaconda强烈建议用conda创建独立环境而不是直接装到base环境。因为深度学习项目之间经常依赖不同版本的库隔离环境能避免很多“改一个依赖崩一片”的惨剧。我一般会这样建环境conda create -n pytorch python3.9 conda activate pytorchPython版本选择上3.9到3.11都是常见选择。太老的版本可能不支持新特性太新的版本可能有包依赖还没跟上。如果你用的是PyTorch 2.x建议Python 3.9以上兼容性最稳。至于GPU版本还是CPU版本这是第一个分岔路。有人问“安装pytorch是不是必须装有GPU”这里明确回答不是必须。没有独立GPU的电脑完全可以用CPU版本跑小模型手写数字识别这种任务CPU跑一个epoch也就十几秒完全够用。但有NVIDIA显卡并且想认真训练大模型尽早装CUDA版本训练速度能快几十倍。1.2 用conda还是pip两种方式我都给你试过官方推荐的conda命令一般是conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia这个命令会从官方channel拉取但有时因为网络原因比较慢。如果卡住了可以用pip安装pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118注意这里的cu118指的是CUDA 11.8对应NVIDIA驱动版本需要大于等于450。如果你的显卡是30系、40系基本都支持。如果你是A卡AMD或者用的是Intel集成显卡那建议直接用CPU版本pip install torch torchvision torchaudio热词里还出现了“7900xtx pytorch wsl”这说的是AMD显卡在WSLWindows Subsystem for Linux里用PyTorch。AMD的ROCm对PyTorch的支持近几年已经不错了但绝大多数教程还是基于NVIDIA CUDA所以如果你只有AMD显卡又不想折腾建议直接在Windows原生用CPU版本或者等ROCm生态更稳定再上。WSL里配置AMD的步骤比较繁琐我不展开细节只提醒一句WSL下需要先装好Windows侧的GPU驱动再在WSL内安装ROCm版的PyTorch而且版本匹配很容易踩坑不如直接物理机Linux配ROCm来得省心。1.3 验证安装别急着写模型先跑通这一段安装完成后一定要验证PyTorch能不能正常导入、能不能调用GPU。这一步能帮你把环境问题挡在门外不然后面报错都不知道是代码问题还是环境问题。import torch print(torch.__version__) print(torch.cuda.is_available()) if torch.cuda.is_available(): print(torch.cuda.get_device_name(0))在干净环境里这段代码输出类似2.1.0 True NVIDIA GeForce RTX 3060如果第三行是False说明你装的是CPU版或者CUDA配置有问题。这时候不要慌回到第一步检查安装命令。大家常问的“为什么我安装了pytorch但是cuda不可用”大概率是装了不带GPU支持的版本。还有一种情况是Windows下没有安装对应显卡驱动去显卡官网下载驱动装好再重启一般就能识别了。2. 神经网络基础先明白自己在干什么2.1 前馈神经网络的结构你要构建的第一个神经网络通常叫前馈神经网络Feedforward Neural Network也叫多层感知机MLP。它由一层一层的“神经元”组成输入层接收数据隐藏层做特征变换输出层给出最终预测。每一个神经元做的事情其实很简单把输入做加权求和加上偏置再过一层非线性激活函数。用生活化的比喻输入层是你拿到的一堆原始特征比如图片的像素值隐藏层像是不同角度的“筛子”把无关信息过滤掉、把关键信息组合起来。比如识别手写数字“9”底层的神经元可能学会识别圆圈高层的神经元学会把“圆圈加一竖”组合成“9”。这就是神经网络能工作的基本逻辑。在PyTorch里定义这样一个网络不需要手写所有数学公式。用torch.nn模块几行代码就能搞定。下面这个例子是常见的基础网络结构import torch.nn as nn class MyFirstNet(nn.Module): def __init__(self): super().__init__() self.fc1 nn.Linear(28*28, 128) self.fc2 nn.Linear(128, 10) self.relu nn.ReLU() def forward(self, x): x x.view(-1, 28*28) # 展平成向量 x self.relu(self.fc1(x)) x self.fc2(x) return x这里nn.Linear(28*28, 128)表示一个全连接层输入784个像素输出128个神经元nn.Linear(128, 10)输出10个类别数字0-9。注意我在两个线性层之间放了ReLU激活函数如果不加激活函数两层线性堆叠本质上还是一层线性变换模型的表达能力会大打折扣。2.2 正向传播与反向传播神经网络学习的核心训练一个神经网络就好比调收音机的旋钮找到最清晰的频率。正向传播就是“按当前参数跑一遍输入得到预测”反向传播则是“根据预测和真实值的差异反过来调整旋钮的方向和幅度”。这个“差异”用损失函数来衡量。分类任务最常用的是交叉熵损失nn.CrossEntropyLoss。你可以把它理解为预测的置信度和真实标签之间的差距。预测越离谱损失越大。反向传播的计算过程PyTorch的autograd库自动帮你完成了。你只需要调用loss.backward()PyTorch就会从输出端开始逐个计算每个参数的梯度。这个机制是整个框架的核心魅力——你不需要手算偏导也不需要懂复杂的链式法则框架帮你把数学细节封装好了。然后优化器拿到梯度更新参数optimizer.step()这个step()完成的是类似w w - lr * gradient的操作。PyTorch提供的优化器有很多比如SGD、Adam、AdamW。个人经验是入门阶段直接用Adam学习率设为0.001大多数任务都不会太差。SGD虽然理论简单但对学习率更敏感新手容易调不好。2.3 损失函数与优化器怎么选损失函数的选择取决于任务类型。手写数字识别是分类任务输出10个类别的得分所以用CrossEntropyLoss。这个损失函数内部会先对输出做Softmax归一化再计算交叉熵。也就是说你不需要在网络最后额外加Softmax激活函数CrossEntropyLoss会自己处理。如果你做的是回归任务比如预测房价就用MSELoss均方误差。如果你做的是二分类BCEWithLogitsLoss更合适。这些细节建议你遇到了再查不用提前背下来。优化器方面现在PyTorch 2.x版本里最稳妥的选择是torch.optim.Adam。它融合了动量Momentum和自适应学习率的思想通常比纯SGD收敛得快而且对学习率不那么敏感。PyTorch还提供了AdamW在Transformer类模型里表现更好但入门可以先不纠结。3. 实战用PyTorch构建你的第一个神经网络3.1 数据准备用现成的MNIST跑通全流程选数据集也有讲究。第一个项目最适合的当然是MNIST手写数字数据集——28x28的灰度图6万张训练、1万张测试所有主流框架都内置了对它的支持。PyTorch的torchvision里直接提供了下载接口不用自己找数据。不夸张地说我第一次跑模型时输出了预测错误的图才知道原来自己把数据预处理给做错了。MNIST的像素范围是0到255如果不归一化到0~1之间神经网络早期很难收敛。PyTorch中通常用transforms.ToTensor()把PIL图片转成Tensor同时自动把像素值缩放到[0,1]区间。这个细节看起来不起眼但影响很大。具体加载代码如下from torch.utils.data import DataLoader from torchvision import datasets, transforms transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_data datasets.MNIST(root./data, trainTrue, downloadTrue, transformtransform) test_data datasets.MNIST(root./data, trainFalse, downloadTrue, transformtransform) train_loader DataLoader(train_data, batch_size64, shuffleTrue) test_loader DataLoader(test_data, batch_size64, shuffleFalse)这里的Normalize((0.1307,), (0.3081,))是MNIST的官方均值和标准差。归一化能缩小数据分布差异让梯度下降更稳。我第一次写的时候漏了Normalize结果模型要训练更多轮才达到同样的正确率。DataLoader是PyTorch的数据迭代器它会自动把数据集切成长度为batch_size的批次并支持多进程加载和随机打乱。shuffleTrue只在训练集上使用测试集不需要打乱因为评估时不需要数据多样性。3.2 定义网络架构从输入到输出前文给的MyFirstNet是个非常简单的两层网络。但为了让你理解网络设计的一般原则我再展开说说层数、神经元数量怎么定。输入层维度必须等于特征维度MNIST是28*28784。中间层数量没有硬性规定理论上来讲层数和每层神经元越多模型的拟合能力越强但也会带来过拟合和训练变慢的问题。对于MNIST这种简单任务一两层隐藏层就已经够用了。这里我选择128个神经元这是一个“够用不上头”的量训练速度快准确率也能到97%左右。如果第一层直接跳到输出层比如nn.Linear(784, 10)那其实就是一个线性回归模型没有非线性能力测试准确率会掉到90%左右而且对复杂数据完全没法用。所以隐藏层和激活函数是必须的。我们来对比一下不同设计的感受网络设计参数量大概测试准确率训练几轮后784 - 10无线性激活7850约91%784 - 128 - 10ReLU101770约97%784 - 256 - 128 - 10233738约98%可以看到增加一层和适当扩大宽度确实能提升准确率但提升幅度会越来越小。入门阶段选第二种方案最划算。3.3 训练循环怎么写三个关键步骤不能乱PyTorch的训练循环没有官方模板但所有人都遵循同一个套路。我习惯把这个套路固定下来以后不管跑到什么模型直接套用。核心流程是取一批数据把数据和标签移到设备上然后optimizer.zero_grad()清零梯度前向传播得到输出计算损失调用loss.backward()反向传播最后optimizer.step()更新参数。我经常提醒初学者optimizer.zero_grad()千万别漏。因为PyTorch的梯度默认是累加的如果不清零下一轮batch的梯度会跟上一轮累加在一起导致参数更新方向被严重扭曲。这是所有PyTorch入门者都会踩的坑包括我自己第一次跑出来的loss曲线抖得跟心电图似的查了半天才发现是这里漏了。完整训练代码示例import torch import torch.nn as nn import torch.optim as optim device torch.device(cuda if torch.cuda.is_available() else cpu) model MyFirstNet().to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) def train(model, loader): model.train() total_loss 0 correct 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() total_loss loss.item() pred output.argmax(dim1, keepdimTrue) correct pred.eq(target.view_as(pred)).sum().item() return total_loss / len(loader), correct / len(loader.dataset)这段代码里有两个小技巧值得说说。一个是output.argmax(dim1)取每个样本在10个类别中得分最大的那个索引就是模型预测的类别。另一个是target.view_as(pred)因为target的形状是(batch_size,)而pred是(batch_size, 1)形状不同直接比较会广播成矩阵所以要先reshape对齐。训练时记得调用model.train()这会启用BN层和Dropout的训练模式评估时调用model.eval()并配合with torch.no_grad():告诉PyTorch不需要计算梯度节省显存和计算量。很多人漏掉model.eval()导致Dropout仍然随机屏蔽神经元测试准确率忽高忽低。3.4 模型评估与保存训练几轮后用测试集评估。下面这段代码既评估准确率也能看看每条数据预测对了没def evaluate(model, loader): model.eval() correct 0 total 0 with torch.no_grad(): for data, target in loader: data, target data.to(device), target.to(device) output model(data) pred output.argmax(dim1) total target.size(0) correct (pred target).sum().item() return correct / total当你看到测试准确率超过97%时第一个神经网络已经算跑通了。最后别忘了把模型保存下来PyTorch最推荐的方式是只保存模型参数state_dict而不是把整个模型对象序列化。这样后续加载时更稳定torch.save(model.state_dict(), mnist_fc.pth)加载模型时你需要先实例化一个同样结构的网络再把参数文件load进来loaded_model MyFirstNet() loaded_model.load_state_dict(torch.load(mnist_fc.pth)) loaded_model.eval()这里有个很实用的参数是map_location特别是你在一台有GPU的机器上训练然后拿到没有GPU的机器上做推理时需要torch.load(mnist_fc.pth, map_locationcpu)否则会报错“加载CUDA张量到CPU”。4. 常见问题与排查技巧实录这些坑我都替你踩过4.1 安装阶段版本不匹配是最容易踩的坑我见过太多人折在安装上最典型的三种第一种pip install torch装的是CPU版之后发现torch.cuda.is_available()为False。解决办法很简单按照PyTorch官方选择页面的命令指定CUDA版本重新安装。有些人问“我必须装GPU版吗”如果你的电脑没有NVIDIA卡那基本只能装CPU版但依然可以学习写神经网络。理性评估自己的需求不要被“GPU才能玩深度学习”吓退。第二种conda环境里装了但Jupyter Notebook里面import torch失败。这个大概率是Jupyter用的Python环境跟conda环境不是同一个。解决方案是先在conda环境里执行conda install ipykernel再python -m ipykernel install --user --name pytorch然后在Notebook里选择对应的kernel。第三种Windows下直接pip安装后出现Microsoft Visual C Redistributable is required的报错。这是缺Visual C运行库去微软官方下载安装即可或者在conda里安装vc包。这个报错跟PyTorch本身没关系很多人误以为是PyTorch的问题重装好几遍都没用。4.2 训练阶段Loss变成NaN或者不下降Loss变成NaN大概率是学习率过大了。我遇到过好几次尤其在使用SGD时学习率设成0.1以上loss直接飞了。换成Adam且lr0.001后问题迎刃而解。另外如果你的数据没有归一化也可能导致梯度爆炸先检查数据预处理。Loss不下降除了optimizer.zero_grad()忘写之外还有可能是激活函数死了。ReLU有个特点如果神经元输出恒为负数梯度永远是0这个神经元就“死”了。解决方法是尝试LeakyReLU或者调小学习率。训练准确率很高但测试准确率低这是过拟合。MNIST上如果不加正则化模型也会慢慢过拟合到训练集。解决思路包括增加数据增强、Dropout、正则化但入门阶段不用过分追求先跑通流程就好。4.3 硬件相关CPU、GPU和WSL的问题有人问“我只有CPU能不能练神经网络”能而且你的第一个项目完全可以。MNIST在CPU上训练一个epoch大概需要十几秒跑10个epoch也就两分钟。真正需要GPU的是大模型和大数据集。如果你有一块独立显卡但显存不大比如4GB也够跑MNIST毕竟单张28x28的图非常小。如果你是NVIDIA显卡但机器装在WSL里有时候会遇到CUDA driver version is insufficient for CUDA runtime version。这是因为WSL里需要装Windows侧的NVIDIA驱动而不是WSL内部的Linux驱动。装好Windows驱动后WSL里就能直接访问GPU了前提是PyTorch和CUDA版本兼容。热词里那个“7900xtx pytorch wsl”如果你使用的是AMD Radeon RX 7900 XTX想在WSL里用PyTorch需要关注ROCm的适配情况。PyTorch的ROCm版本现在也有官方wheel但环境变量和库依赖都比CUDA复杂。我的个人建议是不要一开始就把精力花在折腾AMD的深度学习环境上先用CPU版跑通代码等你有明确的大算力需求再考虑升级到NVIDIA环境。这不是说ROCm不行而是社区资料和踩坑经验积累程度不同入门阶段追求“快速跑通”更重要。4.4 几个能提高效率的日常习惯第一把训练过程写成函数而不是一长串无序命令。我第一次写代码时把所有步骤堆在main里改一个参数就要滚动很久后来拆成train()和evaluate()清爽多了。第二每训练完一个epoch打印一次loss和准确率方便观察趋势。第三用tensorboard或matplotlib画loss曲线对判断收敛很有帮助。我还想特别提一下热词里的“pytorch转onnx”这是个很常见需求——把训练好的模型部署到生产环境。ONNX是跨平台的模型交换格式转换方法很简单dummy_input torch.randn(1, 28*28) torch.onnx.export(model, dummy_input, model.onnx, input_names[input], output_names[output])但注意torch.onnx.export需要模型是推理模式而且要传入一个符合输入维度的dummy_input。如果后面要做量化或者动态轴那还有更复杂的参数配置入门阶段先知道有这回事就行。我个人在实际操作中的体会是用PyTorch写第一个神经网络最大的障碍不在代码而在环境。环境一旦通了后面的学习曲线会平缓很多。我建议你按这篇文章的路径先把MNIST跑起来再去理解为什么激活函数能增加非线性、为什么学习率太大容易发散。如果你在某个环节卡住了先别急着怀疑自己大概率是环境或细节问题对照常见问题列表一项项查多试几次就能解决。最后再分享一个小技巧每个epoch结束后输出一条带时间戳的信息比如Epoch 3/10, Loss: 0.08, Acc: 97.3%, Time: 11s。这条输出能让你清晰地感受到模型在收敛训练过程从“黑盒”变成“可观察”。等你跑通了第一个反向传播再去看卷积神经网络、循环神经网络就会发现很多概念都是相通的。祝你好运。
RELATED

相关推荐

本地大模型部署实战:从显存估算到推理引擎选型与微调编排

本地大模型部署实战:从显存估算到推理引擎选型与微调编排

本地部署大模型这件事,在2026年已经不是极客专利了。我最近半年被问到最多的问题,早就从“能不能部署”变成了“同样一张显卡,为什么你跑得动我跑不动”、“Ollama、vLLM、Dify到底该先装哪个”以及“本地跑DeepSeek到底该买多大显存”。坦白…

📅 2026/10/1 10:42:58
C语言超级玛丽源码拆解:从编译、碰撞检测到状态机设计

C语言超级玛丽源码拆解:从编译、碰撞检测到状态机设计

简介:这是一份基于 C 语言的超级玛丽 2D 游戏完整源码包,面向想通过底层编程理解游戏开发的学生、初学者和自学者。源码覆盖游戏循环、角色动画、碰撞检测、键盘输入、地图关卡、音效播放等关键模块,可直接分析游戏引擎的基本工作方式&#x…

📅 2026/10/1 10:37:57
ASP.NET毕业设计新闻系统源码解析:从跑通到改造实战

ASP.NET毕业设计新闻系统源码解析:从跑通到改造实战

简介:这套ASP.NET新闻系统C#毕业设计版源码,主要面向计算机相关专业学生、个人开发者及小型团队,用于快速搭建具备新闻发布与管理功能的网站,避免从零编写基础模块。资源包共24个文件,约329KB,文件类型覆盖…

📅 2026/10/1 10:37:57
MORE NEWS

更多资讯

📰

Madeira 实战:在 Linux ARM64 上通过 FEX-Emu 与 Wine 运行 Windows 应用

1. 项目缘起:为什么要在 Linux 上折腾 Windows 应用兼容层 第一次接触 Madeira 这个项目,是在一台老旧的 ThinkPad 上。那台机器跑着某个国产 Linux 发行版,硬件配置不算差,但日常办公里总有几个 Windows 独占的小工具绕不开——比…

📰

SpringBoot+Vue+MyBatis前后端分离影院购票系统完整实战源码

做全栈项目最怕什么?不是框架不会用,而是做到一半发现无从下手。前后端分离影院购票系统这个题目我打磨过好几版,这次把SpringBootVueMyBatisMySQL这一套完整源码从数据库设计讲到服务器部署,所有步骤都是我自己实操过的&#xff…

📰

用iframe解决AI病历生成中的样式冲突,简单而优雅

1. 为什么AI病历生成会撞上样式冲突先说一个真实场景。医院的电子病历系统页面里,AI正在自动生成一段病史记录。内科医生点了“生成”按钮,几秒钟后,一段结构化病历出现在页面上——标题字号比正文还小,表格边框消失得干干净净&am…

📰

Java单元测试实战:JUnit 5与Mockito关键实践

Java项目里写不写单元测试,很多时候不是技术问题,是习惯问题。我见过不少团队,代码规范、Code Review、灰度发布样样齐全,唯独 test 目录里躺着三个祖传的测试类,其中一个还标着 Ignore,注释写着"临时…

📰

Claude Code 从安装到实战:终端 AI 编程智能体入门指南

1. 为什么值得花时间把 Claude Code 跑起来 第一次听说 Claude Code 的时候,我正被一个遗留项目里几百个文件的命名重构折磨得够呛。手动改吧,怕漏;写脚本批量替换吧,正则又搞不定那些嵌套的引用关系。后来一个做后端的朋友甩给我…

📰

Matlab支持向量回归(SVR)实战:fitrsvm参数调优与避坑指南

简介:这是一份面向机器学习与MATLAB应用学习者的技术资料,聚焦支持向量回归(SVR)的完整实现与对比分析。文档系统梳理多元线性回归、BP神经网络与决策向量机的原理差异,并重点演示SVR在MATLAB中的建模流程,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬