YOLOv6训练自己的数据集

文章目录


前言

提示:本文是YOLOv6训练自己数据集的记录教程,需要大家在本地已配置好CUDA,cuDNN等环境,没配置的小伙伴可以查看我的往期博客:在Windows10上配置CUDA环境教程

YOLOv6是美团视觉智能部研发的一款面向工业应用的目标检测框架,该框架在保持高检测精度的同时,兼顾了推理效率,是YOLO系列中的又一改进版本。

代码地址:https://github.com/meituan/YOLOv6

论文地址:https://arxiv.org/abs/2209.02976


一、YOLOv6简介

主要特点

  1. Hardware-friendly的骨干网络设计

    YOLOv6采用了基于RepVGG style的可重参数化、更高效的骨干网络EfficientRep Backbone,以及Rep-PAN Neck,这些设计使得网络在推理时能够更有效地利用硬件资源,提高推理速度。

  2. 更简洁高效的Decoupled Head

    YOLOv6采用了解耦检测头(Decoupled Head)结构,并对其进行了精简设计,以减少网络延时,同时保持较高的检测精度。

  3. 高精度与高效率

    YOLOv6在工业界常用的尺寸模型中表现出色。例如,YOLOv6-nano在COCO数据集上的精度可达35.0% AP,在NVIDIA Tesla T4 GPU上的推理速度可达1242 FPS;YOLOv6-s在COCO上的精度可达43.1% AP,推理速度可达520 FPS。

  4. 部署友好

    YOLOv6支持多种不同平台的部署,包括GPU(TensorRT)、CPU(OPENVINO)、ARM(MNN、TNN、NCNN)等,极大地简化了工程部署时的适配工作。

二、环境搭建

在配置好CUDA环境,并且获取到YOLOv6源码后,建议新建一个虚拟环境专门用于YOLOv6模型的训练。将YOLOv6加载到环境后,安装剩余的包。requirements.txt 中包含了运行所需的包和版本,利用以下命令批量安装:

python 复制代码
pip install -r requirements.txt

三、构建数据集

YOLOv6模型的训练需要原图像及对应的YOLO格式标签,还未制作标签的可以参考我这篇文章:LabelImg安装与使用教程

我的原始数据存放在根目录的data文件夹(新建的)下,里面包含图像和标签。


标签内的格式如下:

具体格式为 class_id x y w h,分别代表物体类别,标记框中心点的横纵坐标(x, y),标记框宽高的大小(w, h),且都是归一化后的值,图片左上角为坐标原点。

将原本数据集按照8:1:1的比例划分成训练集、验证集和测试集三类,划分代码如下。

python 复制代码
# 将图片和标注数据按比例切分为 训练集和测试集
import shutil
import random
import os
 
# 原始路径
image_original_path = "originaldata/images/"
label_original_path = "originaldata/labels/"
 
cur_path = os.getcwd()
#cur_path = 'D:/image_denoising_test/denoise/'
# 训练集路径
train_image_path = os.path.join(cur_path, "data/images/train/")
train_label_path = os.path.join(cur_path, "data/labels/train/")
 
# 验证集路径
val_image_path = os.path.join(cur_path, "data/images/val/")
val_label_path = os.path.join(cur_path, "data/labels/val/")
 
# 测试集路径
test_image_path = os.path.join(cur_path, "data/images/test/")
test_label_path = os.path.join(cur_path, "data/labels/test/")
 
# 训练集目录
list_train = os.path.join(cur_path, "data/train.txt")
list_val = os.path.join(cur_path, "data/val.txt")
list_test = os.path.join(cur_path, "data/test.txt")
 
train_percent = 0.8
val_percent = 0.1
test_percent = 0.1
 
 
def del_file(path):
    for i in os.listdir(path):
        file_data = path + "\\" + i
        os.remove(file_data)
 
 
def mkdir():
    if not os.path.exists(train_image_path):
        os.makedirs(train_image_path)
    else:
        del_file(train_image_path)
    if not os.path.exists(train_label_path):
        os.makedirs(train_label_path)
    else:
        del_file(train_label_path)
 
    if not os.path.exists(val_image_path):
        os.makedirs(val_image_path)
    else:
        del_file(val_image_path)
    if not os.path.exists(val_label_path):
        os.makedirs(val_label_path)
    else:
        del_file(val_label_path)
 
    if not os.path.exists(test_image_path):
        os.makedirs(test_image_path)
    else:
        del_file(test_image_path)
    if not os.path.exists(test_label_path):
        os.makedirs(test_label_path)
    else:
        del_file(test_label_path)
 
 
def clearfile():
    if os.path.exists(list_train):
        os.remove(list_train)
    if os.path.exists(list_val):
        os.remove(list_val)
    if os.path.exists(list_test):
        os.remove(list_test)
 
 
def main():
    mkdir()
    clearfile()
 
    file_train = open(list_train, 'w')
    file_val = open(list_val, 'w')
    file_test = open(list_test, 'w')
 
    total_txt = os.listdir(label_original_path)
    num_txt = len(total_txt)
    list_all_txt = range(num_txt)
 
    num_train = int(num_txt * train_percent)
    num_val = int(num_txt * val_percent)
    num_test = num_txt - num_train - num_val
 
    train = random.sample(list_all_txt, num_train)
    # train从list_all_txt取出num_train个元素
    # 所以list_all_txt列表只剩下了这些元素
    val_test = [i for i in list_all_txt if not i in train]
    # 再从val_test取出num_val个元素,val_test剩下的元素就是test
    val = random.sample(val_test, num_val)
 
    print("训练集数目:{}, 验证集数目:{}, 测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))
    for i in list_all_txt:
        name = total_txt[i][:-4]
 
        srcImage = image_original_path + name + '.jpg'
        srcLabel = label_original_path + name + ".txt"
 
        if i in train:
            dst_train_Image = train_image_path + name + '.jpg'
            dst_train_Label = train_label_path + name + '.txt'
            shutil.copyfile(srcImage, dst_train_Image)
            shutil.copyfile(srcLabel, dst_train_Label)
            file_train.write(dst_train_Image + '\n')
        elif i in val:
            dst_val_Image = val_image_path + name + '.jpg'
            dst_val_Label = val_label_path + name + '.txt'
            shutil.copyfile(srcImage, dst_val_Image)
            shutil.copyfile(srcLabel, dst_val_Label)
            file_val.write(dst_val_Image + '\n')
        else:
            dst_test_Image = test_image_path + name + '.jpg'
            dst_test_Label = test_label_path + name + '.txt'
            shutil.copyfile(srcImage, dst_test_Image)
            shutil.copyfile(srcLabel, dst_test_Label)
            file_test.write(dst_test_Image + '\n')
 
    file_train.close()
    file_val.close()
    file_test.close()
 
 
if __name__ == "__main__":
    main()

划分完成后将会在data文件夹下生成划分好的文件,其中images为划分后的图像文件,里面包含用于train、val、test的图像,已经划分完成;labels文件夹中包含划分后的标签文件,已经划分完成,里面包含用于train、val、test的标签;train.tet、val.txt、test.txt中记录了各自的图像路径。

在训练过程中,也是主要使用这三个txt文件进行数据的索引。

四、修改配置文件

①数据集文件配置

数据集划分完成后,在项目的data文件下,新建bubbleplume.yaml,替代coco.yaml。用于指明数据集路径和类别,我这边只有一个类别,nc中只留了一个,多类别的在names内加上类别名即可。bubbleplume.yaml中的内容为:

python 复制代码
# Please insure that your custom_dataset are put in same parent dir with YOLOv6_DIR
train: ./data/images/train # train images
val: ./data/images/val # val images
test: ./data/images/test # test images (optional)

# whether it is coco dataset, only coco dataset should be set to True.
is_coco: False
# Classes
nc: 1  # number of classes
names: ['plume']  # class names

②权重下载

在进行模型训练之前,需要到官网下载预训练权重,权重地址为:https://github.com/meituan/YOLOv6/releases

权重下载完成后,在项目根目录新建weights文件夹,将下载的权重放到里面,要用哪个版本的模型加载哪个权重即可

③模型文件配置

在模型配置中,YOLOv6只需要修改tools文件夹中的train.py,在24行处的def parse_opt()函数中,主要修改data-path、conf-file、img-size、batch-size、epochs、workers以及device。这些参数已足够顺利训练了,其他参数就是一些后续的调参工作了。

data-path是配置数据集文件的路径,将default中的内容修改成自己的数据集yaml文件路径。

python 复制代码
parser.add_argument('--data-path', default='./data/bubbleplume.yaml', type=str, help='path of dataset')

conf-file指选用的模型文件,在configs文件夹下,里面包含模型结构和一些超参数。选用哪个模型,就在default中填上他的路径。yaml文件中带有finetune的表示使用预训练权重,即下载在weight文件夹下的权重,不是用带finetune的则表示不使用权重,直接训练。

python 复制代码
parser.add_argument('--conf-file', default='./configs/yolov6m_finetune.py', type=str, help='experiments description file')

epochs指训练的轮次,这里我这边在default中定了一个300次,只要模型能收敛即可。

python 复制代码
parser.add_argument('--epochs', default=400, type=int, help='number of total epochs to run')

batch-size是表示一次性将多少张图片放在一起训练,越大训练的越快,如果设置的太大会报OOM 错误,我这边在default中设置16,表示一次训练16张图像。设置的大小为2的幂次,1为2的0次,16为2的4次。

python 复制代码
parser.add_argument('--batch-size', default=16, type=int, help='total batch size for all GPUs')

img-size表示送入训练的图像大小,会统一进行缩放。要求是32的整数倍,尽量和图像本身大小一致。这边在default中设置为640。

python 复制代码
parser.add_argument('--img-size', default=320, type=int, help='train, val image size (pixels)')

device指训练运行的设备。该参数指定了模型训练所使用的设备,例如使用 GPU 运行可以指定为 default='0',或者使用多个 GPU 运行可以指定为 device=0,1,2,3,如果没有可用的 GPU,可以指定为device='cpu'使用 CPU 进行训练。

python 复制代码
parser.add_argument('--device', default='0', type=str, help='cuda device, i.e. 0 or 0,1,2,3 or cpu')

workers是指数据装载时cpu所使用的线程数,默认为8,过高时会报错:[WinError 1455] 页面文件太小,无法完成操作 ,此时就只能将default调成0了。

python 复制代码
parser.add_argument('--workers', default=10, type=int, help='number of data loading workers (default: 8)')

模型训练的相关基本参数就是这些啦,其余的参数可以等到后期训练完成进行调参时再详细了解。

五、模型训练和测试

模型训练

在将train.py文件配置完成后,即可运行此文件,便会开始训练啦


训练完成后,将会在runs/train/exp/weight文件夹下存放训练后的权重文件。

模型测试

使用tools/eval.py进行测试,需要修改def parse_opt()中的data、weights、batch-size、img-size、devicey以及task。

其中weights为训练出来的新模型权重,路径在runs/train文件夹下,

python 复制代码
parser.add_argument('--weights', type=str, default='./runs/train/exp/weights/best_ckpt.pt', help='model.pt path(s)')

task,表示在验证时所使用的数据集,这里使用test

python 复制代码
parser.add_argument('--task', default='test', help='val, test, or speed')

其余参数和训练时一致。

运行eval.py文件后便会得出训练精度等相关信息。


总结

以上就是YOLOv6训练自己数据集的全部过程啦,欢迎大家在评论区交流~

相关推荐
JicasdC123asd1 天前
Converse2D频域卷积上采样改进YOLOv26图像重建与细节恢复能力
人工智能·yolo·目标跟踪
云和数据.ChenGuang1 天前
chromadb为什么需要模拟数据运行
人工智能·神经网络·目标检测·机器学习·计算机视觉
FL16238631291 天前
基于yolov8+pyqt5实现的水尺图像识别与水深计算系统
开发语言·qt·yolo
jay神1 天前
基于YOLOv8的传送带异物检测系统
人工智能·python·深度学习·yolo·可视化·计算机毕业设计
智驱力人工智能1 天前
馆藏文物预防性保护依赖的图像分析技术 文物损害检测 文物破损检测 文物损害识别误报率优化方案 文物安全巡查AI系统案例 智慧文保AI监测
人工智能·算法·安全·yolo·边缘计算
智驱力人工智能1 天前
一盔一带AI抓拍系统能否破解非机动车执法取证难 骑行未戴头盔检测 电动车未戴头盔智能监测 摩托车头盔佩戴AI识别系统 边缘计算实时处理
人工智能·算法·yolo·目标检测·边缘计算
jay神1 天前
基于YOLOv8的无人机识别与检测系统
人工智能·深度学习·yolo·目标检测·毕业设计·无人机
小高求学之路1 天前
计算机视觉、YOLO算法模型训练、无人机监测人员密集自动识别
算法·yolo·计算机视觉
duyinbi75172 天前
ADown高效下采样改进YOLOv26目标检测性能提升
yolo·目标检测·目标跟踪
棱镜研途2 天前
EI会议分享 | 2026年图像处理与模式识别国际会议(IC-IPPR 2026)【SPIE出版】
图像处理·人工智能·深度学习·目标检测·计算机·计算机视觉·视觉检测