Yolov10笔记

一、前言

        清华大学团队设计的Yolov10.

        在这项工作中,我们主要从后处理和模型结构两方面进一步优化YOLO系列模型的性能和延迟平衡。我们首先为YOLO引入了端到端训练的一致双重分配,这在大大降低推理延迟的情况下保证了性能。此外,我们针对YOLO的各组件使用效率和精度驱动的模型设计策略。这大大减少了计算冗余,并增强了模型能力。

        最终,我们获得了一个新的实时的端到端目标检测模型,即YOLOv10。广泛的实验表明,YOLOv10在各种模型规模上达到了最先进的性能和效率平衡。例如,YOLOv10-S在COCO上的类似AP下比RT-DETR-R18快1.8倍,同时有2.8倍更少的参数和FLOPs。与YOLOv9-C相比,YOLOv10-B在相同性能下延迟减少了46%,参数减少了25%。

二、创新点

1、一致双重匹配

        与一对多匹配不同,一对一匹配只为每个物体分配一个预测,避免了NMS后处理。然而,这会带来较弱的监督信息,导致次优的准确性和收敛速度[19]。另一方面,一对多策略则可以引入更多的正样本和监督信号,可有效弥补一对一匹配的不足[23]。因此,我们为YOLOs引入了双重标签匹配,如下图,以充分结合两种策略的优点。

2、效率精度驱动的模型设计

效率驱动的模型设计

(1)、轻量级分类头

(2)、空间-通道解耦下采样

(3)、秩引导的块设计

精度驱动的模型设计

(1)、大核卷积

(2)、部分自注意力(PSA)

三、代码解读

1、网络结构图

以yolov10s模型为例。

# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]s: [0.33, 0.50, 1024]backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, SCDown, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, SCDown, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2fCIB, [1024, True, True]]- [-1, 1, SPPF, [1024, 5]] # 9- [-1, 1, PSA, [1024]] # 10# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 13- [-1, 1, nn.Upsample, [None, 2, "nearest"]]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f, [256]] # 16 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 13], 1, Concat, [1]] # cat head P4- [-1, 3, C2f, [512]] # 19 (P4/16-medium)- [-1, 1, SCDown, [512, 3, 2]]- [[-1, 10], 1, Concat, [1]] # cat head P5- [-1, 3, C2fCIB, [1024, True, True]] # 22 (P5/32-large)- [[16, 19, 22], 1, v10Detect, [nc]] # Detect(P3, P4, P5)

由于完整的模型图太长,这里只截取头部处理的模型图。

2、代码分析

class v10Detect(Detect):max_det = -1def __init__(self, nc=80, ch=()):super().__init__(nc, ch)c3 = max(ch[0], min(self.nc, 100))  # channelsself.cv3 = nn.ModuleList(nn.Sequential(nn.Sequential(Conv(x, x, 3, g=x), Conv(x, c3, 1)), \nn.Sequential(Conv(c3, c3, 3, g=c3), Conv(c3, c3, 1)), \nn.Conv2d(c3, self.nc, 1)) for i, x in enumerate(ch))self.one2one_cv2 = copy.deepcopy(self.cv2)self.one2one_cv3 = copy.deepcopy(self.cv3)def forward(self, x):one2one = self.forward_feat([xi.detach() for xi in x], self.one2one_cv2, self.one2one_cv3)if not self.export:one2many = super().forward(x)if not self.training:one2one = self.inference(one2one)if not self.export:return {"one2many": one2many, "one2one": one2one}else:assert(self.max_det != -1)boxes, scores, labels = ops.v10postprocess(one2one.permute(0, 2, 1), self.max_det, self.nc)return torch.cat([boxes, scores.unsqueeze(-1), labels.unsqueeze(-1)], dim=-1)else:return {"one2many": one2many, "one2one": one2one}
def v10postprocess(preds, max_det, nc=80):# preds: shape[1,8400,84]assert(4 + nc == preds.shape[-1])boxes, scores = preds.split([4, nc], dim=-1)  # [1,8400,4]  [1,8400,80]max_scores = scores.amax(dim=-1)  # [1,8400]max_scores, index = torch.topk(max_scores, max_det, axis=-1)  # [1,300]index = index.unsqueeze(-1)  # [1,300,1]boxes = torch.gather(boxes, dim=1, index=index.repeat(1, 1, boxes.shape[-1]))     # [1,300,4]scores = torch.gather(scores, dim=1, index=index.repeat(1, 1, scores.shape[-1]))  # [1,300,80]scores, index = torch.topk(scores.flatten(1), max_det, axis=-1)  # 1*300labels = index % nc  # 1*300index = index // nc  # 1*300boxes = boxes.gather(dim=1, index=index.unsqueeze(-1).repeat(1, 1, boxes.shape[-1]))  # 1*300*4return boxes, scores, labels
    def inference(self, x):# Inference pathshape = x[0].shape  # BCHWx_cat = torch.cat([xi.view(shape[0], self.no, -1) for xi in x], 2)if self.dynamic or self.shape != shape:self.anchors, self.strides = (x.transpose(0, 1) for x in make_anchors(x, self.stride, 0.5))self.shape = shapeif self.export and self.format in ("saved_model", "pb", "tflite", "edgetpu", "tfjs"):  # avoid TF FlexSplitV opsbox = x_cat[:, : self.reg_max * 4]cls = x_cat[:, self.reg_max * 4 :]else:box, cls = x_cat.split((self.reg_max * 4, self.nc), 1)if self.export and self.format in ("tflite", "edgetpu"):# Precompute normalization factor to increase numerical stability# See https://github.com/ultralytics/ultralytics/issues/7371grid_h = shape[2]grid_w = shape[3]grid_size = torch.tensor([grid_w, grid_h, grid_w, grid_h], device=box.device).reshape(1, 4, 1)norm = self.strides / (self.stride[0] * grid_size)dbox = self.decode_bboxes(self.dfl(box) * norm, self.anchors.unsqueeze(0) * norm[:, :2])else:dbox = self.decode_bboxes(self.dfl(box), self.anchors.unsqueeze(0)) * self.stridesy = torch.cat((dbox, cls.sigmoid()), 1)return y if self.export else (y, x)

记录各个模块返回参数的shape

*** one2one = self.forward_feat([xi.detach() for xi in x], self.one2one_cv2, self.one2one_cv3)  ===>
1*128*80*80 ==> 1*64*80*80 + 1*80*80*80 = 1*144*80*80
1*256*40*40 ==> 1*64*40*40 + 1*80*40*40 = 1*144*40*40
1*512*20*20 ==> 1*64*20*20 + 1*80*20*20 = 1*144*20*20*** one2one = self.inference(one2one)  ===>  
1*144*6400 + 1*144*1600 + 1*144*400 = 1*144*8400
box: 1*64*8400  ==>  dbox: 1*4*8400
cls: 1*80*8400
output: 1*4*8400 + 1*80*8400 = 1*84*8400*** boxes, scores, labels = ops.v10postprocess(one2one.permute(0, 2, 1), 300, 80)
1*84*8400  ==> boxes:1*300*4   scores:1*300   labels:1*300*** torch.cat([boxes, scores.unsqueeze(-1), labels.unsqueeze(-1)], dim=-1) ===>
boxes:1*300*4   scores:1*300   labels:1*300  ==>  1*300*6

四、参考

1、博客:YOLOv10:实时的端到端目标检测 (qq.com)

2、论文:[2405.14458] YOLOv10: Real-Time End-to-End Object Detection (arxiv.org)

3、code:THU-MIG/yolov10: YOLOv10: Real-Time End-to-End Object Detection (github.com)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

养生与健康|一起跟随林曦老师养个元气满满

暄桐是一间传统美学教育教室,创办于2011年,林曦是创办人和授课老师,教授以书法为主的传统文化和技艺,皆在以书法为起点,亲近中国传统之美,以实践和所得,滋养当下生活。    在暄桐教室的六阶…

XCP协议系列介绍02-基于ASAP2 Tool-Set生成A2l介绍

本文框架 1. 前言2. ASAP2 Tool-Set系统介绍2.1 ASAP2 Creator介绍2.2 ASAP2 Updater介绍2.3 ASAP2 Merger介绍2.4 ASAP2 Comparer及Checker介绍2.5 ASAP2 Modifier介绍2.6 ASAP2 Studio介绍 3. 项目实操说明3.1 项目实操建议3.2 工具下载地址及使用 1. 前言 在XCP观测及标定整…

计算机网络期末复习(1)计算机网络在信息时代对的作用 计算机网络的定义和分类 三种交换方法

计算机网络在信息时代扮演着至关重要的角色,它极大地改变了我们生活、工作和学习的方式。 计算机网络在信息时代的作用 信息共享与传播:计算机网络使全球范围内的信息快速共享成为可能,无论是新闻、学术研究还是娱乐内容,都可以…

【C++】类和对象——构造和析构函数

目录 前言类的六个默认构造函数构造函数1.构造函数的概念2.构造函数的特性 初始化列表1.构造函数整体赋值2.初始化列表 析构函数1.析构函数的概念2.析构函数的特性 前言 类和对象相关博客:【C】类和对象   我们前面一个内容已经讲了关于类好对象的初步的一些知识&…

【MyBatis】零基础从入门到进阶(源码级深入详解)

1 MyBatis概述 1.1 框架 ● 在⽂献中看到的framework被翻译为框架 ● Java常⽤框架: ○ SSM三⼤框架:Spring SpringMVC MyBatis ○ SpringBoot ○ SpringCloud ○ 等。。 ● 框架其实就是对通用代码的封装,提前写好了⼀堆通用…

数据库系统概论(个人笔记)(第三部分)

数据库系统概论(个人笔记) 文章目录 数据库系统概论(个人笔记)3、SQL介绍3.1 SQL查询语言概述3.2 SQL数据定义3.3 SQL查询的基本查询结构3.4 其他基本操作3.5 设置操作3.6 空值3.7 聚合函数3.8 嵌套子查询3.9 数据库的修改 3、SQL…

看车牌识别API如何应用到实际

车牌识别技术作为一种先进的识别系统,在现代城市的交通管理和安全领域扮演着日益重要的角色。本文将深入探讨车牌识别API 接口在智能停车、安全监控以及数据分析等方面的具体应用。通过详细研究这些应用场景,我们可以更好地理解这项技术如何提升交通流畅…

Laravel和ThinkPHP框架比较

一、开发体验与易用性比较 1. 代码可读性: - Laravel以其优雅的语法和良好的代码结构著称,使得代码更加易读易懂。 - 相比之下,ThinkPHP的代码可读性较为一般,在一些复杂业务场景下,可能会稍显混乱。 让您能够一站式…

WordPress中借助Table of Contents Plus+Widget Options插件,实现仅在文章侧边栏显示文章目录的功能

本文转自博主的个人博客:https://blog.zhumengmeng.work,欢迎大家前往查看。 原文链接:点我访问 序言:今天心血来潮,写了一篇文章,忽然发现自己的文章极少有目录,这对于长文章的阅读来说是十分不利的&#…

Day 10:100322. 删除星号以后字典序最小的字符串

Leetcode 100322. 删除星号以后字典序最小的字符串 给你一个字符串 s 。它可能包含任意数量的 ‘’ 字符。你的任务是删除所有的 ’ 字符。 当字符串还存在至少一个 ‘*’ 字符时,你可以执行以下操作: 删除最左边的 ‘*’ 字符,同时删除该星号…

STM32(十):SPI (标准库函数)

前言 上一篇文章已经介绍了如何用STM32单片机中USART通信协议来串口通信,并向XCOM串口助手发送信息。这篇文章我们来介绍一下如何用STM32单片机中SPI接口来实现LED的闪亮并玩转WS2812B灯带。 一、实验原理 串行通信之前的博客里有所介绍,可以查看以下…

python中利用cartopy库绘制SST图像

1. Cartopy简介 Cartopy 是一个开源的 Python 库,用于绘制地图和地理数据分析。它结合了 matplotlib 的绘图功能和 shapely、pyproj 等库的地理空间数据处理能力,为用户提供了在地图上可视化数据的强大工具。 以下是 Cartopy 的一些主要特点和功能&#…

2、浮动的用法特点,解决父元素高度塌陷解决

一、浮动 用法:浮动就是使用float样式,使元素脱离文档流。属性值有三个:none默认left right 特点: 常用于文字环绕图片浮动的元素脱离文档流影响其他元素排列造成父元素高度塌陷 1、一旦元素设置了浮动,元素就会脱离…

Python知识点14---被规定的资源

提前说一点:如果你是专注于Python开发,那么本系列知识点只是带你入个门再详细的开发点就要去看其他资料了,而如果你和作者一样只是操作其他技术的Python API那就足够了。 在Python中被规定的东西不止有常识中的那些关键字、构造器等编程语言…

汇编原理 | 二进制、跳转指令、算数运算、

一.二进制 two complement reprentation(补码) 二进制的运算: 6的二进制 0110 -6的二进制 如何表示? 四个bit的第一个bit表示符号:1负0正 -6表示为1010 解释: 0 0000 1 0001 -1 1111(由 …

自然语言处理(NLP)—— 置信度(Confidence)

1. 置信度(Confidence)的概念 置信度(Confidence)在机器学习和统计中通常指一个模型对其做出的预测是正确的确信程度。在分类任务中,置信度通常由模型赋予特定类别的概率值来表示。例如,在文本分类或实体识…

dm8 什么时候视图中统计的内存会超过OS

v$bufferpool和v$mem_pool视图记录着DMSERVER各组件的内存占用量。理论上跟OS看到的保持一致。但实际大多数场景下,OS中看到的数据远大于视图中的统计。这里面可能有内存泄漏的原因。不过也有的时候视图中的统计数据超过OS。下面就是这种情况: 上图中红线…

Vue插槽与作用域插槽

title: Vue插槽与作用域插槽 date: 2024/6/1 下午9:07:52 updated: 2024/6/1 下午9:07:52 categories: 前端开发 tags:VueSlotScopeSlot组件通信Vue2/3插槽作用域API动态插槽插槽优化 第1章:插槽的概念与原理 插槽的定义 在Vue.js中,插槽(…

【OpenHarmony】TypeScript 语法 ④ ( 函数 | TypeScript 具名函数和匿名函数 | 可选参数 | 剩余参数 | 箭头参数 )

文章目录 一、TypeScript 函数1、TypeScript 具名函数和匿名函数2、TypeScript 函数 与 JavaScript 函数对比3、TypeScript 函数 可选参数4、TypeScript 函数 剩余参数5、TypeScript 箭头函数 参考文档 : <HarmonyOS第一课>ArkTS开发语言介绍 一、TypeScript 函数 1、Typ…

【Hive SQL 每日一题】统计指定范围内的有效下单用户

文章目录 测试数据需求说明需求实现 前言&#xff1a;本题制作参考牛客网进阶题目 —— SQL128 未完成试卷数大于1的有效用户 测试数据 -- 创建用户表 DROP TABLE IF EXISTS users; CREATE TABLE users (user_id INT,name STRING,age INT,gender STRING,register_date STRING…