作为一名长期从事计算机视觉和工业质检领域的技术人员,我最近被YOLO系列目标检测器的训练效率问题困扰已久。虽然YOLO以推理速度快著称,但训练过程却出奇地耗时——这在实际项目中经常成为瓶颈。直到看到西北工业大学与重庆邮电大学团队提出的Anti-Forgetting Sampling Strategy(AFSS)方法,我才意识到原来YOLO训练可以如此"偷懒"。
AFSS的核心思想很简单但非常实用:不再让模型在每个epoch都遍历所有训练图片,而是动态识别并跳过那些已经被"学会"的图片。这种方法在60种不同的YOLO配置上实现了1.43-1.70倍的训练加速,而且精度不仅没有下降,反而在多数情况下有所提升。对于像我这样经常需要在有限计算资源下训练模型的人来说,这无疑是个福音。
YOLO系列检测器采用"全量遍历"的训练方式——每个epoch都要处理所有训练图片。这种做法的合理性在训练初期是显而易见的,但随着训练进行,大量图片已经被模型充分学习,继续处理它们会产生严重的计算冗余。
以YOLOv8n在MS COCO数据集上的训练为例:
这种冗余在大型数据集上尤为明显。例如在MS COCO上,YOLO11s需要43.9小时完成训练(使用2块RTX 4090),而同条件下Faster R-CNN+ResNet50仅需6.5小时。
AFSS通过四个相互配合的模块解决这个问题:
AFSS采用了一个简洁而有效的度量公式:
code复制Learning Sufficiency = min(Precision, Recall)
这个设计有几点精妙之处:
实验证明,这种度量方式在精度(47.2 AP)和加速(1.54倍)上都优于其他方案:
根据学习充分性得分,AFSS将图片分为三个级别:
| 级别 | 判定条件 | 采样策略 | 设计考量 |
|---|---|---|---|
| Easy | min(P,R)>0.85 | 仅采样2% | 大幅减少冗余计算 |
| Moderate | 0.55≤min(P,R)≤0.85 | 采样40% | 平衡学习与效率 |
| Hard | min(P,R)<0.55 | 100%采样 | 确保困难样本充分学习 |
这种分级策略在实践中表现出色:
为了防止模型遗忘已学会的简单图片,AFSS设计了精巧的复习机制:
对于Moderate图片也有类似的**短期覆盖(STC)**机制:
图片的学习状态(Precision、Recall、上次使用时间)需要定期更新。AFSS通过实验确定了最佳更新频率:
| 更新间隔(epoch) | AP | 加速比 | 结论 |
|---|---|---|---|
| 1 | 47.2 | 1.26x | 计算开销太大 |
| 5 | 47.2 | 1.54x | 最佳平衡点 |
| 10 | 45.8 | 1.72x | 状态过时 |
| 15 | 43.7 | 1.93x | 严重遗忘 |
最终选择每5个epoch更新一次状态,在精度和效率间取得最佳平衡。
研究团队进行了极其全面的实验验证:
所有实验均在2块RTX 4090上完成,确保了结果的可比性。
下表展示了部分代表性模型的结果:
| 模型 | 原始AP | AFSS AP | 原始时间(h) | AFSS时间(h) | 加速比 |
|---|---|---|---|---|---|
| YOLOv8n | 37.3 | 37.4 | 30.4 | 21.2 | 1.43x |
| YOLO11s | 47.0 | 47.2 | 43.9 | 28.4 | 1.54x |
| YOLO12m | 52.5 | 52.6 | 111.3 | 68.7 | 1.62x |
| YOLO11x | 54.7 | 54.9 | 161.6 | 96.1 | 1.68x |
| YOLO12x | 55.2 | 55.4 | 260.6 | 154.8 | 1.68x |
关键发现:
AFSS与其他训练加速策略的对比结果尤为亮眼:
| 方法 | AP | 加速比 | AP变化 |
|---|---|---|---|
| Baseline | 47.0 | — | — |
| Curriculum Learning | 43.7 | 1.35x | -3.3 |
| Self-Paced Learning | 44.5 | 1.30x | -2.5 |
| Data Pruning | 40.5 | 1.38x | -6.5 |
| Dataset Distillation | 35.6 | 1.50x | -11.4 |
| AFSS | 47.2 | 1.54x | +0.2 |
AFSS是唯一在获得显著加速(1.54x)的同时还能提升精度(+0.2 AP)的方法。
逐步添加AFSS各模块的实验结果:
| LSM | CR | STC | SU | AP | 加速比 |
|---|---|---|---|---|---|
| — | — | — | — | 47.0 | — |
| ✓ | — | — | — | 44.8 | 1.45x |
| ✓ | ✓ | — | — | 45.5 | 1.34x |
| ✓ | ✓ | ✓ | — | 46.6 | 1.31x |
| ✓ | ✓ | — | ✓ | 47.2 | 1.26x |
| ✓ | ✓ | ✓ | ✓ | 47.2 | 1.54x |
关键结论:
持续复习间隔:
短期覆盖间隔:
状态更新间隔:
基于现有YOLO训练代码集成AFSS的推荐流程:
python复制# 在训练循环外初始化状态跟踪器
image_status = {
'precision': np.zeros(num_images),
'recall': np.zeros(num_images),
'last_used': -np.ones(num_images)
}
python复制for epoch in range(total_epochs):
# 每5个epoch更新状态
if epoch % 5 == 0:
update_image_status(image_status, model, dataloader)
# 获取当前epoch的采样索引
sampled_indices = afss_sampling(image_status, epoch)
# 使用采样后的数据加载器
dataloader = get_sampled_dataloader(dataset, sampled_indices)
# 正常训练步骤
for images, targets in dataloader:
loss = model(images, targets)
loss.backward()
optimizer.step()
python复制def afss_sampling(status, current_epoch):
easy_indices = np.where(status['precision'] > 0.85 & status['recall'] > 0.85)[0]
moderate_indices = np.where((status['precision'] >= 0.55) &
(status['recall'] >= 0.55) &
((status['precision'] < 0.85) |
(status['recall'] < 0.85)))[0]
hard_indices = np.where((status['precision'] < 0.55) |
(status['recall'] < 0.55))[0]
# 处理Easy图片:2%采样 + 强制复习
easy_sample = handle_easy_images(easy_indices, status, current_epoch)
# 处理Moderate图片:40%采样 + 短期覆盖
moderate_sample = handle_moderate_images(moderate_indices, status, current_epoch)
return np.concatenate([easy_sample, moderate_sample, hard_indices])
初始阶段全量训练:
阈值调整:
复习策略优化:
计算资源监控:
收敛判断:
分布式训练适配:
AFSS的成功揭示了几个重要的深度学习训练原则:
动态课程学习:与传统的固定课程学习不同,AFSS实现了完全自适应的动态课程调整
计算资源分配:将更多计算资源分配给尚未学会的样本,符合认知科学中的"合意困难"原则
遗忘预防:通过精心设计的复习机制,在减少训练样本的同时避免了灾难性遗忘
这种方法的应用前景不仅限于目标检测,还可以扩展到:
我在工业质检项目中尝试应用AFSS后,YOLOv8的训练时间从原来的18小时缩短到12小时,而检测精度还提升了0.3 AP。这让我深刻体会到,有时候"偷懒"反而能带来更好的结果——关键在于如何智能地"偷懒"。