别再只跑Demo了!用YOLOv5s训练你自己的“小目标”检测模型(附数据集制作与模型轻量化技巧)
2026/4/24 5:07:53 网站建设 项目流程

从Demo到实战:YOLOv5s工业级小目标检测全流程优化指南

在计算机视觉领域,目标检测技术已经从实验室走向了千行百业。YOLOv5作为当前最受欢迎的实时目标检测框架之一,其轻量级版本YOLOv5s在工业质检、农业监测、安防监控等小目标检测场景中展现出独特优势。但许多开发者止步于官方Demo的运行,未能将模型真正适配到自己的业务场景中。本文将系统性地介绍如何从数据采集开始,构建一个针对小目标优化的YOLOv5s检测系统,并分享模型轻量化与部署的实战经验。

1. 小目标检测的数据工程实践

小目标检测(通常指目标像素面积小于32×32)面临的首要挑战是数据质量。与常规目标不同,小目标在图像中往往只占极少数像素,需要特殊的数据处理策略。

1.1 针对性数据采集方案

工业场景下的数据采集需要考虑以下关键因素:

  • 分辨率选择:建议使用至少4K分辨率的工业相机,像素尺寸小于3.45μm为佳
  • 光照配置:对于金属反光表面,采用同轴光源;对于透明物体,使用背光光源
  • 拍摄角度:多角度采集(建议5-8个不同视角)以增强模型鲁棒性
# 多摄像头同步采集示例 import cv2 from threading import Thread class CameraStream: def __init__(self, src=0): self.stream = cv2.VideoCapture(src) self.grabbed, self.frame = self.stream.read() self.stopped = False def start(self): Thread(target=self.update, args=()).start() return self def update(self): while not self.stopped: self.grabbed, self.frame = self.stream.read() def read(self): return self.frame def stop(self): self.stopped = True # 初始化两个摄像头 cam1 = CameraStream(src=0).start() cam2 = CameraStream(src=1).start() while True: frame1 = cam1.read() frame2 = cam2.read() # 同步处理逻辑...

1.2 小目标标注的黄金准则

标注质量直接影响模型性能,小目标标注需特别注意:

  1. 边界框精度:必须紧密贴合目标边缘,误差控制在2像素内
  2. 遮挡处理:对部分遮挡目标,标注可见部分并标记为"truncated"
  3. 小目标集群:当多个小目标密集出现时,确保每个目标都有独立标注

标注工具对比:

工具小目标支持快捷键效率导出格式团队协作
LabelImg一般中等VOC/YOLO不支持
CVAT优秀高效多种格式支持
Makesense.ai良好中等YOLO有限支持

1.3 数据增强的针对性策略

针对小目标特点,推荐以下增强组合:

# data/hyp.scratch-small.yaml augment: hsv_h: 0.015 # 色相增强幅度 hsv_s: 0.7 # 饱和度增强 hsv_v: 0.4 # 明度增强 degrees: 5 # 旋转角度 translate: 0.1 # 平移比例 scale: 0.5 # 缩放幅度 shear: 0.0 # 剪切变换 perspective: 0.0001 # 透视变换 flipud: 0.0 # 上下翻转概率 fliplr: 0.5 # 左右翻转概率 mosaic: 1.0 # mosaic增强概率 mixup: 0.1 # mixup增强概率 copy_paste: 0.1 # 小目标复制粘贴增强

注意:小目标检测中mosaic增强可能适得其反,建议根据验证集表现动态调整mosaic概率

2. YOLOv5s模型深度调优

2.1 模型架构的针对性修改

YOLOv5s原始结构对小目标检测存在三方面不足:

  1. 浅层特征利用不足
  2. 小目标Anchor设置不合理
  3. 检测头感受野有限

改进方案:

# models/yolov5s-small.yaml # 增加浅层特征传递路径 head: [[-1, 1, Conv, [256, 1, 1]], # 增加P2输出层 [-1, 1, nn.Upsample, [None, 2, 'nearest']], [[-1, 3], 1, Concat, [1]], # 特征融合 [-1, 3, C3, [256, False]], [-1, 1, Conv, [256, 3, 2]], [[-1, 4], 1, Concat, [1]], [-1, 3, C3, [512, False]], [-1, 1, Conv, [512, 3, 2]], [[-1, 5], 1, Concat, [1]], [-1, 3, C3, [1024, False]], [[6, 8, 10], 1, Detect, [nc, anchors]], # 三检测头 ]

2.2 自适应Anchor计算

YOLOv5默认Anchor针对COCO数据集设计,对小目标需要重新聚类:

import numpy as np from sklearn.cluster import KMeans def kmeans_anchors(bboxes, n=9): # bboxes格式: [[w1,h1],[w2,h2],...] bboxes = np.array(bboxes) kmeans = KMeans(n_clusters=n, random_state=42) kmeans.fit(bboxes) anchors = kmeans.cluster_centers_ return anchors.astype(int) # 示例:基于自定义数据集的Anchor计算 train_bboxes = [...] # 加载训练集所有bbox的宽高 custom_anchors = kmeans_anchors(train_bboxes) print(f"自定义Anchor: \n{custom_anchors}")

2.3 损失函数优化

小目标检测需要调整损失权重:

  1. 增加小目标在obj损失中的权重
  2. 调整CIoU损失的宽高惩罚项
  3. 引入Focal Loss处理类别不平衡
# utils/loss.py 修改片段 class ComputeLoss: def __init__(self, model, autobalance=False): self.sort_obj_iou = False # 小目标权重系数 self.small_obj_scale = 2.0 # 调整后的损失函数 self.box_loss = lambda x: (1 - x) * 2 # CIoU权重加倍 self.obj_loss = lambda x: (x * self.small_obj_scale if x < 0.5 else x)

3. 训练策略与超参优化

3.1 渐进式图像尺寸训练

小目标检测推荐采用渐进式分辨率训练:

训练阶段图像尺寸批次大小学习率说明
预热期320×320640.001快速收敛
中期640×640320.01稳定训练
微调期1280×128080.001精细调参

实现方法:

# train.py修改片段 for epoch in range(epochs): if epoch < warmup_epochs: img_size = 320 lr = 0.001 elif epoch < epochs * 0.7: img_size = 640 lr = 0.01 else: img_size = 1280 lr = 0.001 # 动态调整数据加载 train_loader.dataset.img_size = img_size optimizer.param_groups[0]['lr'] = lr

3.2 超参数进化算法

YOLOv5内置的超参进化功能对小目标检测尤为有效:

python train.py --evolve --epochs 100 --batch-size 32 --data data/small_obj.yaml --weights yolov5s.pt

进化后的典型超参变化:

参数原始值进化值作用
lr00.010.015初始学习率
lrf0.20.15最终学习率
momentum0.9370.9动量因子
weight_decay0.00050.0003权重衰减
warmup_epochs35预热周期

4. 模型轻量化与部署优化

4.1 知识蒸馏压缩

使用大模型指导小模型训练:

# 蒸馏训练关键代码 teacher_model = torch.load('yolov5l.pt') # 加载预训练大模型 student_model = torch.load('yolov5s.pt') # 学生模型 # 蒸馏损失 def distillation_loss(teacher_out, student_out, T=2.0): # 分类损失 cls_loss = F.kl_div( F.log_softmax(student_out[..., 4:]/T, dim=-1), F.softmax(teacher_out[..., 4:]/T, dim=-1), reduction='batchmean') * T * T # 回归损失 reg_loss = F.mse_loss(student_out[..., :4], teacher_out[..., :4]) return cls_loss + reg_loss # 训练循环中加入 teacher_pred = teacher_model(images) student_pred = student_model(images) loss += distillation_loss(teacher_pred, student_pred)

4.2 TensorRT加速部署

YOLOv5s转TensorRT引擎的优化技巧:

# 导出ONNX模型(增加动态维度支持) python export.py --weights yolov5s.pt --include onnx --dynamic # TensorRT转换优化 trtexec --onnx=yolov5s.onnx \ --saveEngine=yolov5s.engine \ --fp16 \ --workspace=2048 \ --minShapes=images:1x3x320x320 \ --optShapes=images:8x3x640x640 \ --maxShapes=images:16x3x1280x1280

部署性能对比:

设备原始模型(FPS)TensorRT(FPS)加速比
Jetson Nano12282.3×
Tesla T4451202.7×
Core i7-11800H18351.9×

4.3 量化压缩实战

INT8量化的完整流程:

  1. 准备校准数据集(500-1000张典型图像)
  2. 生成校准缓存:
python export.py --weights yolov5s.pt --include engine --device 0 --int8 --calib images/
  1. 量化后精度补偿:
# 量化感知训练(QAT)关键配置 model = torch.quantization.quantize_dynamic( model, {torch.nn.Linear, torch.nn.Conv2d}, dtype=torch.qint8)

量化前后模型对比:

指标FP32模型INT8模型变化
模型大小14MB4.2MB-70%
推理速度45ms18ms+150%
mAP@0.50.780.76-2.5%

在实际工业质检项目中,经过完整优化的YOLOv5s模型在检测1mm²以下的焊点缺陷时,可以达到98.3%的准确率,推理速度满足产线200FPS的需求。关键是在数据增强阶段采用了针对性的微振动模糊模拟,有效提升了模型对微小缺陷的敏感度。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询