自定义数据集完整训练流程
Ultralytics 统一训练代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| from ultralytics import YOLO
# 加载模型
# model = YOLO("yolov8n.yaml") # 从头训练
# model = YOLO("yolo11n.pt") # 基于预训练权重
model = YOLO("yolo26n.pt") # 2026推荐,边缘部署首选
# 开始训练
results = model.train(
# 基础配置
data="data.yaml", # 数据集配置
epochs=100, # 训练轮数
imgsz=640, # 输入尺寸
batch=16, # 批次大小
workers=8, # 数据加载线程数
# 优化器配置
optimizer="auto", # YOLO26自动使用MuSGD
lr0=0.01, # 初始学习率
lrf=0.01, # 最终学习率因子
momentum=0.937, # SGD动量
weight_decay=0.0005, # 权重衰减
# 数据增强
mosaic=1.0,
mixup=0.1,
copy_paste=0.1,
# 其他配置
device=0, # GPU设备,"cpu"为CPU
project="runs/train", # 保存路径
name="yolo26_exp1", # 实验名称
exist_ok=False, # 是否覆盖
pretrained=True, # 使用预训练
verbose=True, # 详细日志
seed=42, # 随机种子
)
# 验证模型
metrics = model.val()
print(f"mAP50: {metrics.box.map50:.3f}")
print(f"mAP50-95: {metrics.box.map:.3f}")
|
各版本训练参数差异
| 参数 | YOLOv8 | YOLO11 | YOLO26 |
|---|
| 默认优化器 | SGD | SGD | MuSGD |
| DFL 损失 | ✅ | ✅ | ❌ 已移除 |
| NMS 后处理 | ✅ | ✅ | ❌ 原生无 NMS |
| 小目标优化 | 一般 | 较好 | 最佳 (STAL) |
| CPU 推理速度 | 基准 | +25% | +43% |
损失函数详解
YOLO 的损失函数由三部分组成,每部分针对不同的学习目标:
1
2
3
4
5
| # 损失权重配置 (ultralytics/cfg/default.yaml)
loss_weights:
box: 7.5 # 边框回归损失权重
cls: 0.5 # 分类损失权重
dfl: 1.5 # DFL 损失权重 (仅 YOLOv8/v11)
|
边框回归损失 — CIoU
YOLO 使用 CIoU (Complete IoU) 作为边框回归损失。CIoU 在标准 IoU 基础上增加了中心点距离和长宽比一致性惩罚:
$$
L_{CIoU} = 1 - IoU + \frac{\rho^2(b, b_{gt})}{c^2} + \alpha v
$$
- $IoU$:预测框与真实框的交并比
- $\rho^2(b, b_{gt})$:两个框中心点的欧氏距离
- $c^2$:最小外接矩形的对角线长度
- $\alpha v$:长宽比一致性惩罚项
CIoU 相比普通 IoU 损失的核心优势:即使两个框完全不重叠,梯度依然存在,模型可以持续学习。
分类损失 — BCE Loss
分类任务使用 二元交叉熵损失 (Binary Cross-Entropy):
$$
L_{cls} = -\sum_{i=1}^{C} [y_i \cdot \log(\hat{y}_i) + (1 - y_i) \cdot \log(1 - \hat{y}_i)]
$$
YOLO 采用多标签分类(Multi-label Classification)而非 Softmax,因为一个锚点可能同时包含多个目标。每个类别独立计算 BCE 损失后求和。
DFL 损失 (Distribution Focal Loss)
YOLOv8/YOLO11 将边界框的四条边距建模为离散概率分布:
$$
DFL(\mathcal{S}i, \mathcal{S}{gt}) = -\sum_{k=0}^{15} \text{Cat}(k; y_{gt}) \cdot \log(\mathcal{S}_i[k])
$$
每条边由 16 个离散值表示,使模型能表达定位的不确定性。首次出现 DFL 损失时 loss 值通常在 3~5 之间,随着训练逐渐降到 1 以下。
YOLO26 的 ProgLoss
YOLO26 移除了 DFL,引入 ProgLoss (Progressive Loss Balancing):
1
2
3
4
5
6
| # YOLO26 损失函数特点
# ❌ DFL 已移除 —— 简化训练,减少超参数
# ✅ ProgLoss:渐进式平衡 box/cls 损失权重
# - 早期阶段:侧重分类学习 (cls 权重升高)
# - 后期阶段:侧重边框精调 (box 权重升高)
# ✅ 损失曲线更平滑,调参更直观
|
ProgLoss 采用课程学习 (Curriculum Learning) 策略:训练初期模型先学会「是什么」(分类),再学会「在哪里」(定位),避免早期定位损失过大干扰分类学习。
1
2
3
4
| ProgLoss weight schedule (示意):
Epoch 0-10: cls=1.0, box=5.0 → 侧重分类
Epoch 10-30: cls=1.0, box=7.5 → 均衡学习
Epoch 30+: cls=0.5, box=7.5 → 侧重边框
|
损失权重调优建议
| 场景 | box 权重 | cls 权重 | 说明 |
|---|
| 通用检测 | 7.5 | 0.5 | Ultralytics 默认值 |
| 小目标为主 | 10.0 | 0.3 | 提升边框精度 |
| 分类精度优先 | 5.0 | 1.0 | 减少误检 |
| 高 IoU 要求 | 12.0 | 0.3 | 提升定位精度 |
训练调优最佳实践
学习率调优
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 小数据集:降低学习率
model.train(
lr0=0.001, # 从0.01降到0.001
epochs=200, # 增加轮数
cos_lr=True, # 使用余弦退火
)
# 大数据集:标准配置
model.train(
lr0=0.01,
epochs=100,
warmup_epochs=3,
)
|
批次大小选择
| GPU 显存 | 推荐 batch | 模型尺寸 |
|---|
| 4GB | 8 | n/s |
| 8GB | 16 | n/s/m |
| 12GB | 32 | n/s/m/l |
| 24GB | 64 | 全部 |
多 GPU 训练
1
2
3
4
5
6
| # 指定多个 GPU
model.train(
device=[0, 1, 2, 3], # 使用 4 张 GPU
batch=64, # 总 batch = 单卡 batch × GPU 数
workers=8, # 数据加载线程数
)
|
DDP (Distributed Data Parallel)
Ultralytics 使用 PyTorch 的 DistributedDataParallel 实现多卡训练。DDP 将模型复制到每张 GPU,每个进程独立计算梯度后通过 AllReduce 同步:
1
2
3
4
5
| # 自动启用 DDP (无需手动配置)
model.train(
device=[0, 1, 2, 3],
batch=64,
)
|
批次大小缩放规则
| 显卡数 | 单卡 batch | 总 batch | 学习率调整 |
|---|
| 1 | 16 | 16 | lr0=0.01 (基准) |
| 2 | 16 | 32 | lr0=0.02 |
| 4 | 16 | 64 | lr0=0.04 |
| 8 | 16 | 128 | lr0=0.08 |
线性缩放法则 (Linear Scaling Rule):多卡训练时,学习率应随总 batch 大小线性增加。起始学习率 = 基准 lr0 × (总 batch / 单卡基准 batch)。建议配合 warmup_epochs 在前几个 epoch 逐步升温到目标学习率,防止初期梯度不稳定。
注意事项
- Batch Normalization:DDP 默认同步 BN 统计量,多卡训练 BN 估计更准确
- 梯度累积 (Gradient Accumulation):显存不足时可通过
accumulate 参数模拟大 batch 效果 - 显存均衡:确保各卡的 batch 和图像尺寸一致,避免 straggler 拖慢整体速度
- 同步种子:设置
seed=42 确保各卡初始化一致
早停与恢复训练
1
2
3
4
5
6
7
8
9
| # 启用早停
model.train(
patience=50, # 50轮无提升则停止
...
)
# 恢复中断的训练
model = YOLO("runs/train/exp/weights/last.pt")
model.train(resume=True)
|
训练可视化分析
超参数搜索
使用 Ultralytics 自动调参
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| from ultralytics import YOLO
model = YOLO("yolo26n.pt")
# 启动超参数搜索
result = model.tune(
data="data.yaml",
epochs=50,
iterations=100, # 搜索迭代次数
optimizer="AdamW", # 搜索时建议使用 AdamW
device=0,
batch=16,
plots=True, # 绘制调参过程
save=True, # 保存每次 trial 结果
)
|
搜索空间配置
Ultralytics 内置的默认搜索空间涵盖 10+ 个超参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 默认搜索空间 (ultralytics/cfg/tune.yaml)
lr0: [0.0001, 0.01] # 初始学习率
lrf: [0.0001, 0.1] # 最终学习率因子
momentum: [0.7, 0.99] # SGD 动量
weight_decay: [0.0, 0.002] # 权重衰减
warmup_epochs: [0, 5] # 预热轮数
warmup_momentum: [0.0, 0.95]
mosaic: [0.0, 1.0] # Mosaic 增强概率
mixup: [0.0, 0.5] # MixUp 增强概率
copy_paste: [0.0, 0.5] # Copy-Paste 增强概率
hsv_h: [0.0, 0.1] # HSV 色调增强
hsv_s: [0.0, 0.9] # HSV 饱和度增强
hsv_v: [0.0, 0.9] # HSV 明度增强
flipud: [0.0, 1.0] # 上下翻转
fliplr: [0.0, 1.0] # 左右翻转
|
与 Ray Tune 集成
对于更大规模的超参数搜索,Ultralytics 支持与 Ray Tune 集成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| import ray
from ray import tune
from ultralytics import YOLO
# Ray Tune 搜索空间
search_space = {
"lr0": tune.loguniform(1e-4, 1e-2),
"lrf": tune.loguniform(1e-4, 1e-1),
"momentum": tune.uniform(0.7, 0.99),
"weight_decay": tune.uniform(0.0, 0.002),
"mosaic": tune.uniform(0.0, 1.0),
}
# 启动 Ray Tune 搜索
model = YOLO("yolo26n.pt")
result = model.tune(
data="data.yaml",
epochs=50,
iterations=100,
use_ray=True, # 启用 Ray Tune
ray_search_alg="asha", # Async Successive Halving Algorithm
device=[0, 1, 2, 3], # 多卡并行搜索
)
|
搜索结果解读
runs/tune/ 目录下生成:
1
2
3
4
5
6
| runs/tune/
├── exp1/ # 每次 trial 的完整训练结果
├── exp2/
├── ...
├── tune_results.csv # 所有试验的超参数与指标汇总
└── tune_scatter.png # 超参数相关性散点图
|
解读技巧:
- 学习率 vs mAP:散点图左上角密集区对应最优学习率范围
- 增强强度 vs 过拟合:如果高 mosaic/mixup 值对应更高的 val mAP,说明数据增强有效
- 权重衰减敏感度:小数据集通常对 weight_decay 更敏感,最优值在 0.0003~0.0007
过拟合诊断与正则化
从损失曲线识别过拟合
训练过程出现以下信号时,模型可能正在过拟合:
1
2
3
4
| Loss curves:
📈 Train Loss: 持续下降
📉 Val Loss: 先降后升 (拐点 = 过拟合开始)
📊 mAP: 在验证集上停滞或下降
|
关键判断指标:当训练损失持续下降但验证损失开始上升时,即出现泛化差距 (Generalization Gap),这是过拟合的最明确信号。
正则化技术
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 在训练中应用多种正则化
model.train(
# 显式正则化
weight_decay=0.001, # L2 正则化(权重衰减)
dropout=0.1, # Dropout 概率
# 隐式正则化(数据增强)
mosaic=1.0,
mixup=0.2, # 混合两张图像
copy_paste=0.2, # 复制粘贴增强
# 训练控制
patience=30, # 早停
)
|
- L2 正则化 (Weight Decay):惩罚大权重,防止模型过于依赖少数特征
- Dropout:随机丢弃部分神经元,强制模型学习冗余特征
- 数据增强:Mosaic、MixUp、Copy-Paste 等增强策略隐式地扩充训练分布
- 标签平滑 (Label Smoothing):通过
label_smoothing 参数控制,防止模型过度自信
数据增强调优
不同数据集适合不同的增强策略:
| 数据集类型 | 推荐增强 | 说明 | |
|---|
| 小数据集 (<1000 张) | mosaic=1.0, mixup=0.3 | 强增强扩充多样性 | |
| 中等数据集 | mosaic=1.0, mixup=0.1 | 适中的增强 | |
| 大数据集 (>10K) | mosaic=0.5, mixup=0.0 | 弱增强,保留原始分布 | |
| 密集场景 | copy_paste=0.3 | 提升遮挡检测能力 | |
| 航拍/卫星图 | mosaic=1.0, flipud=0.5 | 利用旋转不变性 | |
早停策略调优
1
2
3
4
5
6
7
| model.train(
patience=50, # 默认 50,小数据集建议 20~30
save_period=10, # 每 N 轮保存一次方便回溯
cos_lr=True, # 余弦退火配合早停
lrf=0.001, # 最终学习率接近零
warmup_epochs=3, # 预热防止早停误判
)
|
过拟合严重时,首选手段是增加数据量或降低模型复杂度(选择更小的模型规模如 n→s),正则化只是辅助手段。
结果文件说明
训练完成后 runs/train/exp/ 目录:
1
2
3
4
5
6
7
8
| weights/
├── best.pt # 最佳权重
└── last.pt # 最后一轮权重
results.csv # 训练日志CSV
results.png # 损失曲线
confusion_matrix.png # 混淆矩阵
PR_curve.png # PR曲线
F1_curve.png # F1曲线
|
关键指标解读
验证指标深度解析
Precision 与 Recall
YOLO 训练输出的指标基于以下定义:
| 指标 | 公式 | 含义 |
|---|
| Precision (精确率) | TP / (TP + FP) | 预测为真的样本中,实际为真的比例 |
| Recall (召回率) | TP / (TP + FN) | 实际为真的样本中,被正确预测的比例 |
| F1-Score | 2 × P × R / (P + R) | Precision 与 Recall 的调和平均 |
这些指标随 Confidence 阈值变化 —— 高阈值提升 Precision 但降低 Recall,反之亦然。
混淆矩阵 (Confusion Matrix)
confusion_matrix.png 是诊断模型行为的核心工具:
1
2
3
4
5
6
7
| 预测类别
┌─────────────────┐
实际 │ TP │ FP (误检) │
类别 ├─────┼───────────┤
│ FN │ background │
│(漏检)│ (背景误判) │
└─────┴───────────┘
|
- 对角线:正确分类的样本(越多越好)
- 非对角线:类别混淆(如将"猫"预测为"狗")→ 需增加类别区分度特征
- Background FP:模型将背景误检为目标 → 增加负样本或降低置信度阈值
- 漏检 (FN):目标未被检测到 → 降低置信度阈值或增加小目标检测头
mAP 计算流程
mAP (Mean Average Precision) 是 YOLO 的核心评估指标:
- 对所有检测结果按 Confidence 排序
- 依次计算每个 Confidence 阈值下的 Precision 和 Recall
- 绘制 PR 曲线(Precision-Recall Curve),曲线下面积即为 AP
- mAP50:IoU 阈值设为 0.5 时所有类别的 AP 均值
- mAP50-95:IoU 从 0.5 到 0.95(步长 0.05)取 10 个阈值的 AP 均值
1
2
| mAP50 = 宽松评估 → 目标大致位置正确即可
mAP50-95 = 严格评估 → 框必须精确贴合目标
|
用指标诊断模型问题
| 现象 | 可能原因 | 解决方向 |
|---|
| Precision 高、Recall 低 | 漏检严重 | 降低置信度阈值、增加小目标数据 |
| Recall 高、Precision 低 | 误检过多 | 提高置信度阈值、增加负样本 |
| mAP50 高、mAP50-95 低 | 框不够精确 | 增加 box 损失权重、细化标注 |
| 类别 A 的 AP 远低于其他类 | 类别不平衡 | 增加 A 类样本或使用 Class Weights |
| PR 曲线突降 | 难例集中 | Hard Negative Mining、数据增强 |
F1-Confidence 曲线
F1_curve.png 展示了不同 Confidence 阈值下 F1 得分的曲线。曲线最高点对应的 Confidence 值即为该模型的最优阈值:
1
2
3
4
| # 自动寻找最优 Confidence 阈值
results = model.val()
best_conf = results.f1_score(threshold=...)
print(f"最优置信度阈值: {best_conf:.3f}")
|
YOLO26 专属训练方案
MuSGD 优化器
YOLO26 默认使用 MuSGD (Momentum with Scheduled Updates),这是对标准 SGD 的改进:
- 自适应动量调度:动量值在训练过程中根据梯度方差动态调整
- 时间感知学习率:集成 cosine annealing 的变体,无需单独设置
cos_lr=True - 更快的收敛:在相同 epoch 数下,MuSGD 通常比标准 SGD 提前 10~15% 达到同等精度
1
2
3
4
5
6
7
8
| # YOLO26 推荐训练配置
model.train(
optimizer="auto", # 自动选择 MuSGD
lr0=0.01, # MuSGD 对学习率不敏感,0.005~0.02 均可
momentum=0.937,
weight_decay=0.0005,
cos_lr=False, # MuSGD 内置调度,无需额外余弦退火
)
|
ProgLoss 渐进式损失平衡
YOLO26 的 ProgLoss 自动管理 box/cls 损失的权重调度,无需手动调参:
1
2
3
4
5
| Training stage Focus Loss behavior
──────────────────────────────────────────────────────────────
Epoch 1-10 (warmup) 分类学习为主 cls loss 快速下降
Epoch 10-30 (explore) 分类+定位均衡 box loss 开始显著下降
Epoch 30+ (refine) 定位精调为主 box loss 缓慢收敛
|
如果在训练日志中观察到 cls loss 长时间不降,说明 ProgLoss 的默认调度可能不适合当前数据集。此时可回退到手动模式:
1
2
3
4
5
6
7
8
| # 禁用 ProgLoss 手动设置权重
model.train(
loss_weights={
"box": 7.5,
"cls": 0.5,
},
prog_loss=False,
)
|
STAL 小目标增强训练
YOLO26 的 STAL (Small Target Augmentation Layer) 专门优化小目标检测:
1
2
3
4
5
6
| # 启用 STAL(YOLO26 默认启用)
model.train(
stal=True, # 小目标增强层
stal_scale_range=[0.5, 1.0], # 缩放范围
stal_epoch_gamma=0.1, # 增强衰减系数
)
|
STAL 工作原理:
- 检测阶段:识别图像中尺寸小于 32×32 像素的目标
- 增强阶段:对这些小目标进行上采样、复制、粘贴到图像其他区域
- 衰减策略:随着训练进行,STAL 增强强度逐渐降低,让模型逐步适应原始分布
YOLO26 训练清单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # ===== YOLO26 推荐完整训练配置 =====
model.train(
# 数据
data="data.yaml",
epochs=200,
imgsz=640,
batch=16,
# 优化器 (MuSGD)
optimizer="auto",
lr0=0.01,
momentum=0.937,
weight_decay=0.0005,
# 增强 (STAL 自动启用)
mosaic=1.0,
mixup=0.1,
copy_paste=0.1,
# 正则化
dropout=0.1,
label_smoothing=0.0,
# 其他
device=0,
patience=50,
seed=42,
verbose=True,
)
|
提示:YOLO26 在边缘设备(Jetson、树莓派等)上部署时,建议使用 imgsz=320 或 imgsz=480,推理速度可提升 23 倍,mAP 下降仅 13%。