一、背景
yolov8 推出之后,官方代码仓库结构发生了比较大的变化,虽然更有利于上手操作,几行代码即可开启训练,但代码修改也变得繁琐一些,且在使用之前需要安装 ultralytics 库,该仓库中包含yolov3 到11的所有模型,任务类型有分类、检测、分割、关键点等,还提供了像目标计数、停车位管理等常用场景的样例,可谓相当全面。但考虑到自己的实际需求,可能只是需要用到分割这一个功能,且模型也只用到 yolov8-seg,使用场景也是定制化场景,同时考虑到后面需要将代码迁移到边缘设备,整合到业务逻辑当中,所以代码结构越简洁越好,因此需要手动修改代码结构,特此记录一下修改过程中遇到的一些问题和解决方法。
建议先看总结部分
二、训练自定义数据集
官方仓库:Ultralytics YOLO11 🚀
数据集:传送带异物检测及物料跑偏检测_数据集-飞桨AI Studio星河社区
1. 准备数据集
yolov8-seg 需要的分割数据集格式如下:
每1行表示1个目标,每行中的第一个值表示目标类别,后面为分割区域(归一化后)的坐标值,使用 labelme 等工具标注之后写个转换脚本转换一下就可以得到标签数据了。官方也提供了一个 JSON 到 YOLO 的转换脚本。最终数据集的存放格式如下:
|--dataset
|--images
|--train
|--img1.jpg
|--img2.jpg
...
|--val
|--img1.jpg
|--img2.jpg
...
|--labels
|--train
|--img1.txt
|--img2.txt
...
|--val
|--img1.txt
|--img2.txt
...
2. 模型训练
(1)安装 ultralytics 库
pip install ultralytics
(2)下载预训练权重
如果用的是 yolo11 系列,可以在仓库首页下载,其他版本模型可以到Ultralytics官网上选择Models,找对应版本的模型下载即可。
(3)准备数据集配置文件
在 cfg/datasets 下新建一个 yaml 文件,填写自定义数据集路径和类别信息
path: /path/to/your/dataset/root/dir
train: images/train # 训练集
val: images/val # 验证集
test: images/test # 测试集(可选)
names:
0: person
1: bicycle
2: car
3: motorcycle
4: airplane
5: bus
6: train
7: truck
8: boat
9: traffic light
10: fire hydrant
11: stop sign
...
(4)训练
以下代码会根据模型文件自动识别模型结构和任务类型
from ultralytics import YOLO
# 加载预训练权重
model = YOLO("path/to/your/pretrained/model")
# 训练
results = model.train(data="path/to/your_dataset.yaml", epochs=, imgsz=640)
只做分割训练
from models.yolo.segment import SegmentationTrainer
trainer = SegmentationTrainer()
trainer.train()
三、不安装 ultralytics 库训练(不建议参考)
1. 下载代码仓库
如果不安装 ultralytics,就需要下载代码仓库,其中主要用到的就是 ultralytics 文件夹,实际 ultralytics 库也就是下载的代码仓库,程序当中需要的库默认到 ultralytics 库路径下的 ultralytics 文件下下查找。如果既安装了 ultralytics 又下载了代码,则在当前代码中所做的修改(比如修改训练参数,/cfg/models/default.yaml)均不生效,只有对 ultralytics 库路径(anaconda3/envs/seg/lib/python3.8/site-packages/ultralytics/ultralytics)下的代码做修改才会生效,有点不太方便。
2. 修改训练参数
官方代码默认使用预训练权重,默认开启 amp,且检查 amp 默认使用 yolo11n,如果没有下载 yolo11n 则会自动安装。以上功能都可在训练配置文件(default.yaml)或者训练脚本(model.train中修改对应参数值)中修改。
(1)不使用预训练权重
pretrained=False,加载权重文件的代码改为加载模型结构文件
model = YOLO("path/to/model.yaml")
(2) 修改 amp 配置
不使用 amp,则 amp=False 即可,如果使用 amp 但不使用默认11n模型,需要修改utils/checks.py,Line 692,将 "yolo11n.pt" 改为 model.args.model
3. 修改 ultralytics 文件夹名
ultralytics 文件夹中存放的是主要代码,但 ultralytics 这个名字与预训练权重是绑定的,官方提供的预训练权重的层信息中包含 ultralytics 关键字,所以如果修改了 ultralytics 这个文件夹的名字(像我只用 yolov8 做分割,就把 ultralytics 改成 yolov8_seg)在加载模型时则会报错,且所有文件中的导库命令都是从 ultralytics 开始的,因此一旦修改了 ultralytics 这个名字,则所有与ultralytics 相关的导库语句需要修改为自定义名字。
注:一旦修改了 ultralytics 这个名字,官方提供的预训练权重就用不了了,只能重新训练模型,这样训练出来的模型层结构信息中的 ultralytics 就会被替换为自定义名字,此时可以将该模型作为预训练权重作为后续训练使用。
实测在自定义数据集上训练,使用相同 epoch 和 batchsize,使用官方预训练权重,收敛速度和检测效果确实比 train from scratch 要好一些,这么看如果数据多了还是利大于弊,显得这不工作没啥大用😂,好在在自己的数据集上多训练几个 epoch 效果也差不多。
labels.jpg
pred.jpg
四、总结
亲测按照三中的方式修改代码后,程序只能从 PyCharm 中正常运行,在 terminal 中以命令行方式执行会报 ModuleNotFoundError,后面又继续修改,将不同文件下的 __init__.py 删掉,或者将其改名,防止循环导入,__init__.py 一旦修改之后所有文件中的导库语句又要修改,同时为防止库名重复问题又将部分文件(主要是 utils.py)改名,折腾了好一会最后终于能在 terminal 中训练了,同时层结构信息中的yolo_seg关键字也没了,这样的话名字也可以随便改了。
因为没安装Ultralytics,训练时会打印警告信息,可以在 nn/tasks.py 注释掉 Line850-855,Line856 也可以注释掉,跳过模块检查部分。
如果想换其它模型比如 yolo11,只需在配置文件中修改模型文件路径即可。
第三章不建议参考,还是好好用官方代码训练方便些,本人纯属瞎折腾,大佬勿喷。