3、工业数据集准备:数据采集规范、标注工具使用、数据集目录结构、Train/Val/Test划分

各位同学,欢迎来到第三章。前两章我们聊了YOLOv6的架构和部署环境,今天咱们来干点「脏活累活」——准备数据集。

说实话,我见过太多项目死在数据准备这一步。模型选得再好,代码写得再漂亮,数据一塌糊涂,结果就是白忙活。我自己就踩过这个坑,所以这一章,我会把压箱底的经验都掏出来。

3.1 数据采集规范:别让「垃圾数据」毁了你的模型

数据采集,听起来简单,不就是拍照吗?其实门道很多。我刚开始做工业检测时,以为随便拍几张照片就能训练,结果模型在产线上直接「翻车」。

核心原则:数据要能覆盖真实场景的所有变化。

具体来说,你得考虑以下几点:

  • 光照条件:产线上的光照不是恒定的。白天、夜晚、灯光老化、甚至操作员影子挡住光源,都会影响图像。我建议你采集时,刻意在不同时段、不同角度光源下拍摄。
  • 拍摄角度与距离:相机安装位置可能有微小偏差。别只拍「标准姿势」,稍微偏一点、远一点、近一点的数据都要有。我曾经有个项目,模型在实验室跑得飞起,一上产线就漏检,最后发现是相机支架被碰歪了2度。
  • 背景干扰:工业现场背景复杂,有传送带纹理、油污、甚至飞虫。你的训练数据里,最好包含这些「干扰项」。说白了,要让模型学会在嘈杂环境中找到目标。
  • 缺陷多样性:工业缺陷往往形态各异。比如划痕,有深有浅、有长有短、有直有弯。每种缺陷至少采集几百个样本,否则模型学不到「全貌」。

我的经验之谈:数据采集阶段,宁可多拍,不要少拍。后期发现数据不够,再补拍的成本是前期的10倍。我一般会多采集30%的冗余数据,留着备用。

3.2 标注工具:LabelImg vs CVAT,我该选哪个?

标注工具,说白了就是给图片里的目标「画框」并「起名字」。工业检测中,最常用的两个工具是LabelImg和CVAT。

LabelImg:轻量级,适合单兵作战

LabelImg是个基于Python的桌面软件,安装简单,打开即用。我个人习惯用它来做小规模数据集的快速标注。

  • 优点:轻量、离线可用、支持PascalVOC和YOLO格式
  • 缺点:不支持多人协作、没有自动标注功能

CVAT:企业级,适合团队协作

CVAT是Intel开源的在线标注平台,功能强大。如果你团队有3个以上标注员,我强烈建议用CVAT。

  • 优点:支持多人同时标注、有自动跟踪和半自动标注功能、支持多种导出格式
  • 缺点:需要部署服务器,学习曲线稍陡

我的建议:初期项目或个人学习,用LabelImg就够了。如果是企业级工业项目,直接上CVAT。我曾经帮一家工厂搭建标注流水线,用CVAT后标注效率提升了3倍。

标注规范:统一标准,避免「一人一个样」

标注最怕什么?最怕标准不统一。同一个缺陷,张三标成「scratch」,李四标成「scratch_small」,模型就懵了。

我建议你制定一份《标注规范文档》,明确以下几点:

  • 类别名称统一:比如「划痕」统一用「scratch」
  • 标注框规则:框要紧紧包住目标,还是留一点边?我一般要求框的边缘离目标轮廓不超过2个像素
  • 遮挡处理:目标被遮挡超过50%时,是否标注?我的规则是:遮挡超过70%就不标,否则标
  • 边缘目标:目标在图像边缘被截断,怎么标?我建议正常标注,但框不能超出图像边界

避坑指南:我曾经有个项目,标注员把「正常产品」也标成了「背景」类别,导致模型把正常产品误检为缺陷。记住:背景不需要标注,只标注你关心的目标。

3.3 数据集目录结构:整洁的目录,是项目成功的基石

你想想看,一个工业检测项目,数据集可能有几万张图片,几十个类别。如果目录乱成一锅粥,后期找数据、改配置、做实验,都会让你崩溃。

我推荐使用YOLO官方推荐的标准目录结构:

dataset/
├── images/
│   ├── train/
│   │   ├── 000001.jpg
│   │   ├── 000002.jpg
│   │   └── ...
│   ├── val/
│   │   ├── 000100.jpg
│   │   └── ...
│   └── test/
│       ├── 000200.jpg
│       └── ...
├── labels/
│   ├── train/
│   │   ├── 000001.txt
│   │   ├── 000002.txt
│   │   └── ...
│   ├── val/
│   │   ├── 000100.txt
│   │   └── ...
│   └── test/
│       ├── 000200.txt
│       └── ...
└── data.yaml

注意几点:

  • 图片和标注文件一一对应,文件名相同,后缀不同
  • 标注文件是txt格式,每行一个目标:class_id x_center y_center width height(归一化坐标)
  • data.yaml文件定义类别名称和路径

data.yaml示例:

train: ./dataset/images/train
val: ./dataset/images/val
test: ./dataset/images/test

nc: 3
names: ['scratch', 'dent', 'crack']

我的习惯:我会在dataset目录下再放一个README.md文件,记录数据来源、采集日期、标注人员、版本号等信息。半年后你回头看,会感谢自己这个习惯。

3.4 Train/Val/Test划分:别让模型「作弊」

数据集划分,说白了就是决定哪些数据用来训练、哪些用来验证、哪些用来最终测试。这个环节做不好,模型的评估结果就是「虚假繁荣」。

划分比例:工业场景下,我一般用70%训练、15%验证、15%测试。如果数据量特别大(比如10万张以上),可以调整为80%、10%、10%。

划分原则:随机且分层

不能简单随机打乱就完事。你要保证每个类别在训练集、验证集、测试集中的比例大致相同。比如「划痕」类占总数20%,那它在三个子集中的比例也应该是20%左右。

我写过一个简单的Python脚本做分层抽样:

import os
import random
from sklearn.model_selection import train_test_split

# 假设你有所有图片的路径列表和对应的类别标签
images = [...]  # 图片路径列表
labels = [...]  # 对应的类别ID列表

# 先分出测试集
train_val_images, test_images, train_val_labels, test_labels = train_test_split(
    images, labels, test_size=0.15, stratify=labels, random_state=42
)

# 再从剩余数据中分出训练集和验证集
train_images, val_images, train_labels, val_labels = train_test_split(
    train_val_images, train_val_labels, test_size=0.176, stratify=train_val_labels, random_state=42
)
# 0.176 = 0.15 / 0.85,保证验证集占总数据的15%

避坑指南:千万不要在划分前对数据进行任何「数据增强」操作!增强后的数据如果混入验证集或测试集,模型相当于提前看到了「变形版」的测试数据,评估结果会虚高。我刚开始做时犯过这个错,后来被导师狠狠批了一顿。

时间序列数据要特殊处理

如果你的数据是按时间顺序采集的(比如产线每天拍一批),那不能随机划分。你应该用前70%的时间段数据做训练,中间15%做验证,最后15%做测试。这样才能模拟模型在「未来数据」上的表现。

嗯,这一章的内容就到这里。数据准备是枯燥的,但也是最重要的。下一章,我们会正式进入YOLOv6的模型训练环节,到时候你会感谢今天认真准备数据的自己。