news 2026/8/30 2:28:31

PyTorch入门教程:从环境搭建到CNN手写数字识别实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PyTorch入门教程:从环境搭建到CNN手写数字识别实战

各位准备入门深度学习的朋友们,大家好。

相信很多初学者在接触深度学习时,都经历过类似的迷茫:理论看了一大堆,但真正想动手训练一个模型时,却不知道该选择哪个框架;好不容易选定了 PyTorch,又在环境配置、张量操作、模型构建这些环节反复卡壳。网上教程虽然很多,但要么太零散,要么直接丢出一大段源码让你自己琢磨,对新手并不友好。

这篇文章就是为这种情况准备的。我会围绕 PyTorch 框架,从为什么选它开始,带你一步步完成环境搭建、理解核心概念、跑通一个完整的图像分类项目,并整理高频报错和工程实践经验。文章内容覆盖入门到基础实战,代码都经过整理可以直接复制运行。不管你是学生、转行者,还是工作中需要用 AI 解决问题的开发者,这篇教程都值得收藏备用。

1. 为什么深度学习首选 PyTorch 框架

1.1 PyTorch 是什么

PyTorch 是一个基于 Python 的开源机器学习框架,由 Facebook 人工智能研究院(FAIR)团队主导开发,底层使用 Torch 库,核心计算基于张量(Tensor),可以理解为“支持自动求导的 NumPy 增强版”。

在深度学习领域,框架要解决的核心问题有三个:

  • 高效地进行张量运算(矩阵乘法、卷积、池化等)。
  • 自动计算梯度,让反向传播不再需要手推公式。
  • 提供神经网络组件,让模型搭建像搭积木一样方便。

PyTorch 对这三点都给出了很优雅的答案。它的动态计算图机制、命令式编程风格,让模型的调试过程非常接近普通 Python 程序,这也是它被学术界和工业界广泛采用的重要原因。

1.2 PyTorch 与其他框架的对比

很多人喜欢问:“PyTorch 和 TensorFlow 有什么区别?我应该学哪个?”

这里不引战,只客观说差异。TensorFlow 早期采用静态图模式,需要先定义好完整的计算图,再喂数据执行,这种方式对性能优化和分布式部署友好,但调试起来比较麻烦。PyTorch 采用动态图,计算图在每次前向传播时实时构建,你可以像写普通 Python 一样打印中间结果、打断点、逐行检查,对开发者非常友好。

从生态来看,Hugging Face 的 Transformers 库已经成了 NLP 领域的事实标准,底层的首选就是 PyTorch。学术论文开源的代码也大多基于 PyTorch。学会 PyTorch,就意味着你打开了一个可以快速复现前沿模型、灵活改进算法、顺利落地项目的大门。

1.3 PyTorch 的主要应用场景

PyTorch 的应用场景非常广泛,常见的包括:

  • 计算机视觉:图像分类、目标检测、语义分割、人脸识别、图像生成。
  • 自然语言处理:文本分类、机器翻译、情感分析、大语言模型微调。
  • 语音处理:语音识别、语音合成、人声分离。
  • 强化学习:游戏智能体、机器人控制策略。
  • 工业落地:缺陷检测、预测性维护、推荐系统、时序预测。

无论你将来从事哪个 AI 方向,PyTorch 都是绕不开的基础工具。所以这篇文章会以“框架本身”为核心,帮你把根基打牢。

2. 环境准备与版本说明

2.1 环境选择思路

在开始安装之前,先明确一点:不要盲目追求最新版本。深度学习的版本兼容性非常关键,一个不小心,CUDA 版本不匹配就会浪费大量时间。

本文示例的通用环境如下:

  • 操作系统:Windows 10/11 或 Ubuntu 20.04/22.04。
  • 编程语言:Python 3.9 或 3.10(建议使用 3.10,兼容性好)。
  • 框架版本:PyTorch 2.x(2.0 之后的版本安装方式和旧版有所不同)。
  • 构建工具:Anaconda 或 Miniconda,用于创建独立的 Python 虚拟环境。
  • IDE:PyCharm 或 VS Code,按个人习惯选择即可。

如果你没有独立的 GPU,或者显卡显存较小,不用担心。本文的核心代码在 CPU 上也能运行,只是训练速度会慢一些。初学者建议先用 CPU 跑通流程,再考虑 GPU 加速。

2.2 安装 Anaconda 与创建虚拟环境

Anaconda 是一个非常流行的 Python 环境管理工具。它集成了 conda 命令,方便我们创建互不干扰的虚拟环境。假设你已经安装好了 Anaconda,打开命令行(Windows 下是 Anaconda Prompt 或 CMD),执行下面命令创建一个名为pytorch的环境:

conda create -n pytorch python=3.10

创建过程中会询问是否继续,输入y回车。环境创建完成后,激活环境:

conda activate pytorch

激活后,命令行前面应该会出现(pytorch)字样,表示你已经进入了该环境。后续安装的 Python 包都会装在这个环境里,不会影响系统其他环境。

2.3 安装 PyTorch

PyTorch 的安装方式很简单,就是在虚拟环境中执行 pip 命令。关键问题在于,你需要根据自己的机器选择是否安装 CUDA 版本。

如果只是想在 CPU 上先跑通流程,直接执行:

pip install torch torchvision torchaudio

如果你有 NVIDIA 显卡,想使用 GPU 加速,需要先确认显卡驱动支持的 CUDA 版本。在命令行执行:

nvidia-smi

在输出的右上角可以看到 “CUDA Version: XX.X” 字样,这个数字表示你的驱动最高支持的 CUDA 版本。然后去 PyTorch 官网找到对应的安装命令。举例来说,如果你的驱动支持 CUDA 11.8,可以执行:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

如果 CUDA 版本是 12.1,则执行:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

国内用户如果下载速度慢,可以在 pip 命令后面追加国内镜像源,例如清华源:

pip install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple

注意,镜像源的切分会改变默认的下载地址,具体以你网络环境为准。安装完成后,进入 Python 环境验证是否成功:

import torch print(torch.__version__) print(torch.cuda.is_available())

如果输出类似2.1.2+cu118这样的版本号,且torch.cuda.is_available()在 GPU 机器上输出True,说明安装成功。如果输出False,说明当前环境只能使用 CPU 计算,不影响运行本文示例。

3. PyTorch 核心知识点拆解

3.1 张量(Tensor):PyTorch 的基本数据结构

张量是 PyTorch 中最基础的数据结构,可以理解为多维数组。它和 NumPy 的ndarray非常相似,区别在于张量可以在 GPU 上运行,并且支持自动求导。

下面看几个常见的张量创建方式:

import torch # 从列表创建张量 a = torch.tensor([[1, 2, 3], [4, 5, 6]]) print("a:", a) # 创建全 0 张量 b = torch.zeros(2, 3) print("b:", b) # 创建全 1 张量 c = torch.ones(2, 3) print("c:", c) # 创建随机张量 d = torch.randn(2, 3) print("d:", d) # 和 NumPy 互相转换 import numpy as np e = np.array([1, 2, 3]) tensor_from_np = torch.from_numpy(e) print("tensor_from_np:", tensor_from_np)

输出结果中,a是我们指定的值,bc是固定数值,d是服从标准正态分布的随机数。

张量的常用操作包括:

  • 形状操作:.shape.reshape().view().transpose()
  • 数学运算:加法、乘法、矩阵乘法torch.matmul()@
  • 设备转移:.to('cuda').cpu()
  • 类型转换:.float().long().numpy()

注意,view()reshape()都可以改变张量形状,但view()要求张量在内存中是连续的,而reshape()会在需要时自动复制数据。在不确定的情况下,使用reshape()更安全。

3.2 自动求导(autograd):深度学习训练的基石

自动求导是 PyTorch 最核心的机制之一。训练神经网络时,我们需要计算损失函数对每个参数的梯度,然后利用梯度更新参数。这个过程如果手工推导,几乎是不可能完成的任务,而 PyTorch 的autograd包可以自动完成。

要实现自动求导,先要把张量的requires_grad属性设置为True,然后对张量执行运算。之后调用.backward(),梯度就会自动累积到张量的.grad属性中。

来看一个简单例子:

import torch x = torch.tensor(2.0, requires_grad=True) y = x ** 2 + 3 * x + 1 y.backward() print("x的梯度:", x.grad)

对于 y = x² + 3x + 1,其导数为 2x + 3。当 x = 2 时,梯度应该是 7。程序输出的tensor(7.)验证了这一点。

再来看一个带矩阵运算的例子,更贴近真实场景:

import torch w = torch.randn(3, 3, requires_grad=True) x = torch.ones(3, 3) y = torch.sum(w * x) y.backward() print("w 的梯度形状:", w.grad.shape) print("w 的梯度内容:", w.grad)

这里y等于w * x所有元素的和。由于x所有元素都是 1,所以 w 每个元素的梯度都是 1。

实际训练中,我们一般不会直接用backward()更新参数,而是把梯度交给优化器处理。后面实战部分会展示完整流程。

3.3 nn.Module:构建神经网络的标准方式

PyTorch 提供torch.nn模块,里面包含了构建神经网络所需的各种层(全连接层、卷积层、池化层、循环神经网络层等)以及损失函数。我们自定义的网络必须继承torch.nn.Module,并在__init__方法中定义网络结构,在forward方法中定义前向传播逻辑。

来看一个最简单的三层全连接网络:

import torch import torch.nn as nn class MyNet(nn.Module): def __init__(self): super(MyNet, self).__init__() self.fc1 = nn.Linear(784, 256) self.relu = nn.ReLU() self.fc2 = nn.Linear(256, 10) def forward(self, x): x = self.fc1(x) x = self.relu(x) x = self.fc2(x) return x model = MyNet() # 模拟输入一个 4 张图片的批次,每张图片展开成 784 维向量 dummy_input = torch.randn(4, 784) output = model(dummy_input) print("输出形状:", output.shape)

forward方法中,输入x依次经过全连接层、激活函数、全连接层,最终输出形状为[4, 10],也就是每个样本有 10 个类别的得分。

这里有个非常重要的点:不要手动调用forward()。正确用法是model(x),因为 PyTorch 在__call__内部做了很多前置检查工作。

nn.Sequential可以进一步简化模型定义:

import torch import torch.nn as nn model = nn.Sequential( nn.Linear(784, 256), nn.ReLU(), nn.Linear(256, 10) ) dummy_input = torch.randn(4, 784) output = model(dummy_input) print("输出形状:", output.shape)

当你不需要复杂设计时,nn.Sequential够用;如果模型结构比较复杂,比如有多分支结构,就需要自定义nn.Module

3.4 数据加载:Dataset 与 DataLoader

在真实项目中,数据通常不会一次全部读入内存,而是通过 Dataset 定义数据读取逻辑,再交给 DataLoader 按批次加载。这也是一个新手容易困惑的地方,这里拆开说明。

  • torch.utils.data.Dataset:抽象类,你需要继承它并实现__len____getitem__两个方法。
  • torch.utils.data.DataLoader:负责自动打乱数据、按批次加载、多进程读取等。

下面是一个自定义 Dataset 的示例:

import torch from torch.utils.data import Dataset, DataLoader class MyDataset(Dataset): def __init__(self, data, labels): self.data = data self.labels = labels def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx], self.labels[idx] # 模拟 100 条数据,每条 10 维 data = torch.randn(100, 10) labels = torch.randint(0, 2, (100,)) dataset = MyDataset(data, labels) dataloader = DataLoader(dataset, batch_size=16, shuffle=True) for batch_data, batch_labels in dataloader: print("批次数据形状:", batch_data.shape) print("批次标签形状:", batch_labels.shape) break

这里的DataLoader会每次取出 16 条数据组成一个批次。shuffle=True表示每个 epoch 都会重新打乱数据顺序,防止模型学到样本顺序信息。

对于常见的 MNIST、CIFAR-10 等标准数据集,torchvision.datasets已经内置了下载和读取接口,不需要自己写 Dataset。下一节实战会直接使用它。

4. 实战:从零搭建一个 CNN 手写数字识别模型

光看不练是学不会深度学习的。这一节我们实现一个完整的项目:使用卷积神经网络(CNN)对 MNIST 手写数字数据集进行分类。整个项目会用到前面讲的所有核心知识点,包括数据加载、模型构建、自动求导、优化器更新。

4.1 创建项目结构

建议在本地创建一个新文件夹,命名为pytorch_mnist_demo,内部结构如下:

pytorch_mnist_demo/ ├── train.py # 训练脚本 ├── test.py # 测试脚本 ├── model.py # 模型定义 └── data/ # 数据集保存目录

为了让代码结构清晰,我们把模型定义单独放一个文件。

4.2 定义 CNN 模型(model.py)

文件路径:model.py

import torch.nn as nn class SimpleCNN(nn.Module): def __init__(self, num_classes=10): super(SimpleCNN, self).__init__() self.features = nn.Sequential( nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(64 * 7 * 7, 128), nn.ReLU(inplace=True), nn.Linear(128, num_classes), ) def forward(self, x): x = self.features(x) x = self.classifier(x) return x

这个网络结构非常简单:

  • 第一个卷积层:输入 1 个通道,输出 32 个通道,卷积核 3×3,padding=1 保持尺寸不变。
  • 最大池化:将 28×28 缩小到 14×14。
  • 第二个卷积层:输入 32,输出 64,尺寸仍为 14×14。
  • 最大池化:将 14×14 缩小到 7×7。
  • 全连接层:把 64×7×7 的特征图展平成 3136 维,经过 128 个神经元后输出 10 类得分。

MNIST 图片是 28×28 的灰度图,所以in_channels=1。经过两次池化后,空间尺寸正好是 7×7,因此展平后的维度是 64×7×7。

4.3 编写训练脚本(train.py)

文件路径:train.py

import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms from model import SimpleCNN # 1. 设置随机种子,保证实验结果可复现 def set_seed(seed=42): torch.manual_seed(seed) set_seed() # 2. 设备管理:优先使用 GPU device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print("使用设备:", device) # 3. 数据预处理:转为张量并归一化 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) # 4. 下载并加载训练集 train_dataset = datasets.MNIST( root="./data", train=True, transform=transform, download=True, ) train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) # 5. 初始化模型、损失函数、优化器 model = SimpleCNN(num_classes=10).to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 6. 训练循环 num_epochs = 5 for epoch in range(1, num_epochs + 1): model.train() # 进入训练模式 running_loss = 0.0 correct = 0 total = 0 for images, labels in train_loader: images, labels = images.to(device), labels.to(device) # 梯度清零 optimizer.zero_grad() # 前向传播 outputs = model(images) # 计算损失 loss = criterion(outputs, labels) # 反向传播 + 参数更新 loss.backward() optimizer.step() # 统计损失和准确率 running_loss += loss.item() * images.size(0) _, predicted = torch.max(outputs, 1) total += labels.size(0) correct += (predicted == labels).sum().item() epoch_loss = running_loss / len(train_dataset) epoch_acc = correct / total * 100 print(f"Epoch[{epoch}/{num_epochs}] Loss: {epoch_loss:.4f} Acc: {epoch_acc:.2f}%") # 7. 保存模型权重 torch.save(model.state_dict(), "./mnist_cnn.pth") print("模型已保存到 ./mnist_cnn.pth")

这个脚本的核心流程是:

  1. 设置随机种子,确保结果可复现;
  2. 自动检测 GPU 和 CPU;
  3. 将图片数据转换为张量,并做归一化处理,加速模型收敛;
  4. 使用torchvision.datasets.MNIST自动下载数据,并封装成 DataLoader;
  5. 初始化模型、交叉熵损失函数、Adam 优化器;
  6. 执行 5 轮训练,每轮结束后打印损失和准确率;
  7. 保存模型参数。

这里特别解释几个关键点。

optimizer.zero_grad()用于清空历史梯度。如果不清零,PyTorch 默认会梯度累积,导致参数更新方向错误。

loss.backward()负责计算所有参数的梯度。optimizer.step()根据梯度和学习率更新参数。这三行代码是训练循环里的固定搭配。

model.train()model.eval()会影响部分层的行为,例如 Dropout 和 BatchNorm。训练时必须调用model.train()

在 GPU 环境,图片和标签都需要通过.to(device)放到 GPU 上。如果忘记这一步,会报 “Expected all tensors to be on the same device” 错误。

4.4 编写测试脚本(test.py)

训练完成后,我们可以写一个测试脚本,加载保存的模型权重,在测试集上验证准确率。

文件路径:test.py

import torch from torch.utils.data import DataLoader from torchvision import datasets, transforms from model import SimpleCNN # 设备管理 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 数据预处理 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) # 加载测试集 test_dataset = datasets.MNIST( root="./data", train=False, transform=transform, download=True, ) test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False) # 加载模型 model = SimpleCNN(num_classes=10).to(device) model.load_state_dict(torch.load("./mnist_cnn.pth", map_location=device)) model.eval() correct = 0 total = 0 with torch.no_grad(): for images, labels in test_loader: images, labels = images.to(device), labels.to(device) outputs = model(images) _, predicted = torch.max(outputs, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f"测试集准确率: {correct / total * 100:.2f}%")

注意torch.no_grad()的使用。在推理阶段,我们不需要计算梯度,关闭梯度计算可以节省显存和计算资源,同时加速推理。

model.eval()告诉模型当前处于评估模式,这一点在含 Dropout 的模型中特别重要。如果不切换模式,每次试算结果都会有随机性。

4.5 运行与结果说明

打开命令行,进入pytorch_mnist_demo目录,激活虚拟环境后依次执行:

conda activate pytorch python train.py

首次运行会自动下载 MNIST 数据集到./data目录。数据集的下载速度取决于网络环境,如果下载太慢,可以手动下载数据集文件后放到对应的目录中,这是题外话,这里先按下不表。

训练 5 轮后,控制台大概输出如下信息(具体数值受随机种子和软硬件影响,会有小幅波动):

使用设备: cpu Epoch[1/5] Loss: 0.1978 Acc: 93.78% Epoch[2/5] Loss: 0.0573 Acc: 98.20% Epoch[3/5] Loss: 0.0390 Acc: 98.75% Epoch[4/5] Loss: 0.0285 Acc: 99.05% Epoch[5/5] Loss: 0.0223 Acc: 99.25% 模型已保存到 ./mnist_cnn.pth

从输出可以看到,只训练了 1 轮,准确率就接近 94%,5 轮之后训练集准确率超过 99%,说明这个简单的 CNN 在 MNIST 上效果非常好。

接着执行:

python test.py

输出类似:

测试集准确率: 99.04%

也就是说,在模型从未见过的测试集上,准确率也能达到 99% 左右。这验证了模型不仅“记住了”训练集,还真正学到了数字图像的特征。

到这里,你已经完整体验了一个深度学习项目的全流程:数据加载、模型定义、训练、验证、模型保存和加载。

5. 常见问题与排查思路

新手在学习 PyTorch 的过程中一定会遇到各种报错。下面整理了几个最常见的问题和对应的排查思路。

问题现象常见原因解决思路
ModuleNotFoundError: No module named 'torch'当前环境没有安装 PyTorch,或激活了错误的 conda 环境检查激活环境;重新执行 pip install torch
torch.cuda.is_available()返回 False安装的是 CPU 版本 PyTorch;CUDA 驱动不匹配查看 nvidia-smi 的 CUDA 版本,去官网安装对应 GPU 版本
RuntimeError: Expected all tensors to be on the same device模型参数和数据不在同一个设备上模型调用.to(device),数据也要调用.to(device)
CUDA out of memory批次太大、图片太大或显存不足减小 batch_size;降低图片分辨率;使用with torch.no_grad()推理
训练 Loss 为 NaN学习率过高、数据含有 NaN、损失函数使用不当降低学习率;检查数据;添加梯度裁剪torch.nn.utils.clip_grad_norm_
MNIST 数据集下载卡住网络无法访问国外服务器手动下载数据集并放置到本目录;使用国内镜像源(按实际网络选择)
模型预测结果全是同一个类别数据没有归一化、模型未收敛、标签错位检查数据预处理;打印 batch 内标签分布;增加训练轮数

除了表格里的问题,这里再补充一个新手经常忽略的细节:在训练循环里一定要调用optimizer.zero_grad()。如果梯度不清零,梯度会在多个批次之间累积,导致 Loss 震荡甚至不收敛。

此外,如果你遇到“与官方文档示例不一致”的情况,多半是 PyTorch 版本差异导致的。以 PyTorch 2.x 来说,torchvision.transforms的某些接口和旧版有所变化,更新代码时最好查阅对应版本的官方文档,不要盲目复制老代码。

6. 最佳实践与工程建议

6.1 工程目录与命名规范

建议把“数据加载”“模型定义”“训练逻辑”“测试逻辑”拆分成独立文件。如果你未来做更复杂的项目,目录结构可以是:

project/ ├── config/ # 配置文件 ├── data/ # 数据集 ├── models/ # 模型定义 ├── utils/ # 工具函数 ├── train.py # 训练入口 ├── test.py # 测试入口 └── requirements.txt # 依赖清单

命名方面,模型文件用model.pymodels/cnn.py,配置类使用全大写下划线命名,例如LEARNING_RATE = 1e-3。这些规范虽然简单,但能极大提升多人协作时的可读性。

6.2 配置管理

不要在生产代码里硬编码超参数。推荐使用配置文件或命令行参数管理学习率、批次大小、训练轮数等。PyTorch 本身没有强制要求,但工程中常见做法是:

  • 使用argparse接收命令行参数;
  • 使用yamljson配置训练参数;
  • 将关键超参数记录到日志中。

这样,你调整模型时不需要改源代码,也能追溯某一个实验到底用了哪些参数。

6.3 设备管理与随机种子

训练脚本开头建议统一管理设备:

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

与此同时,为了保证实验可复现,在创建模型、加载数据之前先设置随机种子。PyTorch 的随机种子可以直接设置,但如果你使用了 NumPy 或者 Python 内置 random,也需要一起设置:

import random import numpy as np import torch seed = 42 random.seed(seed) np.random.seed(seed) torch.manual_seed(seed)

如果你的模型对精度要求较高,还需要考虑 GPU 的确定性计算设置。不过对于刚入门阶段,记住设置 CPU 和 GPU 的种子就够了。

6.4 日志与模型保存

训练过程中不要只打印 Loss,建议同时记录准确率、学习率、时间等关键信息。最简单的做法是使用logging模块,也可以从第三方库(如 TensorBoard 或 wandb)中选择,按需引入即可。

模型保存时,要注意区分两种形式:

  • torch.save(model.state_dict(), path):只保存权重,文件小,加载时需要先构建模型结构。
  • torch.save(model, path):保存整个模型对象,加载方便,但兼容性较差,不推荐。

推荐使用state_dict方式保存。在测试脚本中,用load_state_dict加载权重时,要确保模型结构定义一致。

6.5 数据处理的边界问题

深度学习模型对数据的分布极其敏感。MNIST 训练集做了Normalize操作,测试集也必须使用完全相同的均值和标准差,否则模型效果会受影响。

批量处理图像时,如果图片尺寸不统一,数据集内部要统一做 resize 或 padding;如果数据分布极不均衡,要考虑类别权重或采样策略。这些都是训练前必须排查的边界问题。

6.6 训练调试技巧

  • 先用小规模数据(比如几十条)跑通代码,再上全量数据。
  • 如果 Loss 长期不降,可以尝试调大学习率;如果 Loss 爆炸或变 NaN,立刻调小学习率。
  • torch.utils.tensorboard或简单打印中间特征图,观察模型是否按预期工作。
  • 在遇到显存不足时,优先检查数据张量是否意外被复制、是否在no_grad下做推理。

7. 总结与下一步学习路线

通过这篇文章,你从零完成了 PyTorch 的完整入门:

  • 理解了 PyTorch 框架解决的核心问题,以及为什么它成为深度学习主流框架。
  • 搭建了独立的 Python 虚拟环境,并完成了支持 GPU/CPU 的 PyTorch 安装。
  • 掌握了张量、自动求导、模型定义、数据加载四个核心知识点。
  • 实现了完整的 CNN 手写数字识别项目,训练出了测试准确率约 99% 的模型。
  • 整理了常见报错和排查思路,以及工程实践中的关键经验。

接下来你可以按下面的顺序继续提升:

  1. 尝试把模型改成不同的结构,比如加深卷积层、加入 BatchNorm 和 Dropout,观察效果变化。
  2. 到 Kaggle 找一些简单的比赛数据集,按照本文流程完整走一遍数据探索、训练、提交。
  3. 学习迁移学习,用 PyTorch 加载预训练的 ResNet、VGG 等模型,完成自定义图像分类。
  4. 学习模型部署相关内容,理解 FP32、FP16、BF16、TF32 等浮点数格式对推理性能和精度的影响,为模型上线做准备。

深度学习知识体系庞大,但 PyTorch 是最值得投入时间掌握的框架。它本身设计友好,社区活跃,资料丰富。建议你跟着本文把代码完整跑一遍,遇到问题不要急着跳过,学会看报错信息、查官方文档,这是每个深度学习开发者都必须具备的能力。如果这篇文章对你有帮助,可以先收藏备用,后面实战遇到问题再回来对照排查。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/30 2:28:27

Agent指令遵循评测:从概念到工程落地的完整方案

我们测量了 Agent 是否真的在按指令做事:一个可落地的指令遵循评测方案 做 Agent 开发的朋友,一定遇到过这样的场景:模型在单个对话里表现完美,你让它“先查库存,再计算最优价格,最后生成报价单”&#xff…

作者头像 李华
网站建设 2026/8/30 2:26:26

Mermaid流程图可视化编辑器:拖拽改图,代码自动同步

先看这个项目的出发点:凡是写过 Mermaid 的同学应该都有体会,流程图用文本写很方便,但想微调节点位置、连线走向,却只能在渲染后的静态图上“干瞪眼”。真要改,要么回到代码里重新调语法,要么把图导进 draw…

作者头像 李华
网站建设 2026/8/30 2:25:49

图像编辑模型评测与落地:从MAI-Image登顶榜单到工程实践

MAI-Image-2.6-Preview 登顶图像编辑榜,是近期 AI 图像领域一个值得关注的变化。图像编辑并不是简单的“给一句话生成一张图”,而是要在保留原图结构、主体、风格等前提下,按照文本指令修改局部或全局内容。这个任务对模型的要求更高&#xf…

作者头像 李华
网站建设 2026/8/30 2:25:22

Web自动化测试Skill实战:从Playwright到AI Agent的完整设计指南

早上开工,产品经理提了一个需求:某个核心用户路径要改版,回归测试必须覆盖旧流程和新流程,最快下班前要结果。你打开项目,想着又要写一遍 Playwright 脚本,脑子里的第一个念头是——能不能让 AI 直接读懂页…

作者头像 李华
网站建设 2026/8/30 2:23:57

阿里实习生笔试题深度解析:从HashMap到分布式核心考点

每年三月底四月初,都是实习生招聘最热闹的时候。2017年那阵我正读研二,投了阿里巴巴的实习生岗位,想着能提前感受一下大厂面试的节奏。笔试是在线上做的,全程摄像头监控,题目分单选、多选和编程题,时间是九…

作者头像 李华
网站建设 2026/8/30 2:23:21

快手后端Java面试全攻略:从HashMap到分布式系统设计

快手后端 Java 的面经,我花了两天时间整理完,发现能写的内容比想象中多。整个流程跑下来,最大的感受是:快手的面试官不太跟你玩虚的,每个问题都会顺着你的回答一直追到底,八股背得再熟,不理解底…

作者头像 李华