PyTorch图像分类实战:数据预处理到模型训练完整流程

前言
图像分类是计算机视觉领域最经典的任务之一,也是深度学习入门的必经之路。图像分类是指让计算机自动判断一张图片属于哪个预定义类别的任务,它是计算机视觉(Computer Vision)的基石任务,因为许多更复杂的视觉任务(如目标检测、语义分割、实例分割)都可以看作是图像分类的扩展。自2012年AlexNet赢得ImageNet竞赛后,卷积神经网络(CNN)成为图像分类的标准方法,通过卷积层自动学习图像的层次化特征表示——从底层的边缘、纹理到高层的物体部件和语义概念——避免了传统方法中手工设计特征的繁琐过程。
本文将基于一个花朵分类项目,详细讲解如何使用 PyTorch 完成从数据预处理、数据增强、模型搭建到训练测试的完整流程。
更重要的是,这套流程是一个通用模板——无论你后续做图像分割、目标检测还是其他视觉任务,数据预处理和训练策略的核心思路都是一致的,区别仅在于中间的网络结构。
项目概览:102类花朵分类任务
数据集目录结构
本项目使用的是一个包含 102 个类别的花朵数据集(Flower Data),目录结构非常直观:
flower_data/train/:训练集,包含 1~102 共 102 个子文件夹,每个文件夹对应一个花朵类别flower_data/valid/:验证集,结构与训练集相同,但每个类别的样本数量更少

该数据集源自牛津大学Visual Geometry Group发布的Oxford 102 Flower Dataset,由Maria-Elena Nilsback和Andrew Zisserman于2008年创建,包含102种英国常见花卉。这个数据集的挑战在于:不同类别的花朵可能外观非常相似(如不同品种的雏菊),而同一类别内部由于拍摄角度、光照、花期阶段不同又存在较大的类内差异,这使得它成为细粒度图像分类(Fine-Grained Visual Classification)的经典benchmark之一。
数据量分析与应对策略
一个关键问题是:训练集总共只有 6000 多张图片,分布在 102 个类别中,平均每个类别不到 60 张。这个数据量是偏小的。
好消息是,我们可以通过数据增强策略来弥补数据不足的问题,同时借助预训练模型的迁移学习能力,即使在小数据集上也能取得不错的效果。迁移学习(Transfer Learning)的核心假设是:在大规模数据集(如ImageNet的128万张图片、1000个类别)上学到的底层视觉特征(如边缘检测、纹理识别、颜色模式)具有通用性,可以直接复用到新任务中。实践中通常有两种策略:一是冻结预训练模型的大部分层,只训练最后的分类头(Feature Extraction);二是用预训练权重初始化整个网络,然后以较小的学习率对所有层进行微调(Fine-Tuning)。对于小数据集,迁移学习能有效避免过拟合,同时大幅减少训练时间。
核心依赖与模型选择
导入关键模块
项目主要依赖两个核心包:torch 和 torchvision。其中 torchvision 提供了三个关键模块:
- transforms:用于数据预处理和数据增强
- models:提供预训练的经典网络模型
- datasets:方便按文件夹结构加载数据集(其中
ImageFolder类会自动将文件夹名映射为类别标签)

为什么选择 ResNet 作为基础模型
在模型选择上,本项目直接使用 torchvision.models 中的 ResNet,而不是从零搭建网络。原因很简单:ResNet 是计算机视觉领域使用最广泛、最经典的模型之一,经过大量实践验证,其性能远超大多数人自行设计的网络结构。
ResNet(Residual Network)由微软研究院的何恺明等人在2015年提出,通过引入残差连接(Skip Connection/Shortcut Connection)解决了深层网络的退化问题。在传统深层网络中,随着层数增加,训练误差反而会上升,这并非过拟合而是优化困难导致的。ResNet的核心思想是:让网络学习残差映射 F(x) = H(x) - x,而非直接学习目标映射 H(x)。通过将输入 x 直接跳跃连接到输出,即使某些层学到的是零映射,网络性能也不会退化。这一设计使得训练数百甚至上千层的网络成为可能。ResNet在ImageNet竞赛中以3.57%的top-5错误率夺冠,首次超越人类水平(约5.1%),并衍生出ResNet-18、ResNet-34、ResNet-50、ResNet-101、ResNet-152等不同深度的变体。
对于实际项目而言,站在巨人肩膀上才是明智之举。
数据预处理:构建通用的 Pipeline
路径配置
首先需要指定数据路径。代码中通过 data_dir 变量指向 flower_data 目录,然后分别拼接出训练集路径和验证集路径:
data_dir = 'flower_data'
train_dir = os.path.join(data_dir, 'train')
valid_dir = os.path.join(data_dir, 'valid')
如果你要迁移到自己的项目,只需将数据按照相同的文件夹结构组织,修改路径即可。
transforms.Compose:按顺序组合预处理操作
数据预处理的核心是 transforms.Compose,它将多个预处理步骤按顺序组合成一个 pipeline。训练集和验证集的处理策略是不同的——训练集需要数据增强,验证集则不需要。
transforms.Compose 采用了函数式编程中的管道(Pipeline)模式,将多个数据变换操作串联成一个可调用对象。每个变换操作接收一个 PIL Image 或 Tensor 作为输入,返回处理后的结果作为下一个操作的输入。这种设计的优势在于:模块化(每个变换独立可复用)、可组合性(自由搭配不同变换)、以及延迟执行(只在实际加载数据时才执行变换,而非预先处理所有数据)。在 PyTorch 的 DataLoader 机制中,transforms 在每次取样时动态执行,这意味着同一张图片在不同 epoch 中会经历不同的随机增强,等效于扩大了训练数据量。

代码采用字典结构来管理两套预处理方案:
data_transforms = {
'train': transforms.Compose([...]), # 训练集:包含数据增强
'valid': transforms.Compose([...]) # 验证集:仅做基础处理
}
Resize 统一输入尺寸
预处理的第一步是 Resize。原始图片的长宽各不相同,但卷积神经网络要求所有输入数据具有相同的尺寸,因此必须将所有图片统一 resize 到固定大小。

本项目选择的尺寸是 96×96(正方形),这个选择背后有几个考量:
| 尺寸 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 96×96 | 计算速度快,CPU 也能跑 | 丢失较多细节信息 | 快速实验、CPU 环境 |
| 224×224 | ResNet 标准输入,效果好 | 计算量适中 | GPU 环境 |
| 256×256+ | 保留更多特征 | 计算量大,显存需求高 | 高性能 GPU |
Resize 尺寸选择建议:
- 使用 CPU 训练时,建议选择 96 或 64,否则训练时间会非常长
- 有 GPU 环境时,可以尝试 224 或 256,效果会显著提升
- 尺寸越大,每层卷积的计算量都会增加,几十层累积下来差异巨大
- 分类任务中正方形输入是主流选择,大部分经典网络都针对正方形优化
需要补充的是,卷积层的计算量与输入特征图的空间尺寸成正比。对于一个卷积核大小为 k×k、输入通道为 C_in、输出通道为 C_out 的卷积层,其浮点运算次数(FLOPs)约为 2 × k² × C_in × C_out × H × W,其中 H×W 是输出特征图的空间尺寸。因此,将输入从 96×96 增大到 224×224,计算量大约增加 (224/96)² ≈ 5.4 倍,这在几十层网络中的累积效应是非常显著的。
数据增强:小数据集的必备策略
对于只有 6000 多张图片、102 个类别的数据集来说,数据增强几乎是必须的。数据增强的理论基础来自于正则化和不变性学习:从正则化角度看,数据增强通过人为增加训练样本的多样性来约束模型的假设空间,降低过拟合风险,其效果类似于L2正则化或Dropout;从不变性学习角度看,通过对图像施加各种几何变换和光度变换,模型被迫学习对这些变换不变的特征表示。研究表明,合理的数据增强策略可以将模型准确率提升5-15个百分点,在小数据集上效果尤为显著。
transforms 模块提供了丰富的增强方法,常用的包括:
- RandomResizedCrop:随机裁剪并缩放,模拟不同拍摄距离。该操作先随机选择原图的一个子区域(面积比例和宽高比在指定范围内随机),然后将其缩放到目标尺寸,这同时实现了位置增强和尺度增强
- RandomHorizontalFlip:随机水平翻转,增加样本多样性。默认以50%的概率执行翻转,对于花朵这类左右对称的物体特别有效
- RandomRotation:随机旋转,提升模型对角度变化的鲁棒性
- ColorJitter:颜色抖动(亮度、对比度、饱和度),模拟不同光照条件。这对于户外拍摄的花朵图片尤为重要,因为自然光照条件变化很大
- Normalize:标准化(使用 ImageNet 的均值和标准差),加速模型收敛
关于 Normalize 操作,它将图像像素值从[0,1]范围转换为均值为0、标准差为1附近的分布。PyTorch 中常用的 ImageNet 标准化参数为 mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225],这是在 ImageNet 的128万张图片上统计得到的 RGB 三通道均值和标准差。标准化使输入数据分布在原点附近且各维度方差一致,有助于梯度下降优化器更高效地工作。使用预训练模型时,必须使用与预训练时相同的标准化参数,否则输入分布的偏移会导致预训练特征失效。
需要注意的是,数据增强只应用于训练集,验证集只做 Resize 和 Normalize 等基础操作,以确保评估结果的客观性。这是因为验证集的目的是模拟模型在真实场景中的表现,如果对验证集也做随机增强,评估结果将不具有可重复性和可比性。
近年来,数据增强领域还出现了许多自动化方法,如 Google 提出的 AutoAugment(通过强化学习搜索最优增强策略)和 RandAugment(随机选择增强操作并统一控制强度),这些方法进一步降低了人工调参的成本。
总结与实践建议
本文介绍了 PyTorch 图像分类项目的前半部分——数据准备与预处理。几个核心要点:
- 通用模板思维:数据预处理、训练策略在分类/分割/检测任务中高度通用,学会一个就能举一反三
- 善用预训练模型:ResNet 等经典模型经过充分验证,直接调用远优于自行设计
- Resize 尺寸权衡:在计算资源和模型效果之间找到平衡点
- 数据增强是必备技能:尤其在小数据集场景下,合理的数据增强能显著提升模型性能
对于初学者,建议先用小尺寸(96×96)跑通整个流程,理解每一步的作用,然后再逐步调大尺寸、尝试不同的增强策略来优化效果。整个项目的代码和数据集均可直接运行,是非常好的深度学习入门练手项目。
核心要点
相关推荐

MLOps实战项目:衣物洗涤识别系统端到端构建全解析
通过一个衣物洗涤识别系统,详解MLOps端到端实战流程,涵盖自动化数据采集、模型再训练、Docker容器化、AWS云端部署以及Grafana+Prometheus监控,为MLOps初学者和求职者提供完整参考范本。

Row-Bot多智能体编排架构深度解析:父子Agent协作与并发控制
深入解析Row-Bot开源项目的多智能体编排架构,详解父子Agent分工模式、Git worktree并发安全机制、状态持久化与容错恢复设计,为AI Agent工程化落地提供可借鉴的协作范式。

Unsloth Desktop 发布:本地模型运行与训练一体化桌面应用
Unsloth Desktop 是一款开源跨平台桌面应用,集模型运行、微调训练、部署于一体,支持Mac/Windows/Linux,实现2倍训练加速与70%显存节省,零遥测保护隐私。