深度学习笔记_10YOLOv8系列自定义数据集实验

1、mydaya.yaml 配置方法

# 这里分别指向你训练、验证、测试的文件地址,只需要指向图片的文件夹即可。但是要注意图片和labels名称要对应
# 训练集、测试集、验证机文件路径,可以是分类好的TXT文件,也可以直接是图片文件夹路径
train:   # train images (relative to 'path') 128 images
val:  # val images (relative to 'path') 128 images
test: 

# 共有几个类别
nc : 1

# Classes
names: 
0: person
1: bicycle
2: car

2、配置数据集文件夹

2.1简易配置:

2.2细节配置:

mydata

…dataSet #之后会在Main文件夹内自动生成train.txt,val.txt,test.txt和trainval.txt四个文件,存放训练集、验证集、测试集图片的名字(无后缀.jpg)

…images # 存放图片

…labels # 存放图片对应的标签文件

…xml # 存放图片对应的xml文件

dataSet 文件夹下面存放训练集、验证集、测试集的划分,通过脚本生成,

可以创建一个split_train_val.py文件,代码内容如下:

import os  # 导入操作系统模块,用于文件路径操作
import random  # 导入随机数模块,用于随机抽样

# 设置训练验证数据集占总数据集的百分比
trainval_percent = 0.7
# 设置训练数据集占训练验证数据集的百分比
train_percent = 0.7
# 存储XML文件的文件夹路径
xmlfilepath = 'dataset/data/xml'
# 存储训练验证数据集和测试数据集的路径
txtsavepath = 'dataset/data/dataSet'
# 获取XML文件夹下所有文件的文件名列表
total_xml = os.listdir(xmlfilepath)

# 获取XML文件的总数
num = len(total_xml)
# 生成从0到num-1的列表
list = range(num)
# 计算训练验证数据集的数量
tv = int(num * trainval_percent)
# 计算训练数据集的数量
tr = int(tv * train_percent)
# 从列表中随机抽取tv个元素作为训练验证数据集的索引
trainval = random.sample(list, tv)
# 从训练验证数据集的索引中随机抽取tr个元素作为训练数据集的索引
train = random.sample(trainval, tr)

# 打开训练验证数据集、测试数据集、训练数据集和验证数据集的文件,准备写入数据
ftrainval = open('dataset/data/dataSet/trainval.txt', 'w')
ftest = open('dataset/data/dataSet/test.txt', 'w')
ftrain = open('dataset/data/dataSet/train.txt', 'w')
fval = open('dataset/data/dataSet/val.txt', 'w')

# 遍历总的XML文件列表
for i in list:
    # 获取当前XML文件的文件名,并去除文件扩展名
    name = total_xml[i][:-4] + '\n'
    # 判断当前文件索引是否在训练验证数据集中
    if i in trainval:
        # 将文件名写入训练验证数据集文件
        ftrainval.write(name)
        # 如果当前文件索引在训练数据集中
        if i in train:
            # 将文件名写入训练数据集文件
            ftrain.write(name)
        else:
            # 否则将文件名写入验证数据集文件
            fval.write(name)
    else:
        # 如果当前文件索引不在训练验证数据集中,则将文件名写入测试数据集文件
        ftest.write(name)

# 关闭所有文件
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

创建voc_label.py文件,将训练集、验证集、测试集生成label标签(训练中要用到),同时将数据集路径导入txt文件中,代码内容如下: 

# -*- coding: utf-8 -*-
# xml解析包
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join


sets = ['train', 'test', 'val']
classes = ['E2', 'J20', 'B2', 'F14', 'Tornado', 'F4', 'B52', 'JAS39','Mirage2000']


# 进行归一化操作
def convert(size, box): # size:(原图w,原图h) , box:(xmin,xmax,ymin,ymax)
    dw = 1./size[0]     # 1/w
    dh = 1./size[1]     # 1/h
    x = (box[0] + box[1])/2.0   # 物体在图中的中心点x坐标
    y = (box[2] + box[3])/2.0   # 物体在图中的中心点y坐标
    w = box[1] - box[0]         # 物体实际像素宽度
    h = box[3] - box[2]         # 物体实际像素高度
    x = x*dw    # 物体中心点x的坐标比(相当于 x/原图w)
    w = w*dw    # 物体宽度的宽度比(相当于 w/原图w)
    y = y*dh    # 物体中心点y的坐标比(相当于 y/原图h)
    h = h*dh    # 物体宽度的宽度比(相当于 h/原图h)
    return (x, y, w, h)    # 返回 相对于原图的物体中心点的x坐标比,y坐标比,宽度比,高度比,取值范围[0-1]


# year ='2012', 对应图片的id(文件名)
def convert_annotation(image_id):
    '''
    将对应文件名的xml文件转化为label文件,xml文件包含了对应的bunding框以及图片长款大小等信息,
    通过对其解析,然后进行归一化最终读到label文件中去,也就是说
    一张图片文件对应一个xml文件,然后通过解析和归一化,能够将对应的信息保存到唯一一个label文件中去
    一张图片文件对应一个xml文件,然后通过解析和归一化,能够将对应的信息保存到唯一一个label文件中去
    labal文件中的格式:calss x y w h  同时,一张图片对应的类别有多个,所以对应的bunding的信息也有多个
    '''
    # 对应的通过year 找到相应的文件夹,并且打开相应image_id的xml文件,其对应bund文件
    in_file = open('/home/featurize/work/yolov5-master/data/mydata/xml/%s.xml' % (image_id), encoding='utf-8')
    # 准备在对应的image_id 中写入对应的label,分别为
    # <object-class> <x> <y> <width> <height>
    out_file = open('/home/featurize/work/yolov5-master/data/mydata/labels/%s.txt' % (image_id), 'w', encoding='utf-8')
    # 解析xml文件
    tree = ET.parse(in_file)
    # 获得对应的键值对
    root = tree.getroot()
    # 获得图片的尺寸大小
    size = root.find('size')
    # 如果xml内的标记为空,增加判断条件
    if size != None:
        # 获得宽
        w = int(size.find('width').text)
        # 获得高
        h = int(size.find('height').text)
        # 遍历目标obj
        # 遍历目标obj
        for obj in root.iter('object'):
            # 获得difficult
            difficult_obj = obj.find('difficult')
            difficult = difficult_obj.text if difficult_obj is not None else '0'
            # 获得类别 =string 类型
            cls = obj.find('name').text
            # 如果类别不是对应在我们预定好的class文件中,或difficult==1则跳过
            if cls not in classes or int(difficult) == 1:
                continue
            # 通过类别名称找到id
            cls_id = classes.index(cls)
            # 找到bndbox 对象
            xmlbox = obj.find('bndbox')
            # 获取对应的bndbox的数组 = ['xmin','xmax','ymin','ymax']
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                 float(xmlbox.find('ymax').text))
            print(image_id, cls, b)
            # 带入进行归一化操作
            # w = 宽, h = 高, b= bndbox的数组 = ['xmin','xmax','ymin','ymax']
            bb = convert((w, h), b)
            # bb 对应的是归一化后的(x,y,w,h)
            # 生成 calss x y w h 在label文件中
            out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


# 返回当前工作目录
wd = getcwd()
print(wd)


for image_set in sets:
    '''
    对所有的文件数据集进行遍历
    做了两个工作:
    1.将所有图片文件都遍历一遍,并且将其所有的全路径都写在对应的txt文件中去,方便定位
    2.同时对所有的图片文件进行解析和转化,将其对应的bundingbox 以及类别的信息全部解析写到label 文件中去
         最后再通过直接读取文件,就能找到对应的label 信息
    '''
    # 先找labels文件夹如果不存在则创建
    if not os.path.exists('/home/featurize/work/yolov5-master/data/mydata/labels'):
        os.makedirs('/home/featurize/work/yolov5-master/data/mydata/labels')
    # 读取在ImageSets/Main 中的train、test..等文件的内容
    # 包含对应的文件名称
    image_ids = open('/home/featurize/work/yolov5-master/data/mydata/dataSet/%s.txt' % (image_set)).read().strip().split()
    # 打开对应的2012_train.txt 文件对其进行写入准备
    list_file = open('/home/featurize/work/yolov5-master/data/mydata/%s.txt' % (image_set), 'w')
    # 将对应的文件_id以及全路径写进去并换行
    for image_id in image_ids:
        list_file.write('/home/featurize/work/yolov5-master/data/mydata/images/%s.jpg\n' % (image_id))
        # 调用  year = 年份  image_id = 对应的文件名_id
        convert_annotation(image_id)
    # 关闭文件
    list_file.close()

# os.system(‘comand’) 会执行括号中的命令,如果命令成功执行,这条语句返回0,否则返回1
# os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
# os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")

3、选择模型

在ultralytics/models/v8/目录下是模型的配置文件,随着架构的增大,训练时间也是逐渐增大,只用修改一个参数,把nc改成自己的类别数,需要取整。

4、下载预训练模型

Releases · ultralytics/assets (github.com)

5、训练模型

yolo task=detect mode=train model=yolov8.yaml data=mydata.yaml epochs=200 batch=16  pretrained=yolov8n.pt

 训练参数说明:

参数 默认值 描述 设置建议
model None 模型文件路径,如 yolov8n.pt, yolov8n.yaml 根据需要选择合适的预训练模型文件
data None 数据文件路径,如 coco128.yaml 选择合适的数据集配置文件
epochs 100 训练的周期数 根据数据集大小和模型复杂度调整
time None 训练时间(小时),如果提供,将覆盖epochs参数 根据实际训练时间需求设置
patience 50 早停的周期数,等待无显著改进的周期数 根据模型训练动态调整
batch 16 每个批次的图像数量 根据硬件资源调整
imgsz 640 输入图像的尺寸 根据硬件和模型性能要求调整
save True 是否保存训练检查点和预测结果 通常保持默认
save_period -1 每x周期保存检查点,如果<1则禁用 根据需要设置
cache False 是否使用数据加载缓存,选项:True/ram, disk 或 False 根据硬件资源和数据集大小决定
device None 运行设备,如 cuda device=0 或 device=cpu 根据可用的硬件资源设置
workers 8 数据加载的工作线程数 根据系统资源调整
project None 项目名称 根据需要自定义
name None 实验名称 自定义实验名以便识别
exist_ok False 是否覆盖现有实验 如果需要重复实验,设置为True
pretrained True 是否使用预训练模型 通常对于新的训练任务保持True
optimizer 'auto' 优化器,可选项:SGD, Adam等 根据模型和数据集特性选择合适的优化器
verbose False 是否打印详细输出 开发和调试时可设为True
seed 0 重现性的随机种子 需要重现结果时设置确定值
deterministic True 是否启用确定性模式 需要确保结果一致性时设置为True
single_cls False 是否将多类数据作为单类训练 特定应用场景下调整
rect False 矩形训练,每个批次为最小填充 特定应用场景下调整
cos_lr False 是否使用余弦学习率调度器 根据训练策略调整
close_mosaic 10 关闭马赛克增强的最后周期数 根据训练需求调整
resume False 从最后检查点恢复训练 需要从中断的训练继续时设置为True
amp True 是否使用自动混合精度训练 根据硬件支持选择
fraction 1.0 训练的数据集比例 如需使用数据集的子集进行训练,调整此值
profile False 训练期间记录ONNX和TensorRT速度 性能分析时启用
freeze None 冻结训练期间的前n层或特定层 特定模型调整时使用
lr0 0.01 初始学习率 根据模型和数据集特性调整
lrf 0.01 最终学习率 根据训练策略调整
momentum 0.937 SGD动量/Adam beta1 根据优化器类型调整
weight_decay 0.0005 优化器权重衰减 通常保持默认值
warmup_epochs 3.0 热身周期数 根据模型特性调整
warmup_momentum 0.8 热身初始动量 根据训练策略调整
warmup_bias_lr 0.1 热身初始偏置学习率 根据训练策略调整
box 7.5 盒子损失增益 根据模型特性和训练数据调整
cls 0.5 类别损失增益 根据分类任务的复杂性调整
dfl 1.5 DFL损失增益 根据具体应用调整
pose 12.0 姿态损失增益(仅限姿态) 仅在姿态检测任务中使用
kobj 2.0 关键点目标损失增益(仅限姿态) 仅在姿态检测任务中使用
label_smoothing 0.0 标签平滑(比例) 根据训练策略调整
nbs 64 标称批量大小 根据硬件资源调整
overlap_mask True 掩码在训练期间是否重叠(仅限分割训练) 仅在分割任务中使用
mask_ratio 4 掩码下采样比例(仅限分割训练) 仅在分割任务中使用
dropout 0.0 使用dropout正则化(仅限分类训练) 仅在分类任务中使用
val True 训练期间进行验证/测试 通常保持默认
plots False 训练/验证期间保存图表和图像 需要可视化训练过程时设置为True

6、labels.txt 文件数据说明

使用YOLOv8进行目标检测时,每个图像通常都伴随一个.txt文件,该文件包含了关于图像中对象的标注信息。这些.txt文件中的每一行都代表图像中的一个对象,包含以下信息:

类别ID:这是一个整数,代表了对象所属的类别。例如,如果你的数据集有“人”、“车”和“狗”三个类别,那么可能分别用0、1和2来表示这些类别。

中心X坐标:这是一个归一化后的值,代表对象边界框中心的X坐标(水平方向)。这个值是相对于整个图像宽度的比例。

中心Y坐标:这是一个归一化后的值,代表对象边界框中心的Y坐标(垂直方向)。这个值是相对于整个图像高度的比例。

边界框宽度:这也是一个归一化后的值,代表对象边界框的宽度。这个值是相对于整个图像宽度的比例。

边界框高度:这同样是一个归一化值,代表对象边界框的高度。这个值是相对于整个图像高度的比例。

7、训练结果文件说明

以乳腺癌目标检测结果为例:

best.pt:损失值最小的模型文件
last.pt:训练到最后的模型文件


args.yaml:模型训练的配置参数

confusion_matrix.png - 混淆矩阵
        这张图展示了分类模型的性能。每一行代表模型预测的类别,每一列代表实际的类别。对角线上的数值表示模型正确预测的数量。对角线上较深的颜色表示该类别预测正确的数量较多。

confusion_matrix_normalized.png - 标准化混淆矩阵:
        与普通混淆矩阵类似,但这里的值显示的是每个类别的预测正确比例。这有助于比较不同类别的预测准确性,尤其是在类别样本数量不平衡的情况下。

F1_curve.png - F1-置信度曲线
        此曲线显示了F1得分随着置信度阈值的变化。F1得分是精确度和召回率的调和平均值,曲线的峰值表示给定置信度阈值下精确度和召回率的最佳平衡点。

labels.jpg - 标签分布图和边界框分布图
        柱状图显示了不同类别的实例分布数量。散点图则展示了目标检测任务中边界框的空间分布情况,反映了常见的尺寸和长宽比。

labels_correlogram.jpg - 标签相关图
        相关图提供了不同类别标签之间的关系,以及它们在图像中位置的相关性。这有助于理解模型在识别不同类别时可能出现的关联或混淆。

P_curve.png - 精确度-置信度曲线
        这张曲线图展示了模型预测的精确度随着置信度阈值的变化。精确度是模型预测正确正例与预测为正例总数的比值。

PR_curve.png - 精确度-召回曲线
        这张曲线图展示了模型的精确度与召回率之间的关系。理想情况下,模型应在精确度和召回率之间保持良好的平衡。

R_curve.png - 召回-置信度曲线
        此曲线图显示了模型的召回率随置信度阈值的变化。召回率是模型正确预测的正例与实际正例总数的比值。

results.png 和 results.csv - 训练结果图表和数据


        这些图表和数据文件展示了模型在训练过程中的性能变化,包括损失函数的变化和评估指标(如精确度、召回率和mAP)的变化。

参考博客:

超详细YOLOv8目标检测全程概述:环境、训练、验证与预测详解_yolov8目标检测流程-CSDN博客

一文了解YOLOv8(附带各种任务详细说明链接):计算机视觉领域的新星_yolov8官方文档解读-CSDN博客

最近更新

  1. TCP协议是安全的吗?

    2024-05-09 11:40:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-09 11:40:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-09 11:40:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-09 11:40:02       18 阅读

热门阅读

  1. 学习R语言第六天

    2024-05-09 11:40:02       9 阅读
  2. 浏览器原理---浏览器同源策略

    2024-05-09 11:40:02       9 阅读
  3. 【Web前端】定位_浮动_音视频

    2024-05-09 11:40:02       8 阅读
  4. Python进阶之-hashlib详解

    2024-05-09 11:40:02       7 阅读
  5. CMakeLists.txt语法规则:条件判断中表达式说明四

    2024-05-09 11:40:02       8 阅读
  6. React 学习-2

    2024-05-09 11:40:02       7 阅读
  7. React 第二十五章 React.memo

    2024-05-09 11:40:02       11 阅读