高质量非机动车检测数据集构建与优化实践
1. 为什么你需要一个高质量的非机动车检测数据集
做目标检测的朋友都知道,数据集的质量直接决定了模型的上限。我在实际项目中遇到过太多次这样的情况:模型训练了半天,测试集上的指标就是上不去,最后发现问题出在数据集上——要么标注不准确,要么类别混乱,甚至有些数据集直接用模型预标注的。
非机动车检测这个细分领域尤其如此。市面上现成的数据集往往存在几个典型问题:一是自行车、电动车、摩托车混为一谈;二是标注框不够精确;三是场景单一,缺乏多样性。这些问题会导致模型在实际应用中表现不佳,比如把电动车识别成摩托车,或者在复杂场景下漏检。
我去年接手过一个共享单车管理项目,最初使用的公开数据集在测试环境下准确率能达到90%,但实际部署时直接掉到60%以下。后来花了三周时间重建数据集,模型效果才真正达到商用标准。这个经历让我深刻认识到:高质量的数据集不是可选项,而是必选项。
2. 数据采集的实战技巧
2.1 数据来源的选择
我通常建议从多个渠道获取原始数据:
- 公开数据集中的可用部分(但要严格筛选)
- 实际场景拍摄的街景视频
- 交通监控视频的截图
- 合作伙伴提供的业务数据
最近做的一个电动车检测项目,我就是用这种混合采集法:先从公开数据集中筛选出2000张合格图片,再通过路采获取3000张不同时段、不同角度的照片,最后从合作方拿到1500张特定场景下的监控截图。这种组合保证了数据的多样性。
2.2 拍摄时的注意事项
如果你需要自己采集数据,这几个参数要特别注意:
- 分辨率:建议不低于1920×1080,太低会影响小目标检测
- 光照条件:涵盖白天、夜晚、阴天等多种情况
- 拍摄角度:平视、俯视、斜视都要有
- 遮挡情况:适当包含部分遮挡的样本
有个实用技巧是使用行车记录仪采集数据,它能自动记录各种光照条件下的街景,而且视角很接近实际应用场景。我通常会开车在不同时段绕城区转几圈,这样半天就能收集到丰富的素材。
3. 数据标注的黄金标准
3.1 标注工具的选择
试过多种标注工具后,我总结出一个选择标准:
- LabelImg:适合小规模标注,上手简单
- CVAT:适合团队协作,支持视频标注
- Prodigy:适合主动学习场景
最近我在用改进版的LabelImg,它增加了几个实用功能:
# 标注工具的自定义配置示例 { "auto_save": true, # 自动保存 "display_label": false, # 不显示标签名避免遮挡 "label_format": "YOLO", # 直接输出YOLO格式 "default_label": "bike" # 设置默认标签 }3.2 标注质量的把控
标注质量是数据集的核心,我们团队制定了严格的标注规范:
- 边界框要紧贴物体边缘,但不要截断任何部分
- 对于部分遮挡的物体,要标注可见部分的完整轮廓
- 每个物体的标注类别必须明确,不允许出现"不确定"的标签
- 对于难以判断的小目标,至少要经过两名标注员确认
我们开发了一个简单的标注校验脚本,可以快速检查常见问题:
import os from PIL import Image def validate_annotation(img_path, label_path): img = Image.open(img_path) width, height = img.size with open(label_path) as f: lines = f.readlines() for line in lines: _, x, y, w, h = map(float, line.strip().split()) if not (0 <= x <=1 and 0 <=y <=1 and 0 <=w <=1 and 0 <=h <=1): return False if w < 0.01 or h < 0.01: # 过滤过小的目标 return False return True4. 数据增强的进阶策略
4.1 基础增强方法
基础的增强方法包括:
- 随机旋转(-15°到+15°)
- 亮度调整(±30%)
- 添加高斯噪声
- 随机裁剪
我常用的Albumentations配置如下:
import albumentations as A transform = A.Compose([ A.RandomRotate90(), A.Flip(p=0.5), A.RandomBrightnessContrast(p=0.2), A.HueSaturationValue(p=0.2), A.RandomShadow(p=0.1), A.RandomSnow(p=0.1), A.RandomFog(p=0.1), ], bbox_params=A.BboxParams(format='yolo'))4.2 针对非机动车的特殊增强
非机动车有几个特点需要考虑:
- 经常出现在复杂背景中
- 形状变化较大(自行车vs三轮车)
- 常有部分遮挡
我设计了一套专门的增强方案:
- 背景混合:将非机动车抠出来放到不同背景中
- 部分遮挡模拟:随机添加遮挡条
- 多车组合:将多辆车的图像合成到一张图中
这个方案使我们的模型在遮挡场景下的识别率提升了15%。
5. 数据集优化的关键步骤
5.1 数据清洗
拿到原始数据后,我通常会进行三轮清洗:
- 自动过滤:用脚本去除损坏的图片和空标签
- 人工检查:抽样检查标注质量
- 模型辅助:用预训练模型检测明显错误
清洗前后数据质量对比:
| 指标 | 清洗前 | 清洗后 |
|---|---|---|
| 空标签率 | 3.2% | 0% |
| 标注错误率 | 5.7% | 0.8% |
| 图片损坏率 | 1.1% | 0% |
5.2 类别平衡
非机动车数据集中常见的类别不平衡问题:
- 电动车样本远多于三轮车
- 正样本与负样本比例失调
我的解决方法:
- 对少数类过采样
- 使用focal loss
- 人工补充拍摄稀缺类别
最近一个项目通过这种调整,将三轮车的召回率从62%提升到了89%。
6. 实战中的经验分享
在实际项目中,我总结出几个关键点:
- 数据版本控制:像管理代码一样管理数据集版本
- 元数据记录:记录每张图片的采集时间、地点、天气等信息
- 测试集划分:确保测试集覆盖所有场景
我们团队现在使用DVC来做数据版本管理,配置大概是这样:
# 初始化DVC dvc init # 添加数据集 dvc add data/train/images dvc add data/train/labels # 设置远程存储 dvc remote add -d myremote /path/to/remote最后提醒一点:数据集构建是个迭代过程。我们通常会在模型训练过程中发现新的数据需求,比如某些角度的样本不足,或者特定场景的识别效果不好。这时候就需要回到数据采集阶段进行补充。好的数据集往往需要3-5个迭代周期才能达到理想状态。
