赞
踩
- # 这里分别指向你训练、验证、测试的文件地址,只需要指向图片的文件夹即可。但是要注意图片和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
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")
在ultralytics/models/v8/目录下是模型的配置文件,随着架构的增大,训练时间也是逐渐增大,只用修改一个参数,把nc改成自己的类别数,需要取整。
Releases · ultralytics/assets (github.com)
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 |
使用YOLOv8进行目标检测时,每个图像通常都伴随一个.txt文件,该文件包含了关于图像中对象的标注信息。这些.txt文件中的每一行都代表图像中的一个对象,包含以下信息:
类别ID:这是一个整数,代表了对象所属的类别。例如,如果你的数据集有“人”、“车”和“狗”三个类别,那么可能分别用0、1和2来表示这些类别。
中心X坐标:这是一个归一化后的值,代表对象边界框中心的X坐标(水平方向)。这个值是相对于整个图像宽度的比例。
中心Y坐标:这是一个归一化后的值,代表对象边界框中心的Y坐标(垂直方向)。这个值是相对于整个图像高度的比例。
边界框宽度:这也是一个归一化后的值,代表对象边界框的宽度。这个值是相对于整个图像宽度的比例。
边界框高度:这同样是一个归一化值,代表对象边界框的高度。这个值是相对于整个图像高度的比例。
以乳腺癌目标检测结果为例:
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)的变化。
参考博客:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。