YOLOv10的改进、部署和微调训练总结

server/2025/2/11 21:08:47/

YOLO模型因其在计算成本和检测性能之间的平衡而在实时目标检测中很受欢迎。前几天YOLOv10也刚刚发布了。我们这篇文章就来看看YOLOv10有哪些改进,如何部署,以及微调。

YOLOv10通过无nms的训练解决了延迟问题,作者为无nms训练引入了一致的双任务,同时获得了具有竞争力的性能和低推理延迟。他们还提出了一种整体的效率-精度驱动模型设计策略,从效率和精度两个角度对各种YOLO组件进行优化。这减少了计算开销并提高了性能。

通过以上一些列的优化YOLOv10具有最先进的性能和效率。例如,YOLOv10-S比RT-DETR-R18快1.8倍,精度相似但参数和FLOPs更少。与YOLOv9-C相比,在相同性能下,YOLOv10-B的延迟减少了46%,参数减少了25%。

方法

Consistent Dual Assignments

YOLO模型通常使用任务对齐学习(Task Alignment Learning, TAL)进行训练,这涉及到为每个实例分配多个正样本,增强优化和性能。但是这种方法需要进行非最大抑制(NMS)后处理,降低了推理效率。虽然一对一匹配避免了NMS,但它并不能得到最佳的性能。

送一作者介绍了一种使用双标签分配和一致匹配度量的无nms训练策略。

在训练过程中,一对一头部与传统的一对多头部合并,两者共享相同的优化目标,但使用不同的匹配策略。一对多头部提供了丰富的监控信号,而一对一头部在推理过程中确保了高效,无nms的预测。在推理时只使用一对一的头部,避免额外的成本。

为了协调训练过程,使用了一致的匹配度量。该度量使用平衡语义预测和位置回归任务的统一方法,评估一对多和一对一分配的预测和实例之间的一致性。通过调整来自两个头部的监督,模型可以确保一个头部的最佳样本也是另一个头部的最佳样本,从而一致地优化两者。这种方法显著改善了一对一匹配对与一对多匹配的顶级结果的一致性。

精度驱动的模型设计

由于YOLO模型本身的结构,其计算冗余和能力有限,在平衡效率和准确性方面面临挑战。所以作者提出了全面的模型设计来解决这些问题,同时注重效率和准确性。

效率驱动型模型设计:

  • 通过使用深度可分离卷积的简化架构来减少计算开销。
  • 分离空间减少和信道增加减少计算成本并保留信息。
  • 使用内在秩分析来识别和减少模型阶段的冗余,用更有效的结构代替复杂的块。

精度驱动的模型设计:

  • 通过增加深度阶段的接受场来增强模型能力,有选择地使用大核深度卷积来避免浅阶段的开销。
  • 通过PSA划分特征并将自注意力应用于部分特征,结合有效的自注意力,降低计算复杂性和内存使用,同时增强全局表示学习。

实验结果

与基线YOLOv8模型相比,YOLOv10在AP方面表现出显著的改善,N型增加1.2%,S型增加1.4%,M型增加0.5%,L型增加0.3%,X型增加0.5%。此外,YOLOv10显著降低了延迟,从37%到70%不等。

部署和使用示例

我们将从安装所需的库开始。

 # Clone ultralytics repogit clone https://github.com/ultralytics/ultralytics# cd to local directorycd ultralytics# Install dependenciespip install -r requirements.txt

1、使用YOLOv10进行目标检测

目标检测是计算机视觉中的一项基本任务。YOLOv10通过在推理期间消除非最大抑制(NMS)的需要来增强这一点,从而降低延迟并提高性能。

我们先载入模型和需要处理的视频

 importcv2importnumpyasnpfromultralyticsimportYOLO# Load YOLOv10 modelmodel=YOLO('yolov10.pt')# Path to the video filevideo_path='path/to/your/deephub.mp4'cap=cv2.VideoCapture(video_path)

然后就可以处理视频帧

 whilecap.isOpened():ret, frame=cap.read()ifnotret:break# Perform object detectionresults=model(frame)# Draw bounding boxesforresultinresults:boxes=result['boxes']forboxinboxes:x1, y1, x2, y2=box['coords']label=box['label']confidence=box['confidence']cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)cv2.putText(frame, f'{label}{confidence:.2f}', (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# Display the framecv2.imshow('YOLOv10 Object Detection', frame)ifcv2.waitKey(1) &0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()

结果如下:

2、使用YOLOv10进行区域计数

区域计数可以对指定区域内的对象进行计数,这个例子演示了如何使用YOLOv10对定义区域中的对象进行计数。

定义区域和设置模型

 fromshapely.geometryimportPolygon, Point# Define counting regionscounting_regions= [{"name": "Region 1","polygon": Polygon([(50, 80), (250, 20), (450, 80), (400, 350), (100, 350)]),"counts": 0,"color": (255, 0, 0)},{"name": "Region 2","polygon": Polygon([(200, 250), (440, 250), (440, 550), (200, 550)]),"counts": 0,"color": (0, 255, 0)},]model=YOLO('yolov10.pt')

处理视频和计数区域中的对象

 cap=cv2.VideoCapture('path/to/your/deephub.mp4')whilecap.isOpened():ret, frame=cap.read()ifnotret:break# Perform object detectionresults=model(frame)# Draw regionsforregionincounting_regions:points=np.array(region["polygon"].exterior.coords, dtype=np.int32)cv2.polylines(frame, [points], isClosed=True, color=region["color"], thickness=2)region["counts"] =0  # Reset counts for each frame# Count objects in regionsforresultinresults:boxes=result['boxes']forboxinboxes:x1, y1, x2, y2=box['coords']center=Point((x1+x2) /2, (y1+y2) /2)forregionincounting_regions:ifregion["polygon"].contains(center):region["counts"] +=1# Display countsforregionincounting_regions:text=f'{region["name"]}: {region["counts"]}'cv2.putText(frame, text, (int(region["polygon"].centroid.x), int(region["polygon"].centroid.y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, region["color"], 2)# Display the framecv2.imshow('YOLOv10 Region Counting', frame)ifcv2.waitKey(1) &0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()

微调训练

在使用模型时最主要的还是要在我们自己的数据集上进行微调,所以我们最后再介绍一下如何使用自己的数据进行微调。

我将使用一个预先准备好的检测x射线图像中的危险物品的数据集来作为演示。

我们只用roboflow直接下载yolov8格式的数据集

 !pip install -q roboflowfrom roboflow import Roboflowrf = Roboflow(api_key="your-api-key")project = rf.workspace("vladutc").project("x-ray-baggage")version = project.version(3)dataset = version.download("yolov8")

指定参数和文件路径,然后开始模型训练。

 !yolo task=detect mode=train epochs=25 batch=32 plots=True \model='/content/-q/yolov10n.pt' \data='/content/X-Ray-Baggage-3/data.yaml'

这里需要一个data.yaml文件,他的格式如下:

 names:- Gun- Knife- Pliers- Scissors- Wrenchnc: 5roboflow:license: CC BY 4.0project: x-ray-baggageurl: https://universe.roboflow.com/vladutc/x-ray-baggage/dataset/3version: 3workspace: vladutctest: /content/X-Ray-Baggage-3/test/imagestrain: /content/X-Ray-Baggage-3/train/imagesval: /content/X-Ray-Baggage-3/valid/images

训练完成后我们可以看看结果:

 Image(filename='/content/runs/detect/train/results.png', width=1000)

最后可以测试数据并在网格中显示结果。

 fromultralyticsimportYOLOv10importglobimportmatplotlib.pyplotaspltimportmatplotlib.imageasmpimgmodel_path='/content/runs/detect/train/weights/best.pt'model=YOLOv10(model_path)results=model(source='/content/X-Ray-Baggage-3/test/images', conf=0.25,save=True)images=glob.glob('/content/runs/detect/predict/*.jpg')images_to_display=images[:10]fig, axes=plt.subplots(2, 5, figsize=(20, 10))fori, axinenumerate(axes.flat):ifi<len(images_to_display):img=mpimg.imread(images_to_display[i])ax.imshow(img)ax.axis('off')  else:ax.axis('off')  plt.tight_layout()plt.show()

总结

YOLOv10的改进在性能和延迟方面均达到了最先进的水平,充分展示了其优越性。并且继承了Ultralytics的传统,无论是部署还是自定义训练和微调都十分的友好,有兴趣的可以现在开始研究了。

https://avoid.overfit.cn/post/ef635b20337c435abde2ac2d1577d665


http://www.ppmy.cn/server/46688.html

相关文章

Spring系列-SpringMvc父子容器启动原理解析

1、Spring整合SpringMVC 特性&#xff1a; 说到Spring整合SpringMVC唯一的体现就是父子容器&#xff1a; 通常我们会设置父容器&#xff08;Spring&#xff09;管理Service、Dao层的Bean, 子容器(SpringMVC)管理Controller的Bean .子容器可以访问父容器的Bean, 父容器无法访…

linux进程加载和启动过程分析

我们的源代码通过预处理,编译,汇编,链接后形成可执行文件,那么当我们在终端敲下指令$ ./a.out argv1 argv2 后,操作系统是怎么将我们的可执行文件加载并运行的呢? 首先知道,计算机的操作系统的启动程序是写死在硬件上的,每次计算机上电时,都将自动加载启动程序,之后…

6.3 Go 结构体(Struct)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

使用numpy手写一个神经网络

本文主要包含以下内容&#xff1a; 推导神经网络的误差反向传播过程使用numpy编写简单的神经网络&#xff0c;并使用iris数据集和california_housing数据集分别进行分类和回归任务&#xff0c;最终将训练过程可视化。 1. BP算法的推导过程 1.1 导入 前向传播和反向传播的总体…

深入理解Java多线程与线程池:提升程序性能的利器

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一、实现多线程 1.1. 继承Thread类 1.2. 实现Runnab…

mysql事务详解

事务是用来解决特定场景的问题&#xff0c;在mysql中有些操作需要借助多个sql才能够解决&#xff0c;假设我们有个账户余额表&#xff0c;我们需要进行转账&#xff0c;转账无非就是加减操作&#xff0c;但是在转账过程中必然会出现中间结果&#xff0c;如果在转账未完全成功之…

代码随想录算法跟练 | Day7 | 哈希表Part2

个人博客主页&#xff1a;http://myblog.nxx.nx.cn 代码GitHub地址&#xff1a;https://github.com/nx-xn2002/Data_Structure.git Day7 454. 四数相加 II 题目链接&#xff1a; https://leetcode.cn/problems/4sum-ii/ 题目描述&#xff1a; 给你四个整数数组 nums1、nums…

【算法】在?复习一下快速排序?

基本概念 快速排序是一种基于交换的排序算法&#xff0c;该算法利用了分治的思想。 整个算法分为若干轮次进行。在当前轮次中&#xff0c;对于选定的数组范围[left, right]&#xff0c;首先选取一个标志元素pivot&#xff0c;将所有小于pivot的元素移至其左侧&#xff0c;大于…