共计 2966 个字符,预计需要花费 8 分钟才能阅读完成。
背景痛点
目标检测作为计算机视觉的核心任务,在实际应用中常面临以下典型问题:

- 数据不平衡:小目标样本数量远少于大目标,导致模型对小目标的检测性能较差
- 小目标漏检:由于小目标像素少、特征不明显,容易在卷积过程中丢失信息
- 模型部署复杂度:工业场景需要考虑推理速度、显存占用和模型精度的平衡
这些痛点使得目标检测模型在实际应用中难以达到预期效果,特别是对小目标的检测性能往往不尽如人意。
技术选型
主流目标检测框架对比(基于 COCO val2017 数据集):
| 模型 | mAP@0.5:0.95 | 推理速度(FPS) | 显存占用(GB) |
|---|---|---|---|
| Faster R-CNN | 42.3 | 12 | 8.2 |
| DETR | 43.4 | 28 | 7.8 |
| YOLOv7 | 56.8 | 161 | 5.3 |
YOLOv7 在精度和速度上都有显著优势,特别适合需要实时检测的场景。
核心实现
PyTorch Lightning 训练框架
使用 PyTorch Lightning 可以简化训练流程,提高代码可读性:
class YOLOv7Model(pl.LightningModule):
def __init__(self, cfg):
super().__init__()
self.model = build_model(cfg) # TODO: 可根据需求调整模型结构
self.criterion = YOLOv7Loss(cfg)
def training_step(self, batch, batch_idx):
images, targets = batch
outputs = self.model(images)
loss = self.criterion(outputs, targets)
return loss
自定义 DataLoader 实现 Mosaic 数据增强
Mosaic 数据增强能有效提升小目标检测性能,但需要注意边界处理:
def mosaic_augmentation(image_list, target_list, output_size=640):
"""
:param image_list: 4 张输入图像列表
:param target_list: 对应的标注框列表
:param output_size: 输出图像尺寸
:return: 增强后的图像和标注
"""
output_image = np.zeros((output_size, output_size, 3), dtype=np.uint8)
output_targets = []
# 随机生成拼接中心点
cx, cy = [random.randint(output_size//4, 3*output_size//4) for _ in range(2)]
for i, (img, targets) in enumerate(zip(image_list, target_list)):
h, w = img.shape[:2]
# 根据位置索引确定拼接区域
if i == 0: # 左上
x1a, y1a, x2a, y2a = 0, 0, cx, cy
x1b, y1b, x2b, y2b = w-cx, h-cy, w, h
elif i == 1: # 右上
x1a, y1a, x2a, y2a = cx, 0, output_size, cy
x1b, y1b, x2b, y2b = 0, h-cy, output_size-cx, h
# 边界处理 - 防止索引越界
x1b, y1b, x2b, y2b = max(0, x1b), max(0, y1b), min(w, x2b), min(h, y2b)
# 执行裁剪和拼接
output_image[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]
# 调整标注框坐标
for target in targets:
# TODO: 坐标转换逻辑
pass
return output_image, output_targets
COCO 评估指标可视化
训练完成后,可以使用 COCO API 计算 mAP 指标:
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval
# 加载标注文件
coco_gt = COCO('annotations/instances_val2017.json')
# 准备检测结果
coco_dt = coco_gt.loadRes('detections.json')
# 创建评估器并执行评估
coco_eval = COCOeval(coco_gt, coco_dt, 'bbox')
coco_eval.evaluate()
coco_eval.accumulate()
coco_eval.summarize()
# 输出 AP@0.5:0.95 等指标
print(f'mAP@0.5:0.95 = {coco_eval.stats[0]:.3f}')
生产级优化
EMA 模型平滑
指数移动平均 (EMA) 可以提升模型推理稳定性:
class ModelEMA:
def __init__(self, model, decay=0.9999):
self.ema = deepcopy(model).eval()
self.decay = decay
def update(self, model):
with torch.no_grad():
for ema_param, model_param in zip(self.ema.parameters(), model.parameters()):
ema_param.mul_(self.decay).add_(model_param, alpha=1-self.decay)
混合精度训练
使用 AMP(自动混合精度)减少显存占用:
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
outputs = model(inputs)
loss = criterion(outputs, targets)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
TensorRT 部署优化
层融合策略可以显著提升推理速度:
- 将 Conv+BN+ReLU 融合为单个 Conv 层
- 对连续的 1 ×1 和 3 ×3 卷积进行融合
- 使用 FP16 或 INT8 量化进一步加速
避坑指南
标注格式转换
YOLO 格式与 COCO 格式转换时的常见错误:
- 坐标归一化处理不正确(YOLO 使用相对坐标,COCO 使用绝对坐标)
- 类别 ID 索引不一致(COCO 从 1 开始,部分 YOLO 实现从 0 开始)
- 忽略图像尺寸变化对标注框的影响
学习率 warmup 问题
出现 NaN 值的可能原因及解决方法:
- 初始学习率设置过大
- 损失函数中存在 log(0)操作
- 输入数据包含异常值(如 NaN 或 inf)
- 梯度爆炸(可尝试梯度裁剪)
延伸思考
- 如何设计针对无人机航拍场景的小目标检测专用 neck 结构?考虑因素包括:
- 多尺度特征融合
- 注意力机制的应用
-
计算效率的平衡
-
在小样本场景下,如何有效提升小目标检测性能?可能的方向:
- 半监督学习
- 迁移学习
- 数据增强策略优化
总结
通过本文的实践指南,我们从零搭建了一个基于 YOLOv7 的目标检测系统,涵盖了从数据准备到模型部署的全流程。YOLOv7 在精度和速度上的优势使其成为 2025 年小目标检测的 SOTA 选择。在实际应用中,还需要根据具体场景进行调整和优化,特别是针对小目标的检测性能提升。希望本指南能帮助计算机视觉初学者快速入门目标检测领域。
正文完
发表至: 未分类
近三天内
