概述
第 22 篇已经用 PaddleClas 跑通了图像分类训练、评估和预测。真正开始做自己的项目时,最关键的不是记住命令,而是读懂配置文件。
PaddleClas 通过 YAML 管理训练流程:
text
Global
|
Arch
|
Loss
|
Optimizer
|
DataLoader
|
Metric
|
Infer
每一块都对应训练中的一个关键环节:
- 数据在哪里。
- 类别数是多少。
- 用哪个模型。
- 是否加载预训练权重。
- batch size 多大。
- 学习率怎么设置。
- 训练多少 epoch。
- 保存到哪里。
读完本文,你应该能看懂 PaddleClas 常见配置项,并能把官方配置改成自己的图像分类项目配置。
数据集格式:最常见的 list 文件方式
PaddleClas 常用的数据组织方式是图片目录 + 标注文本。
示例:
text
dataset/flowers/
images/
image_00001.jpg
image_00002.jpg
train_list.txt
val_list.txt
label_list.txt
train_list.txt 内容:
text
images/image_00001.jpg 0
images/image_00002.jpg 1
images/image_00003.jpg 2
每一行包含:
text
图片相对路径 类别ID
类别 ID 通常从 0 开始。
label_list.txt 可以记录类别名:
text
rose
tulip
sunflower
保持类别名和类别 ID 的映射稳定很重要。
数据集检查:训练前先验证 5 件事
训练前检查:
- 图片路径是否真实存在。
- 类别 ID 是否从 0 开始连续编号。
- 训练集和验证集是否有交叉。
- 类别数是否和配置中的
class_num一致。 - 图片是否能正常打开。
可以用一个简单脚本检查:
python
from pathlib import Path
from PIL import Image
def check_list(root, list_file):
root = Path(root)
with open(list_file, "r", encoding="utf-8") as f:
lines = [line.strip() for line in f if line.strip()]
labels = []
for line in lines[:20]:
image_path, label = line.split()
full_path = root / image_path
Image.open(full_path).convert("RGB")
labels.append(int(label))
print("samples:", len(lines))
print("first labels:", labels)
check_list("dataset/flowers", "dataset/flowers/train_list.txt")
如果这里都不能通过,不要急着跑训练。
Global:全局训练配置
常见 Global 配置:
yaml
Global:
epochs: 100
output_dir: ./output/
save_interval: 1
eval_during_train: True
eval_interval: 1
pretrained_model:
checkpoints:
print_batch_step: 10
use_visualdl: False
字段含义:
| 字段 | 作用 |
|---|---|
epochs |
训练总轮数 |
output_dir |
模型和日志输出目录 |
save_interval |
保存间隔 |
eval_during_train |
训练中是否评估 |
eval_interval |
评估间隔 |
pretrained_model |
加载预训练或训练权重 |
checkpoints |
恢复训练 checkpoint |
print_batch_step |
日志打印频率 |
use_visualdl |
是否使用 VisualDL |
pretrained_model 和 checkpoints 不要混淆:
text
pretrained_model:常用于加载预训练权重或已训练参数
checkpoints:常用于恢复完整训练状态
Arch:模型结构配置
示例:
yaml
Arch:
name: MobileNetV3_large_x1_0
class_num: 5
pretrained: True
字段含义:
name:模型名称。class_num:分类类别数。pretrained:是否加载预训练权重。
如果你的数据集有 5 类,必须设置:
yaml
class_num: 5
否则最后分类层输出类别数和标签不匹配,训练会出错。
模型选择建议:
| 场景 | 模型建议 |
|---|---|
| CPU 或边缘设备 | MobileNet、PP-LCNet |
| 精度优先 | ResNet、ResNeXt、Swin 等 |
| 快速实验 | MobileNetV3、PP-LCNet |
| 小数据集微调 | 使用 pretrained |
Loss:损失函数配置
分类任务常见配置:
yaml
Loss:
Train:
- CELoss:
weight: 1.0
Eval:
- CELoss:
weight: 1.0
CELoss 对应交叉熵损失,适合单标签多分类。
如果你是普通图像分类:
text
每张图片只有一个类别
通常使用交叉熵即可。
如果是多标签分类:
text
一张图可能有多个标签
则损失和标签格式都要调整,不能简单套用普通单标签分类配置。
Optimizer 与 LearningRate:控制训练更新
常见配置:
yaml
Optimizer:
name: Momentum
momentum: 0.9
weight_decay: 0.00007
lr:
name: Cosine
learning_rate: 0.1
字段含义:
name:优化器名称。momentum:Momentum 系数。weight_decay:权重衰减。lr:学习率策略。
如果使用 Adam,配置可能类似:
yaml
Optimizer:
name: Adam
beta1: 0.9
beta2: 0.999
weight_decay: 0.0001
lr:
name: Cosine
learning_rate: 0.001
学习率不是越大越好。迁移学习时,通常比从头训练使用更小学习率。
DataLoader:训练和验证数据管道
常见配置结构:
yaml
DataLoader:
Train:
dataset:
name: ImageNetDataset
image_root: ./dataset/flowers/
cls_label_path: ./dataset/flowers/train_list.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 32
drop_last: False
shuffle: True
loader:
num_workers: 4
use_shared_memory: True
验证集配置通常不使用随机增强:
yaml
DataLoader:
Eval:
dataset:
name: ImageNetDataset
image_root: ./dataset/flowers/
cls_label_path: ./dataset/flowers/val_list.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
resize_short: 256
- CropImage:
size: 224
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 64
drop_last: False
shuffle: False
训练集和验证集的差异:
| 项目 | 训练集 | 验证集 |
|---|---|---|
| shuffle | True | False |
| 随机裁剪 | 常用 | 不用 |
| 随机翻转 | 常用 | 不用 |
| Normalize | 使用 | 使用 |
| batch_size | 视显存而定 | 可以稍大 |
transform_ops:最容易出错的地方
图像分类常见 transform:
text
DecodeImage -> RandCropImage -> RandFlipImage -> NormalizeImage -> ToCHWImage
或验证:
text
DecodeImage -> ResizeImage -> CropImage -> NormalizeImage -> ToCHWImage
关键原则:
- 训练集可以随机增强。
- 验证集必须稳定。
- 输入尺寸要和模型配置匹配。
- mean/std 要按 RGB 三通道设置。
- channel order 要和模型输入一致。
如果模型训练 loss 不正常,先检查数据增强是否过强、Normalize 是否写错。
Metric:指标配置
常见配置:
yaml
Metric:
Train:
- TopkAcc:
topk: [1, 5]
Eval:
- TopkAcc:
topk: [1, 5]
Top-1 表示预测最高分的类别是否正确。Top-5 表示真实类别是否在前 5 个预测中。
如果类别数小于 5,例如二分类,Top-5 没有意义。可以改成:
yaml
topk: [1]
使用 -o 覆盖配置
不想修改 YAML 文件时,可以用 -o 覆盖:
bash
python tools/train.py \
-c config.yaml \
-o Global.epochs=10 \
-o DataLoader.Train.sampler.batch_size=16 \
-o Arch.class_num=5
适合快速实验:
- 改 epoch。
- 改 batch size。
- 改学习率。
- 改类别数。
- 切换预训练。
如果实验固定下来,再写回配置文件,避免命令太长。
配置修改顺序:从最少改动开始
建议按这个顺序改:
- 复制一个官方配置文件。
- 修改
Arch.class_num。 - 修改训练和验证数据路径。
- 修改 batch size。
- 先用少量 epoch 跑通。
- 确认评估和预测正常。
- 再调整模型、学习率、增强和正则化。
不要一开始同时改很多项,否则出错很难定位。
常见错误
错误一:class_num 和标签不一致
如果标签最大 ID 是 4,则 class_num 应该至少是 5。
错误二:路径相对位置搞错
命令在哪个目录执行,会影响相对路径。建议先用绝对路径或从 PaddleClas 根目录运行。
错误三:验证集用了随机增强
验证 transform 不应包含随机裁剪和随机翻转。
错误四:batch_size 过大显存不足
减小:
yaml
batch_size: 16
或:
yaml
batch_size: 8
错误五:Top-5 用在类别数小于 5 的任务上
二分类任务只保留 Top-1。
建议练习:改出自己的 PaddleClas 配置
- 复制 quick start 配置。
- 把
class_num改成自己的类别数。 - 修改
image_root和cls_label_path。 - 把训练 epoch 改成 3,先跑通。
- 把 Top-K 改成只看 Top-1。
- 用
-o覆盖 batch size。 - 删除训练随机增强,对比效果。
总结
这一篇讲了 PaddleClas 的配置核心:
- 数据集通常使用图片路径 + 类别 ID 的 list 文件。
Global控制训练全局行为。Arch控制模型和类别数。Loss控制损失函数。Optimizer和lr控制参数更新。DataLoader控制数据读取和 transform。Metric控制训练和评估指标。-o可以快速覆盖配置项。
如果只能记住一句话,那就是:
PaddleClas 训练是否成功,关键不只是命令能跑,而是配置中的数据、模型、损失、优化器和指标是否一致。