【YOLOv8教程】(手把手详细版,支持训练自定义数据集),包含环境配置、数据配置、训练、预测、验证、导出
文章目录
1.环境配置
- Ubuntu 18.04
- CUDA 11.0.3
- Python 3.8.5
- Pytorch 1.7.1
- torchvision 0.8.2
进入虚拟环境,安装YOLOv8,官方给了两种安装方式:
第一种(推荐)
pip install
pip install ultralytics
第二种
git clone
git clone https://github.com/ultralytics/ultralytics
cd ultralytics
pip install -e .
2.准备自己的数据
(1)文件目录结构
有四个文件夹dataset, images, labels, xml
dataset 数据集划分train.txt, val.txt, trainval.txt, test.txt
images 存放图片
labels 存放标注txt文件
xml 存放标注xml文件
└── one
├── dataset
├── images
├── labels
└── xml
(2)一个文件夹中不同后缀名的文件分离出来
例如.img, .txt, .xml
import os
import shutil
path_xml = "/home/wanglu/detection/one/1jiwei"
filelist = os.listdir(path_xml)
path1 = "/home/wanglu/detection/one/1jiweiimages/"
path2 = "/home/wanglu/detection/one/1jiweilabels/"
path3 = "/home/wanglu/detection/one/1jiweixml/"
for files in filelist:
filename1 = os.path.splitext(files)[1] # 读取文件后缀名
filename0 = os.path.splitext(files)[0] #读取文件名
# print(filename1)
# m = filename1 == '.txt'
# print(m)
if filename1 == '.txt' :
full_path = os.path.join(path_xml, files)
despath = path2 + filename0 +'.txt' #.txt为你的文件类型,即后缀名,读者自行修改
shutil.move(full_path, despath)
if filename1 == '.jpg':
full_path = os.path.join(path_xml, files)
despath = path1 + filename0 + '.jpg' #.jpg为你的文件类型,即后缀名,读者自行修改
shutil.move(full_path, despath)
if filename1 == '.xml':
full_path = os.path.join(path_xml, files)
despath = path3 + filename0 + '.xml' # .xml为你的文件类型,即后缀名,读者自行修改
shutil.move(full_path, despath)
(3)数据集划分
新建split_train_val.py文件,生成上述dataset文件夹中train.txt, val.txt, trainval.txt, test.txt文件
# coding:utf-8
import os
import random
import argparse
parser = argparse.ArgumentParser()
#xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
parser.add_argument('--xml_path', default='/home/wanglu/detection/one/one/xml', type=str, help='input xml label path')
#数据集的划分,地址选择自己数据下的ImageSets/Main
parser.add_argument('--txt_path', default='/home/wanglu/detection/one/one/dataset', type=str, help='output txt label path')
opt = parser.parse_args()
trainval_percent = 0.9
train_percent = 0.8
xmlfilepath = opt.xml_path
txtsavepath = opt.txt_path
total_xml = os.listdir(xmlfilepath)
if not os.path.exists(txtsavepath):
os.makedirs(txtsavepath)
num = len(total_xml)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)
file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w')
for i in list_index:
name ='/home/wanglu/detection/one/one/images/' + total_xml[i][:-4] + '.jpg\n'
if i in trainval:
file_trainval.write(name)
if i in train:
file_train.write(name)
else:
file_val.write(name)
else:
file_test.write(name)
file_trainval.close()
file_train.close()
file_val.close()
file_test.close()
(4)新建数据配置文件
在ultralytics/ultralytics/datasets/文件夹下新建dengjianji.yaml
文件路径
ultralytics/ultralytics/datasets/dengjianji.yaml
train: # train images (relative to 'path')
/home/wanglu/detection/one/one/dataset/trainval.txt
val: # val images (relative to 'path')
/home/wanglu/detection/one/one/dataset/test.txt
test: # test images (optional)
/home/wanglu/detection/one/one/dataset/test.txt
# number of classes
nc: 20
# Classes
names:
0: ganjing
1: guahua
2: liewen_pingshen
3: heidian
4: liangshao
5: jingshangfen
6: gouya
7: juzui
8: gehen
9: lvgai
10: zhabutie
11: gaisong
12: quegai
13: pingzi
14: liewen_pingdi
15: bianxing
16: liang
17: aoxian
18: xianglianhuan
19: ganjing_fx
至此数据集的准备已经完成,可以开始训练啦!
3. 模型训练、验证、预测、导出
3.1 训练
YOLOv8 训练介绍
CLI命令行训练(推荐)
yolo task=detect mode=train model=yolov8n.pt args...
classify predict yolov8n-cls.yaml args...
segment val yolov8n-seg.yaml args...
export yolov8n.pt format=onnx args...
(1)单卡训练
(2)多卡训练
直接指定device=‘0, 1, 2, 3’,即可实现多卡训练
多卡训练错误可能会抛出错误:barrier() got an unexpected keyword argument ‘device_ids’
更改/root/miniconda3/lib/python3.8/site-packages/ultralytics/yolo/utils/torch_utils.py
@contextmanager
def torch_distributed_zero_first(local_rank: int):
"""Decorator to make all processes in distributed training wait for each local_master to do something."""
initialized = torch.distributed.is_available() and torch.distributed.is_initialized()
if initialized and local_rank not in (-1, 0):
# dist.barrier(device_ids=[local_rank])
dist.barrier()
yield
if initialized and local_rank == 0:
# dist.barrier(device_ids=[0])
dist.barrier()
(3)使用预训练模型
pretrained=True即可
训练参数见下表:
名称 | 默认值 | 描述 |
---|---|---|
batch | 16 | 训练的批量大小 |
model | null | 训练模型权重,可指定具体位置,如yolov8n.pt,yolov8n.yaml等 |
epochs | 100 | 训练的轮次 |
imgsz | 640 | 输入图像压缩后的尺寸 |
device | null | 用于训练的设备,可选0或1或cpu等 |
workers | 8 | 多线程数据加载,默认8 |
data | null | 数据路径,使用自定义的yaml文件或者官方yaml |
lr0 | float | 初始学习率 |
lrf | float | 最终学习率(lr0 * lrf) |
patience | 50 | 早期训练时,准确率如果没有显著上升则停止的轮次 |
save | True | 是否需要保存训练的模型和预测结果 |
cache | False | 使用缓存进行数据加载,可选True/ram, disk 或者 False |
project | null | 项目名称 |
name | null | 实验的名称 |
exist_ok | False | 是否覆盖现有实验 |
pretrained | False | 是否使用预训练模型 |
optimizer | ‘SGD’ | 优化器,可选[‘SGD’, ‘Adam’, ‘AdamW’, ‘RMSProp’] |
verbose | False | 是否打印详细输出 |
seed | 0 | 重复性实验的随机种子 |
deterministic | True | 是否启用确定性模式 |
single_cls | False | 是否将多类数据训练为单类 |
image_weights | False | 是否使用加权图像选择进行训练 |
rect | False | 是否支持矩形训练 |
cos_lr | False | 是否使用余弦学习率调度器 |
close_mosaic | 10 | 禁用最后 10 个 epoch 的马赛克增强 |
resume | False | 是否从上一个检查点恢复训练 |
lr0 | 0.01 | 初始学习率(SGD=1E-2, Adam=1E-3) |
lrf | 0.01 | 余弦退火超参数 (lr0 * lrf) |
momentum | 0.937 | 学习率动量 |
weight_decay | 0.0005 | 权重衰减系数 |
warmup_epochs | 3.0 | 预热学习轮次 |
warmup_momentum | 0.8 | 预热学习率动量 |
warmup_bias_lr | 0.1 | 预热学习率 |
box | 7.5 | giou损失的系数 |
cls | 0.5 | 分类损失的系数 |
dfl | 1.5 | dfl损失的系数 |
fl_gamma | 0.0 | 焦点损失的gamma系数 (efficientDet默认gamma=1.5) |
label_smoothing | 0.0 | 标签平滑 |
nbs | 64 | 名义批次,比如实际批次为16,那么64/16=4,每4 次迭代,才进行一次反向传播更新权重,可以节约显存 |
overlap_mask | True | 训练期间掩码是否重叠(仅限分割训练) |
mask_ratio | 4 | 掩码下采样率 (仅限分割训练) |
dropout | 0.0 | 使用 dropout 正则化 (仅限分类训练) |
3.2 验证
名称 | 默认值 | 描述 |
---|---|---|
val | True | 在训练期间验证/测试 |
save_json | False | 将结果保存到 JSON 文件 |
save_hybrid | False | 保存标签的混合版本(标签+附加预测) |
conf | 0.001 | 用于检测的对象置信度阈值(预测时默认 0.25 ,验证时默认0.001) |
iou | 0.6 | NMS 的交并比 (IoU) 阈值 |
max_det | 300 | 每张图像的最大检测数 |
half | True | 使用半精度 (FP16) |
dnn | False | 使用 OpenCV DNN 进行 ONNX 推理 |
plots | False | 在训练期间显示图片 |
3.3 预测
source 为图像路径,或者使用摄像头source=0
名称 | 默认值 | 描述 |
---|---|---|
source | ‘ultralytics/assets’ | 图片或视频的源目录 |
save | False | 是否保存结果 |
show | False | 是否显示结果 |
save_txt | False | 将结果保存为 .txt 文件 |
save_conf | False | 保存带有置信度分数的结果 |
save_crop | Fasle | 保存裁剪后的图像和结果 |
conf | 0.3 | 置信度阈值 |
hide_labels | False | 隐藏标签 |
hide_conf | False | 隐藏置信度分数 |
vid_stride | False | 视频帧率步幅 |
line_thickness | 3 | 边界框厚度(像素) |
visualize | False | 可视化模型特征 |
augment | False | 将图像增强应用于预测源 |
agnostic_nms | False | 类别不可知的 NMS |
retina_masks | False | 使用高分辨率分割蒙版 |
classes | null | 只显示某几类结果,如class=0, 或者 class=[0,2,3] |
3.4 导出
新建export.py,终端运行
注意指定opset, 本人指定opset=11
from ultralytics import YOLO
model = YOLO('/home/wanglu/runs/detect/train3/weights/best.pt')
model.export(format='engine', dynamic=True, opset=11, device=0)
参数见下表:
Key | Value | Description |
---|---|---|
format | 'torchscript' | format to export to |
imgsz | 640 | image size as scalar or (h, w) list, i.e. (640, 480) |
keras | False | use Keras for TF SavedModel export |
optimize | False | TorchScript: optimize for mobile |
half | False | FP16 quantization |
int8 | False | INT8 quantization |
dynamic | False | ONNX/TensorRT: dynamic axes |
simplify | False | ONNX/TensorRT: simplify model |
opset | None | ONNX: opset version (optional, defaults to latest) |
workspace | 4 | TensorRT: workspace size (GB) |
nms | False | CoreML: add NMS |
可用的YOLOv8导出格式如下表所示。您可以使用format参数导出为任何格式,即format='onnx’或format=‘engine’。
Format | format Argument | Model | Metadata | Arguments |
---|---|---|---|---|
PyTorch | - | yolov8n.pt | ✅ | - |
TorchScript | torchscript | yolov8n.torchscript | ✅ | imgsz , optimize |
ONNX | onnx | yolov8n.onnx | ✅ | imgsz , half , dynamic , simplify , opset |
OpenVINO | openvino | yolov8n_openvino_model/ | ✅ | imgsz , half |
TensorRT | engine | yolov8n.engine | ✅ | imgsz , half , dynamic , simplify , workspace |
CoreML | coreml | yolov8n.mlmodel | ✅ | imgsz , half , int8 , nms |
TF SavedModel | saved_model | yolov8n_saved_model/ | ✅ | imgsz , keras |
TF GraphDef | pb | yolov8n.pb | ❌ | imgsz |
TF Lite | tflite | yolov8n.tflite | ✅ | imgsz , half , int8 |
TF Edge TPU | edgetpu | yolov8n_edgetpu.tflite | ✅ | imgsz |
TF.js | tfjs | yolov8n_web_model/ | ✅ | imgsz |
PaddlePaddle | paddle | yolov8n_paddle_model/ | ✅ | imgsz |