YOLOv9如何训练自己的数据集(NEU-DET为案列)

 💡💡💡本文内容教会你用自己数据集训练YOLOv9模型

 《YOLOv9魔术师专栏》将从以下各个方向进行创新:

原创自研模块多组合点优化注意力机制主干篇neck优化卷积魔改block&多尺度融合结合损失&IOU优化上下采样优化 SPPELAN & RepNCSPELAN4优化【小目标性能提升】前沿论文分享训练实战篇】

订阅者通过添加WX: AI_CV_0624,入群沟通,提供改进结构图等一系列定制化服务。
订阅者可以申请发票,便于报销 

 YOLOv9魔术师专栏

💡💡💡为本专栏订阅者提供创新点改进代码,改进网络结构图,方便paper写作!!!

💡💡💡适用场景:红外、小目标检测工业缺陷检测医学影像遥感目标检测低对比度场景

💡💡💡适用任务:所有改进点适用【检测】【分割】【pose】【分类】

💡💡💡全网独家首发创新,【自研多个自研模块】【多创新点组合适合paper 】!!!

☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️

包含注意力机制魔改、卷积魔改、检测头创新、损失&IOU优化、block优化&多层特征融合、 轻量级网络设计、24年最新顶会改进思路、原创自研paper级创新等

🚀🚀🚀 本项目持续更新 | 更新完结保底≥80+ ,冲刺100+ 🚀🚀🚀

🍉🍉🍉 联系WX: AI_CV_0624 欢迎交流!🍉🍉🍉

⭐⭐⭐专栏涨价趋势 99 ->199->259->299,越早订阅越划算⭐⭐⭐

💡💡💡 2024年计算机视觉顶会创新点适用于Yolov5、Yolov7、Yolov8等各个Yolo系列,专栏文章提供每一步步骤和源码,轻松带你上手魔改网络 !!!

💡💡💡重点:通过本专栏的阅读,后续你也可以设计魔改网络,在网络不同位置(Backbone、head、detect、loss等)进行魔改,实现创新!!!

☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️

 1.YOLOv9原理介绍

论文: 2402.13616.pdf (arxiv.org)

代码:GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information摘要: 如今的深度学习方法重点关注如何设计最合适的目标函数,从而使得模型的预测结果能够最接近真实情况。同时,必须设计一个适当的架构,可以帮助获取足够的信息进行预测。然而,现有方法忽略了一个事实,即当输入数据经过逐层特征提取和空间变换时,大量信息将会丢失。因此,YOLOv9 深入研究了数据通过深度网络传输时数据丢失的重要问题,即信息瓶颈和可逆函数。作者提出了可编程梯度信息(programmable gradient information,PGI)的概念,来应对深度网络实现多个目标所需要的各种变化。PGI 可以为目标任务计算目标函数提供完整的输入信息,从而获得可靠的梯度信息来更新网络权值。此外,研究者基于梯度路径规划设计了一种新的轻量级网络架构,即通用高效层聚合网络(Generalized Efficient Layer Aggregation Network,GELAN)。该架构证实了 PGI 可以在轻量级模型上取得优异的结果。研究者在基于 MS COCO 数据集的目标检测任务上验证所提出的 GELAN 和 PGI。结果表明,与其他 SOTA 方法相比,GELAN 仅使用传统卷积算子即可实现更好的参数利用率。对于 PGI 而言,它的适用性很强,可用于从轻型到大型的各种模型。我们可以用它来获取完整的信息,从而使从头开始训练的模型能够比使用大型数据集预训练的 SOTA 模型获得更好的结果。对比结果如图1所示。

1.1 YOLOv9框架介绍

YOLOv9各个模型介绍

 models/detect/yolov9.yaml

ELAN models.common.RepNCSPELAN4:

从模块名字不难看出核心是Re-parameter + CSPNet + ELAN。

ELAN-SPP models.common.SPPELAN:

该模块与早前yolo版本中的SPPF结构基本一致,如下图。

ADown models.common.ADown:

该模块在yolov9-c.yamlyolov9-e.yaml结构中出现,替代了模型中部分CBS模块。

 来自:YOLOv9结构详解 - 知乎 (zhihu.com)

2.NEU-DET数据集介绍 

NEU-DET钢材表面缺陷共有六大类,一共1800张,

类别分别为:'crazing','inclusion','patches','pitted_surface','rolled-in_scale','scratches'

 2.1数据集划分

通过split_train_val.py得到trainval.txt、val.txt、test.txt  

# coding:utf-8

import os
import random
import argparse

parser = argparse.ArgumentParser()
#xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
parser.add_argument('--xml_path', default='Annotations', type=str, help='input xml label path')
#数据集的划分,地址选择自己数据下的ImageSets/Main
parser.add_argument('--txt_path', default='ImageSets/Main', 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 = total_xml[i][:-4] + '\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()

2.2  通过voc_label.py生成txt

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val', 'test']
classes = ["crazing","inclusion","patches","pitted_surface","rolled-in_scale","scratches"]   # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)

def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return x, y, w, h

def convert_annotation(image_id):
    in_file = open('Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('labels/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        #difficult = obj.find('Difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

wd = getcwd()
for image_set in sets:
    if not os.path.exists('labels/'):
        os.makedirs('labels/')
    image_ids = open('ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    list_file = open('%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write(abs_path + '/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

2.YOLOv9训练自己的数据集

2.1 修改NEU-DET.yaml

path推荐使用全路径

path: ./data/NEU-DET # dataset root dir
train: train.txt  # train images (relative to 'path') 118287 images
val: val.txt  # val images (relative to 'path') 5000 images

# number of classes
nc: 6

# class names
names:
  0: crazing
  1: inclusion
  2: patches
  3: pitted_surface
  4: rolled-in_scale  
  5: scratches

2.2  修改train_dual.py

def parse_opt(known=False):
    parser = argparse.ArgumentParser()
    # parser.add_argument('--weights', type=str, default=ROOT / 'yolo.pt', help='initial weights path')
    # parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
    parser.add_argument('--weights', type=str, default='weights/yolov9-c.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='models/detect/yolov9-c.yaml', help='model.yaml path')
    parser.add_argument('--data', type=str, default=ROOT / 'data/NEU-DET/NEU-DET.yaml', help='dataset.yaml path')
    parser.add_argument('--hyp', type=str, default=ROOT / 'data/hyps/hyp.scratch-high.yaml', help='hyperparameters path')
    parser.add_argument('--epochs', type=int, default=100, help='total training epochs')
    parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs, -1 for autobatch')
    parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='train, val image size (pixels)')

2.3 开启训练

python train_dual.py

2.4 训练可视化

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
若想使用 YOLOv5 训练 NEU-DET 数据集,可以按照以下步骤进行操作: 1. 下载 NEU-DET 数据集: 首先,从数据集提供的来源下载 NEU-DET 数据集。确保你拥有训练图像和相应的标签文件。 2. 准备数据集: - 将训练图像放在一个文件夹中(如 `data/images/train/`)。 - 将与每个图像对应的标签文件放在另一个文件夹中(如 `data/labels/train/`),标签文件的格式应与 YOLOv5 要求的格式相匹配。 3. 创建数据集配置文件: 在 `data/` 目录下创建一个新的 `.yaml` 文件(如 `neu-det.yaml`),并按照以下格式填写文件内容: ```yaml train: path/to/train.txt val: path/to/val.txt nc: 6 # 类别数目 names: [crazing, inclusion, patches, pitted_surface, rolled-in_scale, scratches] # 类别名称 ``` - 将 `path/to/train.txt` 替换为包含训练图像路径的文本文件的路径。 - 将 `path/to/val.txt` 替换为包含验证图像路径的文本文件的路径。 - 将 `nc` 设置为数据集中的类别数目(在 NEU-DET 中为 6)。 - 将 `names` 设置为数据集中每个类别的名称表。 4. 开始训练: 运行以下命令来启动训练过程: ```shell python train.py --img 640 --batch 16 --epochs 50 --data path/to/neu-det.yaml --weights yolov5s.pt ``` - `--img` 设置输入图像的大小(推荐使用 640 或 1280)。 - `--batch` 设置批量大小。 - `--epochs` 设置训练的轮数。 - `--data` 指定数据集配置文件的路径。 - `--weights` 指定预训练权重文件的路径,可以使用预训练YOLOv5 权重(如 `yolov5s.pt`)或者之前训练的权重文件。 5. 监控训练过程: 训练过程中会显示损失和其他指标,同时会在 `runs/train/` 目录下保存模型权重文件和训练日志。 这样,你就可以使用 YOLOv5 训练 NEU-DET 数据集了。记得替换命令中的路径参数为你自己的路径和设置适合你的训练参数。如果有其他问题,欢迎继续提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI小怪兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值