YOLOv8
YOLOv8
YOLOv8与YOLOv5的主要变化
- 提供了一个全新的
SOTA
模型,包括P5 640
和P6 1280
分辨率的目标检测网络和基于YOLACT
的实例分割模型。和 YOLOv5 一样,基于缩放系数也提供了 N/S/M/L/X 尺度的不同大小模型,用于满足不同场景需求 Backbone
和Neck
部分可能参考了YOLOv7 ELAN
设计思想,将YOLOv5
的C3
结构换成了梯度流更丰富的C2f
结构,并对不同尺度模型调整了不同的通道数,属于对模型结构精心微调,不再是无脑一套参数应用所有模型,大幅提升了模型性能。不过这个C2f
模块中存在Split
等操作对特定硬件部署没有之前那么友好了- Head 部分相比
YOLOv5
改动较大,换成了目前主流的解耦头结构,将分类和检测头分离,同时也从Anchor-Based
换成了Anchor-Free
- Loss 计算方面采用了
TaskAlignedAssigner
正样本分配策略,并引入了Distribution Focal Loss
- 训练的数据增强部分引入了
YOLOX
中的最后10
epoch关闭Mosiac
增强的操作,可以有效地提升精度
总的来说就是YOLOv8
结合了当下许多流行的SOTA
组件,并且在检测精度上相比YOLOv5
也得到了不少的提高
同时YOLOv8
的训练策略和YOLOv5
没有什么大区别,最大区别就是模型的训练总epoch
数从 300
提升到了500
同时,从YOLOv5
的7.0
版本开始,已经支持了目标检测
,实例分割
,分类
三种任务了
本篇文档更偏向应用方面,所以关于结构方面的详解,可以参考OpenMMLab
的知乎回答(https://zhuanlan.zhihu.com/p/598566644)
安装与使用
我这里使用的Mini Conda
,也可以使用venv
虚拟环境
首先创建虚拟环境并激活
conda create -n ultralytics python=3.10
conda activate ultralytics
有两种方式,第一种是直接使用pip
仓库中的包ultralytics
,第二种为克隆其仓库在进行安装
直接使用pip安装
直接在新的虚拟环境中输入以下命令
pip install ultralytics
按照官方的说法,该指令可以直接安装requirement.txt
中的所有modules
包括PyTorch
、CUDA Toolkit
克隆仓库进行安装
第二种我们采用git
对仓库进行克隆并进行安装
如果你对
CUDA
以及PyTorch
的版本有所需求可以直接在新创建的虚拟环境中先进行安装
使用conda
conda install pytorch torchvision torchaudio pytorch-cuda=11.6 -c pytorch -c nvidia
或者使用pip
pip3 install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu116
如果不需要可以直接从这里开始
首先克隆项目仓库
git clone https://github.com/ultralytics/ultralytics
进入该目录并进行安装
cd ultralytics
pip install -e '.[dev]'
数据集
数据集的格式与YOLOv5
、Darknet YOLOv4
等YOLO系列几乎一致
以VSAIS平台中的CLT34数据为例子
path: ../../datasets/CLT34_20220926/save
train: images
val: test/images
test: val/images
# Classes
names:
0: 车身_货车
1: 车身_泵车
2: 车身_挖掘机
3: 车身_土方车
4: 车身_面包车
·············
其中path
为数据集的路径,train
为在数据集路径下训练集的路径,这里直接填写文件夹名称即可,val
为验证集的文件夹,test
为测试集, names
即为数据集中标签的对应
如果类别过多,一个一个输入类别也比较麻烦,可以使用以下代码,自动从平台下载的JSON
文件中获取类别
f = open(jsonfilePath, "r")
json_data = json.load(f)
f.close()
category_list = json_data["label_category"]
categories = []
names = []
for category in category_list:
categories.append(category["id"])
names.append(category["name"])
print(str(categories.index(category["id"]))+ ": " + category["name"])
我们运行之后,即可在终端中得到所需内容,并复制到该YAML
文件中
语法格式
主要语法如下:
yolo task=detect mode=train model=yolov8n.yaml args...
classify predict yolov8n-cls.yaml args...
segment val yolov8n-seg.yaml args...
export yolov8n.pt format=onnx args...
如果需要多GPU
,例如需要四卡训练
可以在末位加上device=\'0,1,2,3\'
即可
因为目标检测
,实例分割
,图片分类
三种任务运行代码几乎一致,只需要替换关键词,所以不再分开赘述
详细参数等内容,还请参考官方文档 (https://docs.ultralytics.com/)
训练
以检测为例
CLI:
yolo detect train data=coco128.yaml model=yolov8l.pt epochs=500 imgsz=640 batch=8
Python:
from ultralytics import YOLO
model = YOLO("yolov8l.yaml")
model = YOLO("yolov8l.pth")
model.train(data="coco128.yaml", epochs=500, imgsz=640,batch=8)
验证
以检测为例
CLI:
yolo detect val model=path/to/best.pt
Python:
from ultralytics import YOLO
model = YOLO("model.pt")
model.val(data="coco128.yaml",batch=8)
推理
以检测为例
CLI:
yolo detect predict model=path/to/best.pt source="xxx" save=True
save=True
选项可以对结果进行保存
Python:
from ultralytics import YOLO
from PIL import Image
import cv2
model = YOLO("model.pt")
# 支持所有格式 - image/dir/Path/URL/video/PIL/ndarray. 0 for webcam
results = model.predict(source="0")
results = model.predict(source="folder", show=True) # Display preds. Accepts all YOLO predict arguments
# from PIL
im1 = Image.open("bus.jpg")
results = model.predict(source=im1, save=True) # save plotted images
# from ndarray
im2 = cv2.imread("bus.jpg")
results = model.predict(source=im2, save=True, save_txt=True) # save predictions as labels
# from list of PIL/ndarray
results = model.predict(source=[im1, im2])
包括后处理代码一些例子,官方文档(https://docs.ultralytics.com/python/)也有详细说明
模型转换与导出
U版的YOLO
模型导出功能一直都较为丰富
YOLOv8
可以支持ONNX
、TensorRT
、PaddlePaddle
、Tensorflow
等等
需要安装相关包,这里只涉及ONNX
、TensorRT
pip install onnx onnxruntime-gpu
半精度的话加上half
参数
依旧分为两种:
CLI:
yolo mode=export model=yolov8n.pt format=onnx
Python:
from ultralytics import YOLO
model = YOLO('yolov8n.yaml')
results = model.export(format='onnx')
其中format
支持的格式如下表中所示:
Format | format=argument | Model |
---|---|---|
PyTorch | - | yolov8n.pt |
TorchScript | torchscript | yolov8n.torchscript |
ONNX | onnx | yolov8n.onnx |
OpenVINO | openvino | yolov8n_openvino_model/ |
TensorRT | engine | yolov8n.engine |
CoreML | coreml | yolov8n.mlmodel |
TensorFlow SavedModel | saved_model | yolov8n_saved_model/ |
TensorFlow GraphDef | pb | yolov8n.pb |
TensorFlow Lite | tflite | yolov8n.tflite |
TensorFlow Edge TPU | edgetpu | yolov8n_edgetpu.tflite |
TensorFlow.js | tfjs | yolov8n_web_model/ |
PaddlePaddle | paddle | yolov8n_paddle_model/ |
使用训练机训练(目标检测)
由于训练机使用的是Ubuntu 18.04
,所以python-venv
的版本最高只能支持到3.6
,因为YOLOv8
的Python
最低版本为3.7
,所以我们需要安装Conda
,在两张3090的训练机
上已经安装好了miniconda
,目录位于/home/vs/miniconda3
conda
打开终端自动激活的环境的功能在这台训练机上已经进行了关闭,命令如下
conda config --set auto_activate_base false
我们依旧以CLT34
车冲数据集为例,我在~/Projects/lyz
处建立了文件夹,其中需要一个YAML
文件用于储存数据集信息
数据集的位置在/home/vs/10Tdata/CLT34/CLT34_20220926/save
中
所以文件内容如下
# Ultralytics YOLO 🚀, GPL-3.0 license
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: /home/vs/10Tdata/CLT34/CLT34_20220926/save # dataset root dir
train: images # train images (relative to 'path') 6471 images
val: test/images # val images (relative to 'path') 548 images
test: val/images # test images (optional) 1610 images
# Classes
names:
0: 车身_货车
1: 车身_泵车
2: 车身_挖掘机
3: 车身_土方车
4: 车身_面包车
...........
关于训练,依据我们上面的内容,可以使用python文件,也可以直接在终端中输入指令开始训练
CLI:
yolo detect train data=CLT34_20220926.yaml model=yolov8x.pt epochs=500 imgsz=640 batch=16 device=0
Python:
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8x.yaml") # build a new model from scratch
model = YOLO("yolov8x.pt") # load a pretrained model (recommended for training)
# Train the model
model.train(data="CLT34_20220926.yaml", epochs=500, imgsz=640, batch=16, device=0)
训练完毕后进行模型导出为ONNX
可以输入
yolo mode=export model=runs/train/weights/best.pt format=onnx
也可以转TensorRT
的engine
格式
yolo mode=export model=runs/train/weights/best.pt format=engine
训练完后推理
python文件:
from ultralytics import YOLO
model = YOLO("best.onnx")
result = model(source)
这里source
可以是一张图片,一段视频,一个文件夹(将会自动推理文件夹内的内容),摄像头
相关问题与解决方案
训练期间会遇到关于libcublasLt.so.11
有关的环境问题
我们只需要在终端中输入以下命令即可
export LD_LIBRARY_PATH=/home/vs/miniconda3/envs/ultralytics/lib/python3.10/site-packages/nvidia/cublas/lib/:$LD_LIBRARY_PATH
训练机网络联通问题
训练机不清楚什么情况,目前终端自带代理功能,而且代理服务器已经挂了
如果使用网络,可以使用内网代理,如果你的电脑有代理,并且支持局域网代理
可以在终端中输入以下指令
export http_proxy=http://ip_address:port
export https_proxy=http://ip_address:port
其中ip_address
和port
均需要改成自己电脑,ip_address
为自己电脑的局域网IP
,port
为代理软件的端口
如需预训练模型,在/home/vs/Projects/lyz/
目录下有YOLOv8
五个预训练模型
实例分割训练实例
这里采用公司的数据集soil cover
,裸土覆盖数据集为例
我们只需要准备好数据集的YAML
文件,由于之前的数据集增强工具只能对目标检测的标签进行转换,所以我写了一个工具,可以将下载下来的JSON
格式标签转化为txt
即为YOLO
格式,详情请见另一篇文档
soil_cover.yaml
:
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../../datasets/soil_cover_new/ # dataset root dir
train: train/images/ # train images (relative to 'path') 128 images
val: test/images/ # val images (relative to 'path') 128 images
test: # test images (optional)
# Classes
names:
0: soil
1: green network
2: steel plate
3: concrete
4: water
5: excavator
.........
训练指令:
from ultralytics import YOLO
model = YOLO('yolov8n-seg.pt') # load a pretrained YOLOv8n segmentation model
model.train(data='data_cfg/soil_cover.yaml', epochs=100) # train the model
最后推理:
from ultralytics import YOLO
model = YOLO('runs/segment/train/weights/best.pt') # load a pretrained YOLOv8n segmentation model
model.predict(source="xxxxxx", save=True) # train the model
分类任务
训练推理指令和上面检测和分割大差不差,这里不再详细叙述
追踪任务
YOLOv8
自带追踪功能,官方文档。不过也是从这两个版本也才开始支持的。
官方可以支持两个Tracker
,分别为BoT-SORT
和ByteTrack
默认选项为BoT-SORT
不过,官方自带的追踪功能是不带ReID
的
ReID
是什么?ReID
可以简单理解为是一个独立的特征提取网络
这里将通过两个例子介绍YOLOv8
的追踪功能
官方支持
通过使用模型的不同,可以实现追踪以及追踪+分割
想实现后者的功能,直接使用其官方分割模型即可
目前可能是官方bug,使用8.0.44
版本在运行下方代码会报错,使用8.0.43
版本即可
命令如下
yolo track model=yolov8s-seg.pt source=test.mp4 show device=0
show
表示是否以窗口形式进行实时展示追踪结果,device
表示使用设备,gpu的话直接加数字即可,如果使用cpu,device=cpu
以Detecron2
的追踪demo视频为例,将会呈现如下的效果
同时,也支持其他格式的模型,例如ONNX
、TensorRT
转换代码如下:
FP16 TensorRT:
yolo export model=yolov8s-seg.pt format=engine device=0 half
ONNX:
yolo export model=yolov8s-seg.pt format=onnx device=0
这里也有一个对推理速度的测试,使用的是YOLOv8s-seg
模型
结果如下:
pt | ONNX | TensorRT FP32 | TensorRT FP16 | |
---|---|---|---|---|
Speed | 6.6ms | 14.1ms | 7.2ms | 2.5ms |
YOLOV8_tracking
仓库链接如下:
YOLOV8_tracking(https://github.com/mikel-brostrom/yolov8_tracking)
和上面说的官方支持,最大的区别是添加了一个ReID
,用作特征提取网络,按作者说可以增加准确率,经过测试
左图为YOLOV8_tracking
项目,右图为YOLOv8官方追踪算法
可以看出两者的准确度基本上来说半斤八两
关于检测速度的对比,因为YOLOV8_tracking
项目还套了一层特征提取网络导致速度上肯定不及官方
结果如下:YOLOV8
:
video 1/1 (1049/1050) /home/kk/Projects/yolov8_tracking/test.avi: 384x640 17 persons, 1 bicycle, 1 car, 1 motorcycle, 1 handbag, 21.0ms
video 1/1 (1050/1050) /home/kk/Projects/yolov8_tracking/test.avi: 384x640 17 persons, 1 bicycle, 1 car, 1 motorcycle, 1 handbag, 22.3ms
Speed: 0.2ms preprocess, 22.3ms inference, 1.5ms postprocess per image at shape (1, 3, 640, 640)
YOLOV8_tracking
:
video 1/1 (1049/1050) /home/kk/Projects/yolov8_tracking/test.avi: 384x640 13 persons, 1 bicycle, 1 car, 46.4ms
video 1/1 (1050/1050) /home/kk/Projects/yolov8_tracking/test.avi: 384x640 13 persons, 1 bicycle, 1 car, 46.3ms
Speed: 0.2ms pre-process, 21.6ms inference, 0.6ms NMS, 24.5ms botsort update per image at shape (1, 3, 640, 640)
可以看出YOLOV8_tracking
的每一帧数要0.2 + 21.6 + 0.6 + 24.5 = 46.9ms
,YOLOV8
则为0.2 + 22.3 + 1.5 = 24.0ms
,几乎差了一倍之多