目标检测:yolov9训练自己的数据集,新手小白也能学会训练模型,一看就会

news2024/10/10 16:44:53

训练自己的数据集分为4部分,先配置环境,再获取制作自己的数据集,然后修改配置训练,最后验证训练结果。新手小白0基础建议一步一步跟着来,哪里看不懂的或者遇到哪有问题可以评论区交流或者私信问~

1. 环境配置

在训练yolov9模型前环境必须配置完成,还不会配置环境的可以看我的这篇博客

深度学习目标检测:yolov9环境配置,适合0基础小白,超详细-CSDN博客文章浏览阅读2.2k次,点赞26次,收藏37次。点击鼠标右键yolov9文件夹通过pycharm打开,打开后需要配置虚拟环境,点击file-settings,点击project:yolov9-main,点击python interpreter,点击右边add....,下载完之后运行安装,建议安装到默认路径,所以C盘需要留有20G以上的存储空间,一直点击下一步,直到出现这个界面,不要点击精简,选择自定义,然后全部勾选再一直下一步即可。下载完之后安装,一直点下一步,遇到选择路径 修改路径到D盘或者其它除C盘,再遇到勾选的选项全部勾选就可以。_yolov9环境配置https://blog.csdn.net/qq_67105081/article/details/139815008?spm=1001.2014.3001.5501

环境配置完验证之后没有问题就可以获取自己的数据集

2. 数据集获取

目标检测相关的数据集一般是需要有图片+标注文件。数据集可以使用网上公开的跟自己研究相契合的数据集,或者是搜索/拍摄自己研究所需要的图片进行标注制作成数据集,这里两种方法都详细介绍一下

2.1 网上搜索公开数据集

可以在搜索引擎上搜索或者在公开数据集的网站上搜索关键词,使用到的公开数据集网站为kaggleKaggle: Your Machine Learning and Data Science CommunityKaggle is the world’s largest data science community with powerful tools and resources to help you achieve your data science goals.https://www.kaggle.com/icon-default.png?t=O83Ahttps://www.kaggle.com/比如这里做一个安全帽检测的研究,就可以在搜索框输入安全帽的英文(因为是英文网站,都需要翻译成英文后搜索)Safety helmet

​​

搜索后就可以找到相关的内容,点击datasets筛选数据集,下载几个看一下数据集是否为目标检测的数据格式,一般文件夹为JPEGImages和Annotations包含这两个就可以使用​​

点开一个后点击download即可下载。

若是下载到分割数据集,即json格式的标注可以看我的这篇文章转为txt,其他数据格式转换也可以私聊问https://blog.csdn.net/qq_67105081/article/details/138123877https://blog.csdn.net/qq_67105081/article/details/138123877

2.2 自制数据集

自制数据集需要先获取一定数量的目标图片,可以拍摄或者下载,图片足够之后使用标注工具Labelimg进行标注

2.2.1 Labelimg安装

使用Labelimg建议使用python3.10以下的环境,这里创建一个python3.8的虚拟环境,不会创建的可以去环境配置的文章下学习

conda create -n labelimg python=3.8

这里创建完之后进入labelimg环境

conda activate labelimg

进入labelimg环境之后通过pip下载labelimg(报错则需要关闭加速软件)

pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple

安装完成之后就可以使用

2.2.2 Labelimg使用

在使用labelimg之前,需要准备好数据集存放位置,这里推荐创建一个大文件夹为data,里面有JPEGImages、Annotations和classes.txt,其中JPEGImages文件夹里面放所有的图片,Annotations文件夹是将会用来对标签文件存放,classes.txt里存放所有的类别,每种一行
​​

classes.txt里存放所有的类别,可以自己起名,需要是英文,如果有空格最好用下划线比如no_hat

​​

上述工作准备好之后,在labelimg环境中cd到data目录下,如果不是在c盘需要先输入其他盘符+:

例如d: 回车之后再输入文件路径,接着输入以下命令打开labelimg

labelimg JPEGImages classes.txt

打开软件后可以看到左侧有很多按钮,open dir是选择图片文件夹,上面选过了

​​

点击change save dir 切换到Annotations目录之中,点击save下面的图标切换到pascal voc格式

切换好之后点击软件上边的view,将 Auto Save mode(切换到下一张图会自动保存标签)和Display Labels(显示标注框和标签) 保持打开状态。

常用快捷键:

A:切换到上一张图片

D:切换到下一张图片

W:调出标注十字架

del :删除标注框

例如,按下w调出标注十字架,标注完成之后选择对应的类别,这张图全部标注完后按d下一张

​​

所有图像标注完成后数据集即制作完成。

2.3 数据集转换及划分

2.3.1 数据集VOC格式转yolo格式

暂时还没有数据集可以先点击下载安全帽检测数据跟着本文进行训练。

如何查看自己数据集格式,打开Annotations文件夹,如果看到文件后缀为.xml,则为VOC格式,如果文件后缀为.txt则一般为yolo格式,后缀名看不到请搜索 如何显示文件后缀名。yolov9训练需要转为yolo格式训练,转换代码如下:

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join


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


def convert_annotation(xml_files_path, save_txt_files_path, classes):
    xml_files = os.listdir(xml_files_path)
    print(xml_files)
    for xml_name in xml_files:
        print(xml_name)
        xml_file = os.path.join(xml_files_path, xml_name)
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree = ET.parse(xml_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
            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))
            # b=(xmin, xmax, ymin, ymax)
            print(w, h, b)
            bb = convert((w, h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


if __name__ == "__main__":
    # 需要转换的类别,需要一一对应
    classes1 = ['hat','nohat']
    # 2、voc格式的xml标签文件路径
    xml_files1 = r'f:\data\Annotations'
    # 3、转化为yolo格式的txt标签文件存储路径
    save_txt_files1 = r'f:\data\labels'

    convert_annotation(xml_files1, save_txt_files1, classes1)

需要自行将类别以及文件路径替换,这里顺序要记住,文件夹也对应替换,不知道有哪些类别可以看这篇博客统计标注文件xml文件类别-CSDN博客。

2.3.2 数据集划分

训练自己的yolov9检测模型,数据集需要划分为训练集、验证集,这里提供一个参考代码,划分比例为8:2(这里不再划分测试集),也可以按照自己的比例划分修改代码,三者加起来为1即可

import os
import shutil
import random

random.seed(0)


def split_data(file_path,xml_path, new_file_path, train_rate, val_rate, test_rate):
    each_class_image = []
    each_class_label = []
    for image in os.listdir(file_path):
        each_class_image.append(image)
    for label in os.listdir(xml_path):
        each_class_label.append(label)
    data=list(zip(each_class_image,each_class_label))
    total = len(each_class_image)
    random.shuffle(data)
    each_class_image,each_class_label=zip(*data)
    train_images = each_class_image[0:int(train_rate * total)]
    val_images = each_class_image[int(train_rate * total):int((train_rate + val_rate) * total)]
    test_images = each_class_image[int((train_rate + val_rate) * total):]
    train_labels = each_class_label[0:int(train_rate * total)]
    val_labels = each_class_label[int(train_rate * total):int((train_rate + val_rate) * total)]
    test_labels = each_class_label[int((train_rate + val_rate) * total):]

    for image in train_images:
        print(image)
        old_path = file_path + '/' + image
        new_path1 = new_file_path + '/' + 'train' + '/' + 'images'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + image
        shutil.copy(old_path, new_path)

    for label in train_labels:
        print(label)
        old_path = xml_path + '/' + label
        new_path1 = new_file_path + '/' + 'train' + '/' + 'labels'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + label
        shutil.copy(old_path, new_path)

    for image in val_images:
        old_path = file_path + '/' + image
        new_path1 = new_file_path + '/' + 'val' + '/' + 'images'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + image
        shutil.copy(old_path, new_path)

    for label in val_labels:
        old_path = xml_path + '/' + label
        new_path1 = new_file_path + '/' + 'val' + '/' + 'labels'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + label
        shutil.copy(old_path, new_path)

    for image in test_images:
        old_path = file_path + '/' + image
        new_path1 = new_file_path + '/' + 'test' + '/' + 'images'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + image
        shutil.copy(old_path, new_path)

    for label in test_labels:
        old_path = xml_path + '/' + label
        new_path1 = new_file_path + '/' + 'test' + '/' + 'labels'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + label
        shutil.copy(old_path, new_path)


if __name__ == '__main__':
    file_path = r"f:\data\JPEGImages"
    txt_path = r'f:\data\labels'
    new_file_path = r"f:\VOCdevkit"
    split_data(file_path,txt_path, new_file_path, train_rate=0.8, val_rate=0.2, test_rate=0.0)

3. 训练模型

需要下载源码,这里选择的是yolov9默认的main版本

不会下载源码的可以看我的这篇博客,也可以点此直接下载,我这里把源码和预训练权重yolov9-t.pt和yolov9-s.pt一起打包上传了。

有了源码之后需要修改里面的参数,导入自己的数据集

3.1 创建data.yaml

在yolov9/data目录下(也就是本文所用的yolov9-main/data目录下)创建一个新的data.yaml文件,也可以是其他名字的例如hat.yaml文件,后缀需要为.yaml,内容如下

train: f:/VOCdevkit/train/images  # train images (relative to 'path') 128 images
val: f:/VOCdevkit/val/images  # val images (relative to 'path') 128 images
 
nc: 2
 
# Classes
names: ['hat','nohat']

具体路径和类别自己替换,需要和上面数据集转换那里类别顺序一致。

3.2 训练模型

这是使用官方提供的预训练权重进行训练,使用yolov9-s.pt,训练较慢也可以使用yolov9-t.pt。

下载完成之后放入yolov9-main根目录中,建议点击上面链接下载。打开train_dual.py文件,修改方框中框选部分内容

其中weights为导入模型,这里修改为yolov9-t-converted.pt或者其他模型,cfg为改为yolov9-t.yaml或者pt对应的yaml文件名,data改为data/data.yaml,修改为自己新建的文件名,epochs可以先设为10,能够正常训练并且保存结果再修改为100或者更多,batch-size根据自己的电脑性能设置大小,建议为2的n次方,可以多次修改找到最适合自己电脑的参数大小。

训练过程如图,耐心等待训练完成即可,训练完成后会生成best.pt权重文件,可以用来验证训练效果或者部署到可视化界面之中展示。

​​

训练过程中遇到报错可以评论区留言,看到都会及时回复

4. 模型测试

找到之前训练的结果保存路径,打开一个detect.py文件,修改图中yolov9.pt为训练好的权重文件路径,如runs/train/exp4/weights/best.pt,然后将待检测图片或视频放入inference/images文件夹中

运行后就会得到预测模型结果

可以打开对应路径下查看预测的图片效果,模型就训练好啦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2202524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在树莓派上部署安装OAK

OAK设备可以与微型主机(例如树莓派)进行连接,在树莓派上安装DepthAI, 需要安装相关依赖Dependencies并且可以通过pip安装Depthai Library. DepthAI Library 在PyPi上对树莓派有预构建的 wheels 使用预配置的树莓派OS 镜像 我们提供预安装了D…

MIBench:首个模型反演攻击与防御基准测试工具。不仅集成了16种最先进的攻击和防御方法,还提供了9种常用评估协议,为标准化和公平的评估分析提供了便利。

2024-10-08,由哈尔滨工业大学(深圳)和清华大学深圳国际研究生院的研究人员联合创建的MIBench,作为首个模型反演攻击和防御的实用基准测试,不仅集成了16种最先进的攻击和防御方法,还提供了9种常用评估协议&a…

SRAM,DRAM,DTCM RAM,ITCM RAM

一:SRAM,DRAM,DTCM RAM,ITCM RAM 1.SRAM:(Static Random Access Memory)一种静态随机存取存储器计算机系统和嵌入式系统中作为高速数据存储容器,SRAM 使用触发器电路来存储每个位的数据&#x…

IDEA使用Maven创建父与子多模块项目

在 IntelliJ IDEA 中使用 Maven 创建父与子多模块项目是一个常见的开发实践,有助于更好地组织和管理代码。在多模块项目中,可以将公共的代码、资源或配置抽离到独立的模块中,然后在其他模块中直接引用。这样可以避免代码重复,提高…

【01】手把手教你0基础部署SpringCloud微服务商城教学-Mybatis篇(上)

序言: 微服务是一种软件架构风格,它是以专注于单一职责的很多小型项目为基础,组合出复杂的大型应用。 想学习SpringCloud搭建项目,首先我们需要学习的就是Mybatis和Docker。 大家在日常开发中应该能发现,单表的CRUD…

IEC104规约的秘密之九----链路层和应用层

104规约从TCP往上,分成链路层和应用层。 如图,APCI就是链路层,ASDU的就是应用层 我们看到报文都是68打头的,因为应用层报文也要交给链路层发送,链路层增加了开头的6个字节再进行发送。 完全用于链路层的报文每帧都只有…

基于卷积神经网络的脊柱骨折识别系统,resnet50,mobilenet模型【pytorch框架+python】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示: 基于卷积神经网络的脊柱骨折识别系统,resnet50,mobilenet【pytorch框架,python,tkinter】_哔哩哔哩_bilibili (一)简介 基于卷…

C++ | Leetcode C++题解之第467题环绕字符串中唯一的子字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:int findSubstringInWraproundString(string p) {vector<int> dp(26);int k 0;for (int i 0; i < p.length(); i) {if (i && (p[i] - p[i - 1] 26) % 26 1) { // 字符之差为 1 或 -25k;} els…

京东统一存储实践

​作者&#xff1a;王腾蛟&#xff0c;2021年8月加入京东&#xff0c;目前主要负责京东离线存储(HDFS)相关工作。 导读 随着大数据时代的到来&#xff0c;海量数据的存储与处理成为了众多企业面临的重要挑战。HDFS 作为一个高可靠性、高扩展性的分布式文件系统&#xff0c;在…

1招!统一管理多个微信,工作效率真的太高了!

你是否经常在使用多个微信号时感到疲惫不堪&#xff1f;每当你需要切换账号时&#xff0c;是不是得不停地登陆、登出&#xff0c;甚至要带着几台手机外出&#xff1f;这种繁琐的操作不仅浪费时间&#xff0c;还严重影响了工作效率。 今天&#xff0c;我将为你分享一款强大的多…

【优选算法】(第三十二篇)

目录 ⼆进制求和&#xff08;easy&#xff09; 题目解析 讲解算法原理 编写代码 字符串相乘&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⼆进制求和&#xff08;easy&#xff09; 题目解析 1.题目链接&#xff1a;. - 力扣&#xff08;LeetCode&a…

C语言-常见文件操作函数详解(fgetc,fputc,fgets,fputs,fscanf,fprintf,fread,fwrite)

&#x1f30f;个人博客&#xff1a;尹蓝锐的博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 顺序读写数据常用函数 函数名调用形式功能返回值fgetcfgetc(fp)从指针变量fp指向的文件中读…

诺贝尔物理学奖向机器学习与神经网络致敬,科学边界的跨越与未来的启示

2024年诺贝尔物理学奖首次颁发给机器学习与神经网络领域的研究者&#xff0c;这一历史性事件打破了人们对诺贝尔物理学奖的传统认知&#xff0c;激起了全球学术界、科技界的广泛讨论。这一变化不仅标志着科学边界的延伸&#xff0c;也体现出人工智能技术对现实世界的深远影响。…

剪切走的照片:高效恢复与预防策略

一、剪切走的照片现象描述 在日常的数字生活中&#xff0c;照片作为记录生活点滴、工作成果的重要载体&#xff0c;其重要性不言而喻。然而&#xff0c;有时我们可能会遇到一种令人头疼的情况&#xff1a;原本打算通过剪切操作将照片移动到另一个位置&#xff0c;却意外地发现…

Java 8 的内存结构

Java8内存结构图 虚拟机内存与本地内存的区别 Java虚拟机在执行的时候会把管理的内存分配成不同的区域&#xff0c;这些区域被称为虚拟机内存&#xff0c;同时&#xff0c;对于虚拟机没有直接管理的物理内存&#xff0c;也有一定的利用&#xff0c;这些被利用却不在虚拟机内存…

Qt5.15.2静态编译 MinGW with static OpenSSL

如果想用VS2017编译,可参考:Qt5.15.2静态编译 VS2017 with static OpenSSL 一.环境 系统:Windows 10 专业版 64位 编译器:MinGW 8.1.0 第三方工具:perl,ruby和python PS:经验证,用MinGW 12.1.0来编译Qt5.15.2会报错 我用Phthon 2.7.18虽然可以编过,但是强烈建议Pyth…

0.0.0.0 127.0.0.1等几个特殊的IP地址

0.0.0.0 127.0.0.1 localhost 255.255.255.0 255.255.255.255 这都是些什么地址&#xff0c;代表了什么意思。 网络为系统服务器&#xff0c;系统需要网络。 这些地址在系统和网络都存在&#xff0c;作用和意思甚至基本相同。 一、0.0.0.0 在路由中&#xff1a;0.0.0.0表…

【面试宝典】深入Python高级:直戳痛点的题目演示(上)

目录 &#x1f354; 你知道深浅拷⻉的区别吗&#xff1f; &#x1f354; 字典反转&#xff0c;列表反转的实现&#xff1f; &#x1f354; 装饰器是什么&#xff0c;什么场景⽤到装饰器&#xff0c;举个例⼦&#xff1f; &#x1f354; 装饰器的实质是什么…

定时关机(python)

内容 为了更简单地实现定时关机&#xff0c;不必去记繁琐的命令行&#xff0c;于是搞了一个gui出来 基于python和Windows命令行实现&#xff0c;核心为&#xff1a; shutdown -s -t 60 代码 # -*- coding: utf-8 -*- # Environment PyCharm # File_name autoShutdown…

【教学类-36-10】20241010职业抽卡(midjounery-niji)(涂色、裁剪、游戏)

背景需求 昨天在户外玩了角色游戏&#xff0c;受道具所限&#xff08;只有烧烤做饭锅子材料&#xff09;&#xff0c;所有的孩子都只玩了烧烤店、娃娃家做饭的内容&#xff0c;扮演的都是爸妈、厨师等工作 今天从以前的纸类学具中找出一套数量相对较多的“职业涂色卡” 学具代…