这一部分内容主要介绍如何使用YOLOv8训练自己的数据集,并进行验证、预测及导出,采用代码和指令的两种方式,参考自官方文档:Detect - Ultralytics YOLOv8 Docs。实践篇不需要关注原理,只需要把流程跑通就行,所有的疑惑会在原理篇进行解释。
1.数据准备
1.1划分训练集和验证集
数据准备就是把标注好的数据,按照一定的比例划分成训练集和验证集,并且将训练集和验证集按照YOLO的格式来存放,方便训练的时候读取数据,如下图所示,train训练集中包含有images和labels两个文件夹,val验证集中包含有images和labels两个文件夹。
下面是随机划分训练集和验证集的脚本代码,只需要填充好image_dir、label_dir(标注好的图片和标签路径),train_image_dir、train_label_dir、val_image_dir、val_label_dir(生成训练集、验证集的图片和标签路径),还可以自己调整train_val_split的值来调整训练集和验证集的划分比例。
"""
随机划分训练集和验证集
"""
import os
import random
from shutil import copyfile
# 输入路径
image_dir = r'G:\yolov8\data\images' # 替换成你的图像文件夹路径
label_dir = r'G:\yolov8\data\label' # 替换成你的标签文件夹路径
# 输出路径
train_image_dir = r'G:\yolov8\ultralytics-main\ultralytics-main\my_data\detection\train\images'
train_label_dir = r'G:\yolov8\ultralytics-main\ultralytics-main\my_data\detection\train\labels'
val_image_dir = r'G:\yolov8\ultralytics-main\ultralytics-main\my_data\detection\val\images'
val_label_dir = r'G:\yolov8\ultralytics-main\ultralytics-main\my_data\detection\val\labels'
# 创建输出文件夹
os.makedirs(train_image_dir, exist_ok=True)
os.makedirs(train_label_dir, exist_ok=True)
os.makedirs(val_image_dir, exist_ok=True)
os.makedirs(val_label_dir, exist_ok=True)
# 划分数据集的比例
train_val_split = 0.8
# 获取图像文件列表
image_files = os.listdir(image_dir)
random.shuffle(image_files)
# 计算划分的索引
split_index = int(len(image_files) * train_val_split)
# 划分训练集和验证集
train_image_files = image_files[:split_index]
val_image_files = image_files[split_index:]
# 复制图像文件并相应地复制标签文件
def copy_images_and_labels(image_files, source_image_dir, source_label_dir, dest_image_dir, dest_label_dir):
for image_file in image_files:
# 复制图像文件
source_image_path = os.path.join(source_image_dir, image_file)
dest_image_path = os.path.join(dest_image_dir, image_file)
copyfile(source_image_path, dest_image_path)
# 复制对应的标签文件
label_file = os.path.splitext(image_file)[0] + '.txt'
source_label_path = os.path.join(source_label_dir, label_file)
dest_label_path = os.path.join(dest_label_dir, label_file)
copyfile(source_label_path, dest_label_path)
# 复制训练集图像和标签
copy_images_and_labels(train_image_files, image_dir, label_dir, train_image_dir, train_label_dir)
# 复制验证集图像和标签
copy_images_and_labels(val_image_files, image_dir, label_dir, val_image_dir, val_label_dir)
1.2 配置data.yaml文件
然后再配置下数据的yaml文件就行,这个文件应该填充在ultralytics-main\ultralytics\cfg\datasets路径下,新建一个yaml文件,命名为my_detect.yaml,填充以下信息,意思就是在加载这个yaml文件的时候,能根据里面的内容找到数据的。Path即由上面代码生成的YOLO格式的路径,name为类别的下标及名称。
# 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: G:\yolov8\ultralytics-main\ultralytics-main\my_data\detection # dataset root dir
train: train # train images (relative to 'path') 128 images
val: val# val images (relative to 'path') 128 images
test: # test images (optional)
# Classes
names:
0: person
1: surfboard
2.YOLOv8训练
2.1代码训练
终于要开始训练了,加载数据有数据的yaml文件,加载模型当然也会有模型的yaml,其路径在ultralytics-main\ultralytics\cfg\models\v8\yolov8.yaml,而yolov8.yaml文件只需要修改类别数即nc的值就行,如下所示:
接下来就可以开始训练了,YOLOv8推出了两种训练的方法,一种是使用脚本,一种是使用命令的方法:使用脚本进行训练的话比较容易Debug,下面是脚本的训练代码,需要注意四个点:第一是预训练权重要放在项目路径下,即\ultralytics-main下面,不然在训练的时候会自动下载预训练权重的,有点麻烦;第二就是在设置模型规模(n,s,m,l,x)的时候,直接通过Model_yaml参数来设置:model_yaml=r"G:\yolov8\ultralytics-main\ultralytics\cfg\models\v8\yolov8n.yaml",虽然该路径下没有yolov8n.yaml文件,但是V8可以识别出来选择的模型类型;第三就是要在if __name__==’’__main__’’:下执行;第四就是调小workers,不然可能会报错。
from ultralytics import YOLO
if __name__=="__main__":
# Load a model
model_yaml=r"G:\yolov8\ultralytics-main\ultralytics-main\ultralytics\cfg\models\v8\yolov8n.yaml"
data_yaml=r"G:\yolov8\ultralytics-main\ultralytics-main\ultralytics\cfg\datasets\my_detect.yaml"
pre_model=r"G:\yolov8\ultralytics-main\ultralytics-main\yolov8n.pt"
model = YOLO(model_yaml,task='detect').load(pre_model) # build from YAML and transfer weights
# Train the model
results = model.train(data=data_yaml, epochs=15, imgsz=640,batch=4,workers=2)
下面已经开始训练了。
此外,还有其他参数可以在\ultralytics-main\ultralytics\cfg\default.yaml进行设置,里面有很多参数可以进行调整,可以参考官方文档进行调整,Configuration - Ultralytics YOLOv8 Docs.
2.2指令训练
直接在控制面板输入指令就行,填写的超参数和代码训练的一样就行。
yolo detect train
data=G:\yolov8\ultralytics-main\ultralytics-main\ultralytics\cfg\datasets\my_detect.yaml
model=G:\yolov8\ultralytics-main\ultralytics-main\ultralytics\cfg\models\v8\yolov8n.yaml pretrained=G:\yolov8\ultralytics-main\ultralytics-main\yolov8n.pt
epochs=15
imgsz=640
batch=4
workers=2
2.3训练评价指标
在runs/train下可以看到训练过程的评估指标变化,如result.png中展示了YOLOv8在训练和验证的过程中三个损失的变化,以及precision、recall、mAP50这些值的变化,由这些数据可以看到模型是逐渐收敛的。
训练好的模型也会放在对应的weight文件夹下,会保存有最新的权重以及最好的权重。
3.YOLOv8验证
3.1代码验证
验证其实是加载验证集,然后使用best.pt进行推理得到的各项指标数据,如下所示。
from ultralytics import YOLO
if __name__=="__main__":
# Load a model
pth_path=r"G:\yolov8\ultralytics-main\ultralytics-main\runs\detect\train17\weights\best.pt"
model = YOLO('yolov8n.pt') # load an official model
model = YOLO(pth_path) # load a custom model
# Validate the model
metrics = model.val() # no arguments needed, dataset and settings remembered
metrics.box.map # map50-95
metrics.box.map50 # map50
metrics.box.map75 # map75
metrics.box.maps # a list contains map50-95 of each category
下图是输出的结果,可以看到这里加载的是train训练集(其实是因为我在配置data.yaml中填错了,这里我就不重新跑结果了),大家知道是加载验证集(在配置data.yaml中val: val中的路径文件)就行了。
3.2指令验证
这一块没啥好说的,直接贴指令了。
yolo detect val
model=G:\yolov8\ultralytics-main\ultralytics-main\runs\detect\train17\weights\best.pt
data=G:\yolov8\ultralytics-main\ultralytics-main\ultralytics\cfg\datasets\my_detect.yaml
4.YOLOv8预测
4.1代码预测
对图片进行预测并保存结果,可以先准备一张图片,或者把图片放进一个文件夹中,然后使用以下代码进行预测,可以看到预测结果保存的地址,注意这里预测的时候并不是640*640尺度进行预测,后面在预测原理章节会详细介绍:
from ultralytics import YOLO
if __name__=="__main__":
pth_path=r"G:\yolov8\ultralytics-main\ultralytics-main\runs\detect\train17\weights\best.pt"
test_path=r"G:\yolov8\ultralytics-main\ultralytics-main\detect_test"
# Load a model
model = YOLO('yolov8n.pt') # load an official model
model = YOLO(pth_path) # load a custom model
# Predict with the model
results = model(test_path,save=True,conf=0.5) # predict on an image
由预测结果可知,其实模型训练的效果还不是很好,模型还有很大的优化空间的。
4.2指令预测
指令如下:
yolo detect predict
model=G:\yolov8\ultralytics-main\ultralytics-main\runs\detect\train17\weights\best.pt source=G:\yolov8\ultralytics-main\ultralytics-main\detect_test
save=True
conf=0.5
5.YOLOv8导出
5.1代码导出
注意导出onnx模型时候需要设置opset=11,不然导出模型可能会报错,或者会出现警告。此外,最好设置动态导出onnx,这样模型的输入就不会仅限制在640*640,而可以是任意batch_size还有任意尺寸的图片了,并且可以同时预测batch_size张图片。
from ultralytics import YOLO
if __name__=="__main__":
pth_path=r"G:\yolov8\ultralytics-main\ultralytics-main\runs\detect\train17\weights\best.pt"
# Load a model
model = YOLO('yolov8n.pt') # load an official model
model = YOLO(pth_path) # load a custom trained model
# Export the model
model.export(format='onnx',opset=11,dynamic=True)
使用netron可视化onnx模型如下所示。可以和静态导出相比较,动态导出更加具有灵活性,输入的图片尺寸(height,width)或者输入图片的个数(batch)将不受限制。
5.2指令导出
指令如下:
yolo export
model=G:\yolov8\ultralytics-main\ultralytics-main\runs\detect\train17\weights\best.pt
format=onnx
opset=11
dynamic=True