yolov10来了!用yolov10训练自己的数据集(原理、训练、部署、应用)

一、引言

YOLOv9还没热乎呢,YOLOv10就出来了,太卷了!太快了!

自今年2月YOLOv9发布之后, YOLO(You Only Look Once)

系列的接力棒传到了清华大学研究人员的手上。YOLOv10推出的消息引发了AI界的关注,它被认为是计算机视觉领域的突破性框架,以实时的端到端目标检测能力而闻名,通过提供结合效率和准确性的强大解决方案,延续了YOLO系列的传统。

从图中可以看出,性能是持续提升的,欢迎各位小伙伴阅读完本篇文章后在评论区留言,谈谈你对本文的看法。

标题 :YOLOv10: Real-Time End-to-End Object Detection
论文https://arxiv.org/pdf/2405.14458
源码https://github.com/THU-MIG/yolov10

2、算法介绍

在我们深入探讨YOLOv10之前,让我们回顾一下YOLO的发展历程。YOLO在实时目标检测领域一直是先驱,兼顾速度和准确性。

从YOLOv1到YOLOv9,每个版本在架构、优化和数据增强方面都引入了显著的改进。然而,随着模型的发展,某些限制依然存在,特别是对后处理依赖非极大值抑制(NMS),这会减慢推理速度。YOLOv10正面解决了这些挑战,使其成为实时应用中稳健高效的模型。

2.1 YOLOv10亮点

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

YOLOv10亮点:

1.无 NMS 设计:利用一致的双重分配来消除对NMS的需求,从而减少推理延迟。

2.整体模型设计:从效率和准确性的角度全面优化各种组件,包括轻量级分类头、空间通道去耦向下采样和等级引导块设计。

3.增强的模型功能:纳入大核卷积和部分自注意模块,在不增加大量计算成本的情况下提高性能。

2.2 YOLOv10版本功能

YOLOv10有多种型号,可满足不同的应用需求,在COCO上的性能表现,包括其各个版本的区别如下:

Model Test Size #Params FLOPs AP^val^ Latency 版本说明
YOLOv10-N 640 2.3M 6.7G 38.5% 1.84ms 用于资源极其有限环境的纳米版本
YOLOv10-S 640 7.2M 21.6G 46.3% 2.49ms 兼顾速度和精度的小型版本
YOLOv10-M 640 15.4M 59.1G 51.1% 4.74ms 通用中型版本
YOLOv10-B 640 19.1M 92.0G 52.5% 5.74ms 平衡型,宽度增加,精度更高
YOLOv10-L 640 24.4M 120.3G 53.2% 7.28ms 大型版本,精度更高,但计算资源增加
YOLOv10-X 640 29.5M 160.4G 54.4% 10.70ms 超大型版本可实现最高精度和性能

3、网络结构

关于YOLOv10的网络结构图具体如下图所示:

3.1 主要改进:

  • Backbone & Neck:使用了先进的结构如 CSPNet 作为骨干网络,和 PAN 作为颈部网络,优化了特征提取和多尺度特征融合。
  • 大卷积核与分区自注意力:这些技术用于增强模型从大范围上下文中学习的能力,提高检测准确性而不显著增加计算成本。
  • 整体效率:引入空间-通道解耦下采样和基于秩引导的模块设计,减少计算冗余,提高整体模型效率。

3.2 YOLOv10与v8结构对比:

从结构上看添加了PSA和在C2f结构中添加了CBI结构。结构设计如下:

而且去掉了NMS:

4、数据准备

在模型训练开始前,首先要进行训练数据准备。由于YOLOv10跟YOLOv8数据集结构一样,所以本文不再重复介绍数据标注、数据清洗、数据集格式转换等操作,有需要的同学可以参考我之前写的《YOLOv8训练自己的数据集+常用传参说明》

YOLOv8训练自己的数据集+常用传参说明:http://t.csdnimg.cn/hyu8C

包含:

准备数据集

python批量重命名

使用labelimg进行标注

labelimg使用说明

数据集的划分

转换数据集格式

编写数据集配置文件

使用YOLOv8训练自己的数据集等

本文为测试YOLOv10的性能,特选取SAR-AIRcraft-1.0:高分辨率SAR飞机检测识别数据集,共发布图像4,368幅,共有16,463个飞机目标实例,包括A220、A320/321、A330、ARJ21、Boeing737、Boeing787和other共7个类别,支持检测任务、识别任务以及检测识别一体化任务。本数据集具有场景复杂、类别丰富、目标密集、噪声干扰、任务多样、多尺度性的特点。

数据集下载地址:https://radars.ac.cn/web/data/getData?dataType=SARDataset

4.1数据集格式

准备数据集格式如下:

这里是数据集根目录

├── Annotations (下载下来的xml文件标注信息)

│ ├── 0000001.xml

│ ├── 0000002.xml

│ ├── 0000003.xml

├── images (下载下来的JPEGImages文件夹,重命名为images)

│ ├── 0000001.jpg

│ ├── 0000002.jpg

│ ├── 0000003.jpg

├── ImageSets(通过程序split_train_val.py分割出来的训练集、验证集)

│ ├── test.txt

│ ├── train.txt

│ ├── trainval.txt

│ └── val.txt

├── labels(通过程序voc_label.py将xml文件转为yolo训练格式的txt文件)

│ ├── 0000001.txt

│ ├── 0000002.txt

│ ├── 0000003.txt

├── sar.yaml (模型训练的数据集配置文件)

├── split_train_val.py

├── test.txt

├── train.txt

├── val.txt

└── voc_label.py

4.2 数据集的划分

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

split_train_val.py

python 复制代码
import os
import random


trainval_percent = 0.9
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = '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('ImageSets/trainval.txt', 'w')
ftest = open('ImageSets/test.txt', 'w')
ftrain = open('ImageSets/train.txt', 'w')
fval = open('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()

4.3 转换数据集格式

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

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

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

voc_label.py

python 复制代码
import xml.etree.ElementTree as ET
import os
from os import getcwd
 
sets = ['train', 'val', 'test']
# 改成你自己的分类
classes = ['A220','A320/321','A330','ARJ21','Boeing737','Boeing787', 'other']
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/%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()

4.4 编写数据集配置文件

创建 sar.yaml

内容如下,其文件路径正是上文生成的划分配置集文件(建议写为绝对路径,否则会出一些问题)

nc代表类别数量,比如我这里是7个分类

names是每个分类名称

sar.yaml

python 复制代码
train: /data/datasets/SAR-aircraft1.0/train.txt
val: /data/datasets/SAR-aircraft1.0/val.txt
test: /data/datasets/SAR-aircraft1.0/test.txt

nc: 7
names:
  0: A220
  1: A320/321
  2: A330
  3: ARJ21
  4: Boeing737
  5: Boeing787
  6: other

5、YOLOv10安装与训练

介绍了那么多,终于来到了本文的重点,开始安装使用YOLOv10。其实如果使用过YOLOv8,再使用YOLOv10的话会很简单。那么我们根据官方文档介绍,一步步按照即可,所需要的Anaconda环境可以参考本人前几篇文章教程。

5.1 下载源码

源码地址:https://github.com/THU-MIG/yolov10

可以直接在服务器上使用git下载,命令如下:

bash 复制代码
# 下载yolov10源码
git clone https://github.com/THU-MIG/yolov10.git
# 进入yolov10目录
cd yolov10

下载后目录如下:

5.2 环境配置与安装

使用conda 创建虚拟环境配置【输入命令前,需进入到项目目下】。命令如下:

bash 复制代码
conda create -n yolov10 python=3.9
conda activate yolov10
pip install -r requirements.txt
pip install -e .

安装完成之后,我们简单执行下推理命令测试下效果:

bash 复制代码
yolo predict model=yolov10s.pt source=ultralytics/assets/bus.jpg

这里需要提前把yolov10s.pt预训练模型下载好,下载地址:https://github.com/THU-MIG/yolov10/releases/tag/v1.1

选择对应的版本进行下载,然后导入到yolov10的安装目录即可。

如果都成功执行,那么就已经正确安装完成YOLOv10了。

5.3 训练模型

在yolov10目录下,编写训练模型train.py

注意这个地方需要导入YOLOv10模块,不是YOLO模块。

训练代码如下:

bash 复制代码
# coding:utf-8
from ultralytics import YOLOv10
# 模型配置文件
model_yaml_path = "ultralytics/cfg/models/v10/yolov10n.yaml"
# 数据集配置文件,最好写绝对路径
data_yaml_path = '/data/datasets/SAR-aircraft1.0/sar.yaml'
# 预训练模型
pre_model_name = 'yolov10n.pt'

if __name__ == '__main__':
 # 加载预训练模型
    model = YOLOv10("ultralytics/cfg/models/v10/yolov10n.yaml").load(pre_model_name)
 # 训练模型
    results = model.train(data=data_yaml_path,
                          epochs=100, 
                          batch=64, # 训练批次,默认16,根据你的GPU情况适当调小
                          workers=64, # 载入数据的线程数
                           resume=True, # 断点训练,默认Flase
                          name='train_v10')

执行python train.py开始训练,打印的网路结构如下:

模型训练完成的结果展示:

再对比下YOLOv8n的训练结果:

可以看出,YOLOv10的参数量更小,权重文件也更小,但似乎YOLOv8精度更高点。。。

5.4 模型推理

在YOLOv10目录下创建predict.py

模型推理代码如下:

python 复制代码
from ultralytics import YOLOv10
  
# Load a pretrained YOLOv10n model
model = YOLOv10("runs/detect/train_v104/weights/best.pt")

# Perform object detection on an image
# results = model("test1.jpg")
results = model.predict("0000001.jpg")

# Display the results
results[0].show()

模型推理输出结果如下:

当然,如果你有可视化界面,可以直接看到推理结果。我这里只输出了推理结果的标签展示。

5.5 模型导出

我们还可以在YOLOv10目录下创建export.py,执行模型导出为onnx格式,文件内容如下:

python 复制代码
from ultralytics import YOLOv10
# Load a model
model = YOLOv10('yolov10x.pt') # load an official model
model = YOLOv10('runs/detect/train_v104/weights/best.pt') # load a custom trained model
 
# Export the model
model.export(format='onnx')

执行该文件,可见已经将模型导出到/data/yolov10/runs/detect/train_v104/weights目录下

6、总结

清华大学研究人员推出的YOLOv10,作为首个无NMS目标检测模型,代表了计算机视觉领域的重大进步。与YOLOv8相比,YOLOv10显著减少了推理延迟,使其更适合高速实时应用,如自动驾驶、视频监控和交互式AI系统。这种推理过程中计算步骤的减少突显了YOLOv10的效率和响应能力。

此外,YOLOv10采用了新的无NMS训练方法,对其各部分进行了微调以提高性能,并在速度和准确性之间达到了很好的平衡。这些升级使得模型的部署更容易,性能更强,速度更快,响应更迅速。无论你是研究人员、开发人员还是技术爱好者,YOLOv10都是值得关注的模型。

如果你有其他疑问,欢迎私信,或者点击下方小卡片,加我微信好友共同学习!

相关推荐
GL_Rain1 分钟前
【OpenCV】Could NOT find TIFF (missing: TIFF_LIBRARY TIFF_INCLUDE_DIR)
人工智能·opencv·计算机视觉
shansjqun5 分钟前
教学内容全覆盖:航拍杂草检测与分类
人工智能·分类·数据挖掘
狸克先生8 分钟前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互
baiduopenmap22 分钟前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
小任同学Alex26 分钟前
浦语提示词工程实践(LangGPT版,服务器上部署internlm2-chat-1_8b,踩坑很多才完成的详细教程,)
人工智能·自然语言处理·大模型
新加坡内哥谈技术32 分钟前
微软 Ignite 2024 大会
人工智能
江瀚视野1 小时前
Q3净利增长超预期,文心大模型调用量大增,百度未来如何分析?
人工智能
陪学1 小时前
百度遭初创企业指控抄袭,维权还是碰瓷?
人工智能·百度·面试·职场和发展·产品运营
QCN_1 小时前
湘潭大学人工智能考试复习1(软件工程)
人工智能
Landy_Jay1 小时前
深度学习:GPT-1的MindSpore实践
人工智能·gpt·深度学习