一、概述

  本文章主要讲述如何实现“快速”完成数据集标注工作,原理是:利用已标注的数据,预训练模型,辅助标注数据集剩下来的部分。容易踩坑的我会用红色字体提醒。建议先看完一遍再开始动手。

二、准备

2.1 数据集

  • 不要求比例,1:1或16:9都可以
  • 预训练的每类标注推荐每类100次左右
  • 一张图片可以包含不同种类kfs,并且推荐多种类放一张图里
  • 建议将数据集多分成几个文件夹,方便操作,也没必要像我这么夸张 😝
kfs-1.png
kfs-1.png
kfs-2.png
kfs-2.png

2.2 一些脚本

下载链接①
下载链接②
脚本简要说明:

match_label.py       # 将本地标注映射为31类标准格式
check_label.py       # 检查标准化后的数据集包含哪些类别
find_label.py        # 查找含有指定类别的图片
count_label.py       # 统计每个类别的标注框数量
auto_divide.py       # 按类别均衡划分训练/验证集
auto_label.py        # 用训练好的模型自动生成标签
txt2json.py          # 将YOLO txt标签转为JSON格式(可选)
train_yolo.py        # 启动YOLO训练
classes.txt          # 标准
requirments.txt      # 依赖清单

2.3 确定规则

  请一定确保最后上传的数据集与 2.2 下载的压缩包中的classes.txt对应,可以使用check_label来确认。稍后会说到如何进行转化。

2.4 标注工具

  各取所好吧,我用的AnyLabeling

三、开始

3.1 预标注

  将部分数据集的文件夹用标注软件打开(AnyLabeling例),推荐按类标注,即先选择具体一类一直标完所有图片,再从第一张图片开始标注第二类,以此类推,可有效避免标错情况,提升效率。觉得数量足够就进入下一步(建议每类100次标注左右,否则极有可能识别不出来,竹篮打水一场空 )

3.2 转化

  由3.1导出的数据集文件夹结构如下:

data/
├─ images/
│  ├─ 001.jpg
│  ├─ 002.jpg
│  ├─ ···
├─ labels/
│  ├─ 001.txt  
│  ├─ 002.txt  
│  ├─ ···
└─ classes.txt  # 导出时生成的,不是标准classes.txt

  由于导出的classes.txt随机(也许可以调,我另辟蹊径),所以labels的ID必然与标准不同,这时需要用脚本转化。运行前请修改相关参数,流程如下:

运行match_label.py,根据data文件夹下的
classes.txt文件自动生成标准`data_标准`
文件夹,直接合并即可
            │
            ▼
(可选)运行check_label.py,根据当前目录下
的classes.txt文件,输出labels包含了哪些
标签,以此判断是否正确
            │
            ▼
(可选)运行find_label.py,修改需要查询
的ID,可以查找并统计哪些图片包含所查询的
标签,并输出文件名
            │
            ▼
(可选)运行count_label.py,可以统计31类标
签的标注次数
            │
            ▼
将标注的部分数据集合并(如果拥有多个文件夹)

3.3 预训练

请先配置虚拟环境,requirements.txt依赖清单文件
pip install -r requirements.txt

3.3.1 文件夹结构

  创建如下所示的文件夹结构

KFS/
├─ train/
│  ├─ images/            # 放置标注好的所有图片
│  └─ labels/            # 与图片对应的YOLO格式txt标签
├─ unlabeled/
│  └─ images/            # 未标注的图片
├─ train_yolo.py         # 训练程序
└─ data.yaml             # 训练配置文件(新建)

3.3.2 划分验证集

  一定要有验证集,要不然很容易过拟合!划分前请考虑需要多少比例的验证集,100张左右的话我推荐每类10%的验证集。如果随机划分,会导致每类验证集失衡,这里使用auto_divide.py划分。设置参数并运行,自动创建验证集并显示占比。

⚠️ auto_divide.py 执行的是 移动文件,不是复制。一旦运行,原始 train/ 中的图片和标签会被移入 val/。 运行前务必备份整个数据集,且不要对已划分过的数据集再次运行。
# ===================== 参数配置 =====================
DATASET_ROOT = r"."           # 数据集根目录
VAL_RATIO = 0.1               # 每类验证集最低占比(0.1对应10%)
RANDOM_SEED = 45              # 随机种子,方便复现,随便写一个

# 模式选择:True=自动模式(使用数据集中所有出现的类别),False=指定模式
AUTO_MODE = False

# 当 AUTO_MODE = False 时,指定要参与的类别ID列表
TARGET_CLS_IDS = [8, 10, ···] # 替换成需要训练的类别

3.3.3 编写训练配置文件

  在KFS根目录新建data.yaml,复制以下内容:

path: .
train: train/images
val: val/images       # 辅助标注训练也需要验证集,要不然很容易过拟合
nc: 31
names:
  0: R1
  1: T_01
  2: T_02
  3: T_03
  4: T_04
  5: T_05
  6: T_06
  7: T_07
  8: T_08
  9: T_09
  10: T_10
  11: T_11
  12: T_12
  13: T_13
  14: T_14
  15: T_15
  16: F_01
  17: F_02
  18: F_03
  19: F_04
  20: F_05
  21: F_06
  22: F_07
  23: F_08
  24: F_09
  25: F_10
  26: F_11
  27: F_12
  28: F_13
  29: F_14
  30: F_15

3.3.4 编写训练配置脚本

  使用train_yolo.py进行训练。这里引入了patience早停参数,程序内部参数也可根据实际情况进行修改。

3.3.5 启动训练

请先进入虚拟环境

  进入Pycharm(VS Code或者终端都行),运行train_yolo.py,等待训练结束即可。

3.3.6 提取训练完成的模型

  训练结束后,在以下路径获取最优模型:

./runs/detect/train-?/weights/best.pt   # ?取最大的数字

3.4 自动标注

  修改auto_label.py中模型路径,运行,生成labels文件夹,即YOLO格式。如需转化成json格式,运行txt2json.py即可(格式转化仅适用我的环境,这里只提供一种思路,请根据源码稍作修改再使用)

#四、结尾

  打开标注软件,切换相应格式(我用json),进行检查和修正步骤,手动增删改。