【yolov10】使用自己的数据集训练目标检测模型并实际应用

1、YOLOv10介绍

YOLOv10是清华大学的研究人员在Ultralytics Python包的基础上,引入了一种新的实时目标检测方法,解决了YOLO 以前版本在后处理和模型架构方面的不足。通过消除非最大抑制(NMS)和优化各种模型组件,YOLOv10 在显著降低计算开销的同时实现了最先进的性能。大量实验证明,YOLOv10 在多个模型尺度上实现了卓越的精度-延迟权衡。

1ca217348e154e4f88a9cc5beea36f39.jpeg

2、yolov10模型图

3ff1b2f1e28a45d6a7c5ea28e8b7be52.png

3、前期准备

anaconda3、pycharm下载完成(最好不要最新版本,也不要太旧,与最新版本保持两个版本差距就行)

这是我用的版本:

ddb009350e69417dbfa630a74d995e9d.png

4、yolov10模型、权重下载

1.模型下载:​ ​​github模型代码下载 ​

103e7431fbdd4d12b9e4d273031cb5fe.jpeg

2.模型权重下载(非必须):yolov10模型下载相同位置,往下翻

或者直接输入:

YOLOV10N:https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10n.pt
YOLOV10S:https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10s.pt
YOLOV10M:https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10m.pt
YOLOV10B:https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10b.pt
YOLOV10L:https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10l.pt
YOLOV10X:https://github.com/THU-MIG/yolov10/releases/download/v1.1/yolov10x.pt

我在这里下载的是yolov10n,下载完成后直接放yolov10文件夹根目录下:

225c3e84bb504cba89aa8dccbc19f856.jpeg

5、环境配置

打开anaconda prompt

1215c9ae275b438db5209bedccbf2801.jpeg

cd进入你下载的yolov10文件夹中

在这里借别人个图,作者忘记截图了。。。

0db89ce4c7a94a1b9317d366b10d8b12.png

创建yolov10环境:输入 conda create -n yolov10(代表环境名称)python=3.9(使用Python的版本),按y+回车。

d86738f9d46148b18327b66fe0934855.png

进入你刚安装的yolov10环境:conda activate yolov10(你的环境名称)

上两步无脑复制:

conda create -n yolov10 python=3.9
conda activate yolov10

进入后()会变成你环境名称 (判断是否安装成功)

f8e1016495584f27aa2ee2d23e0b8365.png

5.2.下载yolov10依赖库

首先到你下载的yolov10文件中找到requirements.txt文件

bf9395a6d6444cbd97d7c236e140e39f.jpeg

这个标记蓝色的直接删除,这是cpu版本的torch和torchvison

dbc352cb743a4c8699d7304b929e8f18.png

然后安装包里的库文件(里面的库依赖可能会冲突,下面再说)

pip install -r requirements.txt

去除模型只读权限(如果说你要修改模型,必须pip install -e.,如果说只是复现,可加可不加)

中间没有报错,就代表下载成功。

5.3.下载CUDA

cuda是连接GPU和模型训练的桥梁。

查看cuda最高支持版本,win+R,输入cmd,打开命令窗口,输入nvidia-smi.exe,红框位置为最大可支持安装版本。

4c34fd8997404eb9b5082eb2f8dfc6c5.jpeg

在你刚才激活的环境中输入:

conda install cudatoolkit=11.7

5.4.下载pytorch

cuda是连接GPU和模型训练的桥梁,pytorch是进入桥梁那段上坡的路(pytorch库必须和cuda版本匹配)(其实这个在之前下载yolov10虚拟环境已经下载过了,但是为了确保你的pytorch版本和CUDA版本一致,所以这里在从下一遍以确保环境没有问题)

无脑复制:

conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia

6、pycharm添加解释器

打开pycharm

点击文件、设置

45333a913b8741fa8dc74c14fc4774b4.jpeg

找到Python解释器

3b433f4b6faa4f739fad18be8cb65dff.jpeg

找到conda环境、使用现有环境,找到你前面配置的yolov10(环境名称)

b80e9c92eb82403b84c076af5c0fed54.png

6.1. 检查pytorch是否下载成功

建立cuda.py

import torch
print('CUDA版本:',torch.version.cuda)
print('Pytorch版本:',torch.__version__)
print('显卡是否可用:','可用' if(torch.cuda.is_available()) else '不可用')
print('显卡数量:',torch.cuda.device_count())
print('当前显卡型号:',torch.cuda.get_device_name())
print('当前显卡的CUDA算力:',torch.cuda.get_device_capability())
print('当前显卡的总显存:',torch.cuda.get_device_properties(0).total_memory/1024/1024/1024,'GB')
print('是否支持TensorCore:','支持' if (torch.cuda.get_device_properties(0).major >= 7) else '不支持')
print('当前显卡的显存使用率:',torch.cuda.memory_allocated(0)/torch.cuda.get_device_properties(0).total_memory*100,'%')

7、数据集制作

7.1. 准备工作

在yolov10根目录下新建datasets文件夹

83f38c6bfce845e79462889d49e0dc65.png

然后如果你有多个项目要训练多个不同模型可以再建立多个(我用的fish)project_1,project_2......

或者直接创建四个文件夹:

Annotations文件夹:用来存放使用labelimg给每张图片标注后的xml文件,后面会讲解如何使用labelimg进行标注。
Images文件夹:用来存放原始的需要训练的数据集图片,图片格式为jpg格式。
ImageSets文件夹:用来存放将数据集划分后的用于训练、验证、测试的文件。
Labels文件夹:用来存放将xml格式的标注文件转换后的txt格式的标注文件。

先在根目录下创建好对应的文件夹(只看文件夹的结构),最终效果如图所示:

e43c30ed347c459d8630e476ae3302a7.png

7.2.  准备数据集

因为我做的人脸识别不便透漏,在这里不再放置图片。
ex:

关于小麦病害的检测,根据采集的数据集将小麦病害划分为7个种类,分别为白粉病、赤霉病、叶锈病、条锈病、颖枯病、正常麦穗、正常麦叶。下图为数据集的一部分,共准备了四千多张原始图片,大约每个种类600张。此处会用到一个非常高效的重命名方式,就不用一张一张图片的进行重命名。批量重命名的代码如下。4000张图片准备好后就放在images文件夹中即可。

rename.py

import os


class BatchRename():
    '''
    批量重命名文件夹中的图片文件
    '''

    def __init__(self):
        self.path = r"E:\YOLOv10\datasets\fish\images"  # 表示需要命名处理的文件夹,这里改为你自己的路径
        self.new_path = r"E:\YOLOv10\datasets\fish\images\new"

    def rename(self):
        filelist = os.listdir(self.path)  # 获取文件夹中文件的所有的文件
        total_num = len(filelist)  # 获取文件长度(个数)
        i = 1  # 表示文件的命名是从1开始的
        for item in filelist:
            if 1:  # 初始的图片的格式为jpg格式的(或者源文件是png格式及其他格式,后面的转换格式就可以调整为自己需要的格式即可)
                src = os.path.join(os.path.abspath(self.path), item)  # 连接两个或更多的路径名组件
                # dst = os.path.join(os.path.abspath(self.new_path), ''+str(i) + '.jpg')#处理后的格式也为jpg格式的,当然这里可以改成png格式
                dst = os.path.join(os.path.abspath(self.path),
                                   'wheat' + format(str(i), '0>3s') + '.jpg')  # 这种情况下的命名格式为wheat000.jpg形式,可以自主定义想要的格式
                try:
                    os.rename(src, dst)  # src – 要修改的目录名      dst – 修改后的目录名
                    print('converting %s to %s ...' % (src, dst))
                    i = i + 1
                except:
                    continue
        print('total %d to rename & converted %d jpgs' % (total_num, i))


if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()

 7.3. 使用labelimg进行标注

labelimg的安装很简单,直接使用pip命令安装就可以

安装labelimg

pip install labelimg

启动
labelimg

Labelimg是一个图像标注工具,软件使用非常简单,安装成功后终端直接输入labelimg就可以直接启动

87420f9366944addb28e4ef3ffde13de.png

使用说明:

(1)Open就是打开图片,我们不需要一张一张的打开,太麻烦了,使用下面的Open Dir

(2)Open Dir就是打开需要标注的图片的文件夹,这里就选择images文件夹

(3)change save dir就是标注后保存标记文件的位置,选择需要保存标注信息的文件夹,这里就选择Annotations文件夹

(4)特别注意需要选择好所需要的标注文件的类型。有yolo(txt), pascalVOC (xml)两种类型。yolo需要txt文件格式的标注文件,但是这里我们选择pascalVOC,后面再将xml格式的标注文件转化为所需的txt格式。

(5)按W键或点击Create\nRectBox开始创建矩形框,把要进行识别训练的区域标记出来就行,选好框后我们定义是什么类别(这个就是你的标签,后面所有的与标签有关的都要与这里分类一致),整张图片的所有目标都标记好了之后按Ctrl+S或点击Save保存 ,然后切换下一张继续,快捷键为按D键,每一张图片标记后都要保存,这个过程是一个比较繁琐的过程。

标注之后的效果如下图所示,会在目标目录生成对应的xml文件:

e725e2cdb9f14fb39bdcf42232f6ba74.jpeg

7.4. .数据集的划分

在根目录或datasets下创建一个脚本,创建一个split_train_val.py文件,运行文件之后会在imageSets文件夹下将数据集划分为训练集、验证集、测试集,里面存放的就是用于训练、验证、测试的图片名称。代码内容如下:

import os
import random

trainval_percent = 0.9 #训练集所占比例,还有一种划分是,训练集:验证集:测试集 (7:2:1) 
train_percent = 0.9
xmlfilepath = 'fish/Annotations'
txtsavepath = 'fish/imageSets'
total_xml = os.listdir(xmlfilepath)

num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)

ftrainval = open('fish/imageSets/trainval.txt', 'w')
ftest = open('fish/imageSets/test.txt', 'w')
ftrain = open('fish/imageSets/train.txt', 'w')
fval = open('fish/imageSets/val.txt', 'w')

for i in list:
    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()

7.5. 转换数据集格式

创建voc_label.py文件,它的作用:

(1)就是把Annoctions里面的xml格式的标注文件转换为txt格式的标注文件,每个图像对应一个txt文件,文件每一行为一个目标的信息,包括class, x_center, y_center, width, height。

(2)就是运行后除了会生成转换后labels文件夹下的图片的txt文件,还会在data文件夹下得到三个包含数据集路径的txt文件,train.tx,tes.txt,val.txt这3个txt文件为划分后图像所在位置的绝对路径,如train.txt就含有所有训练集图像的绝对路径。

import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val', 'test']
# 改成你自己的分类,标注时所打的标签
classes = ['li', 'djs']
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('fish/Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('fish/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('fish/labels/'):
        os.makedirs('fish/labels/')
    image_ids = open('fish/imageSets/%s.txt' % (image_set)).read().strip().split()
    list_file = open('fish/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write(abs_path + '/fish/images/%s.jpg\n' % (image_id)) #路径拼接,容易出错,前面需要加/,如果后面你运行报的错误与路径有关记得检查这里
        convert_annotation(image_id)
    list_file.close()

转换成的txt文件格式应为:

ab584788ee734bd69ae880797628835d.png

前面的0,1代表你划分的种类的序列。

7.6.  编写数据集配置文件

创建 wheat.yaml
内容如下,其文件路径正是上文生成的划分配置集文件
nc代表类别数量,比如我这里是2个分类
names是每个分类名称

train: E:\YOLOv10\datasets\fish\train.txt
val: E:\YOLOv10\datasets\fish\val.txt
test: E:\YOLOv10\datasets\fish\test.txt

nc: 2
names:
  0: li  
  1: djs

到这里数据集制作完成!

8、训练自己的数据集

8.1.  命令行运行

(1)yolo提供自己的指令模式,在调参方面十分方便,可以直接用命令来完成:

yolo train data=你的配置文件(xx.yaml)的绝对路径 model=yolov8n.pt epochs=300 imgsz=640 batch=8 workers=0 device=0

8.2.  文件运行(我喜欢的)

在项目跟目录创建train.py文件

from ultralytics import YOLO

if __name__ == '__main__':
    # 加载模型
    model = YOLO(r"E:\YOLOv10\ultralytics\cfg\models\v10\yolov10n.yaml")

    # 训练模型
    results = model.train(data="fish/wheat.yaml",
                          resume=True,
                          epochs=100,
                          project='wheat',
                          patience=30,
                          name='wheat-yolov10n-100',
                          amp=False,
                          device=0,
                          exist_ok=True)

然后直接运行就可以开始训练, 这种和使用命令行运行是一样的,只是这样更清晰,参数更明了。具体参数说明请看官网:火车 -Ultralytics YOLO 文档

500eba9929274133b052d603f3a49261.jpeg

fd9a0944cb05489e8c80676c5032037f.png

如果一切正常的话,那么就只需静静等待模型的训练啦!

9、模型检验与推理

在你的datasets文件夹下新建predict文件夹,将用于检验模型的图片放在里面,然后创建Python文件image_test.py:

import os
from ultralytics import YOLOv10

# 加载预训练模型
model = YOLOv10(r"E:\YOLOv10\datasets\wheat\wheat-yolov10n-100\weights\best.pt")

# 获取预测目录下所有图片的路径
predict_dir = r"E:\YOLOv10\datasets\fish\predict"
image_paths = [os.path.join(predict_dir, img) for img in os.listdir(predict_dir) if
               img.endswith(('.jpg', '.jpeg', '.png'))]

# 对每张图片进行推理
for image_path in image_paths:
    results = model.predict(image_path)

    # 显示预测结果
    results[0].show()

还可以打开你设备的摄像头进行实时的推理,新建video_test.py:

import cv2
from ultralytics import YOLOv10

# 加载YOLOv10模型
model = YOLOv10(r"E:\YOLOv10\datasets\wheat\wheat-yolov10n-100\weights\best.pt")

# 打开摄像头
cap = cv2.VideoCapture(0)  # 0 表示使用第一个摄像头

# 检查是否成功打开摄像头
if not cap.isOpened():
    print("无法打开摄像头")
    exit()

# 实时获取摄像头帧并进行推理
while True:
    ret, frame = cap.read()  # 读取摄像头帧
    if not ret:
        print("无法接收帧")
        break

    # 使用YOLOv10模型对帧进行推理
    results = model.predict(frame)

    # 将结果绘制到帧上
    annotated_frame = results[0].plot()

    # 显示带有预测结果的帧
    cv2.imshow('YOLOv10 Real-Time Detection', annotated_frame)

    # 按下 'q' 键退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头资源并关闭窗口
cap.release()
cv2.destroyAllWindows()

10、可能遇到的错误

(1)可能遇到numpy与OpenCV版本冲突问题,这时候你可以尝试更新其中一个的版本(不要同时更新,我升级OpenCV版本后解决)

pip install --upgrade numpy
pip install --upgrade opencv-python

(2)在训练时可能遇到worning这时候如果是找不到标签或者找不到某个文件,请检查以上所有步骤中与文件路径有关的,检查是否有拼写错误等。

参考文章:

YOLOv8训练自己的数据集+常用传参说明_yolov8训练命令-优快云博客

YOLOv10GPU训练自己的数据(含网络结构图) (草履虫都能看懂系列)_yolov10 gpu-优快云博客YOLOv9最详细教程(训练自己数据集、结构介绍、重点代码讲解)(草履虫都能看懂系列)-优快云博客

YOLOV10训练自己的数据集_yolov10下载-优快云博客

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值