opencv dnn模块 示例(22) 目标检测 object_detection 之 yolov7

在YOLOv6 初版出来不久,YOLOv7就立马横空出世了。与YOLOv5、YOLOv6不同,YOLOv7是由YOLOv4团队的原班人马提出的(官方出品)。从论文的表上来看,目前YOLOv7无论是在实时性还是准确率上都已经超过了当时已知的所有目标检测算法。并且它在COCO数据集上达到了56.8%的AP。

文章目录

  • 1、YOLOv7介绍
    • 1.1、创新点
    • 1.2、详细设计
      • 1.2.1、聚合网络设计
      • 1.2.2、卷积重参化
      • 1.2.3、基于concatenate的模型缩放
      • 1.2.4、标签分配
      • 1.2.5、训练时的其它策略
    • 1.3、实验结果
  • 2、测试
    • 2.1、官方脚本测试
    • 2.2、opencv dnn测试
    • 2.3、测试统计
  • 3、Opencv dnn 批量推理

1、YOLOv7介绍

1.1、创新点

模型结构重参化和动态标签分配已经成为了目标检测领域中的主要优化方向。针对于结构重参化,作者
通过分析梯度的传播路径来为网络中的不同层进行结构重参化优化,并且提出了不同规划的模型结构重参化。在动态标签分配上,因为模型有多个输出层,所以在训练时就难以为不同的分支分配更好地动态目标。所以作者提出了一个新的动态标签分配办法:coarse-to-fine,即由粗到细引导标签分配的策略。

还提出了扩展和复合缩放的方式,通过这种方式可以更高效利用参数量和计算量。这样不仅可以减少大量参数,还可以提高推理速度以及检测精度。

并且设计了几个可以训练的bag-of-freebies。这样使得模型在不更改本身结构时,大大提高检测精度。

1.2、详细设计

1.2.1、聚合网络设计

为了增强网络的实时性检测,YOLOv7里使使用VoVNet的变体CSPVOVNet。不仅考虑模型的参数量、计算量、内存访问次数、输入输出的通道比、element-wise操作等方面分析参数的数量、计算量和计算密度,还分析了梯度的在模型中流动路径,通过这个来使得不同层的权重能够学习到更加多样化的特征。
在这里插入图片描述
还提出了基于ELAN的Extended-ELAN,也就是E-ELAN方法。通过高效长程注意力网络来控制梯度的最短最长路径,让更深的网络可以更加高效地学习和收敛。作者提出的E-ELAN使用expand、shuffle、merge cardinality来实现在不破坏原有梯度路径的情况下,提升网络的学习能力。无论梯度路径长度和大规模ELAN中计算块的堆叠数量如何,网络都能够达到稳定状态,但是倘若继续这样一直地堆叠这一些计算块下去,反而可能会破坏这种稳定的状态,从而导致降低参数的利用率。
在这里插入图片描述
在结构方面,E-ELAN只改变块本身的架构,对于过渡层的架构则没有改变,这边的调整策略是使用组卷积来扩展计算块的通道和基数,将对计算层的所有计算块应用相同的组参数和通道数,然后,对于每个计算块输出的特征图会根据设置的组参数g被随即打乱成g个组,之后再将它们连接在一起。注意到这个时候,每组特征图的通道数和原来架构中的通道数是一样的,最后,添加g组的特征图来执行合并基数。E-ELAN除了保持原有的ELAN设计架构外,还可以帮助其它组的计算块学习到更加多样化的特征。

1.2.2、卷积重参化

重参化技术是模型在推理时将多个模块合并成一个模块的方法,其实就是一种集成技术。常见的重参化技术有:

  • 一种是用不同的训练数据训练多个相同的模型,然后对多个训练模型的权重进行平均。
  • 一种是对不同迭代次数下模型权重进行加权平均。

然RepConv在VGG上取得了很不错的效果,但将它直接应用于ResNet和DenseNet或其他骨干网络时,它的精度却下降得很厉害。作者就是用梯度传播路径的方法来分析,因为RepConv结合了3×3卷积,1×1卷积,和在一个卷积层中的identity连接,可是这个identity破坏力ResNet的残差连接以及DenseNet的跨层连接,为不同的特征图提供了更多的梯度多样性。

因此,作者认为,在同时使用重参化卷积和残差连接或者跨层连接时,不应该存在identity连接,而且作者还分析重参数化的卷积应该如何与不同的网络结构相结合以及设计了不同的重参数化的卷积。
在这里插入图片描述

1.2.3、基于concatenate的模型缩放

模型缩放是调整模型的大小来生成不同尺度的模型,用于满足不同场景下的推理需求。如今的网络中,主要的缩放因子有input size、depth、width、stage,通过控制这些参数,模型的参数量、计算量、推理速度和精度都有一个很好的平衡。同时,网络架构搜索NAS技术也经常使用到。

作者还发现使用concatenate模型时,不能单独地分析缩放因子的影响,还必须结合通道数的变化一起分析,因为在这过程中会导致输入通道和输出通道的比例会发生变化,从而导致模型的硬件使用率降低。还提出了一种复合缩放方法,这样不仅可以保持模型在初始设计时的特性还可以保持性能最佳时的结构。

在这里插入图片描述

1.2.4、标签分配

但近年来,需要研究者会利用网络的推理结果来结合GT,去生成一些软标签,如IOU。在YOLOv7中,有辅助头也有引导头,在训练时,它们二者都需要得到监督。因此,需要考虑如何为辅助头和引导头进行标签分配。因此在这里,作者提出了一种新的标签分配方法,是以引导头为主,通过引导头的推理来指引辅助头和自身的学习。
在这里插入图片描述
使用引导头的推理结果作为指导,生成从粗到细的层次标签,分别用于辅助头和引导头的学习。为了使那些超粗的正网格影响更小,会在解码器中设置限制,来使超粗的正网格无法完美地产生软标签。通过以上的机制,允许在学习过程中动态调整细标签和粗标签的重要性,使细标签的始终优于粗标签。
在这里插入图片描述

1.2.5、训练时的其它策略

  • Batch Normalization:
    即将Batch Normalization层直接连接到卷积层中。这样可以在推理时将Batch Normalization的均值和方差直接融合到卷积层的偏差和权重中。

  • YOLOR中结合隐性知识和卷积特征图的加法和乘法方法
    在YOLOR中,它认为隐式知识可以在推理时通过预计算步骤被简化为向量。然后再把这个向量和前一个或后一个卷积层的偏差和权重融合在一起。

  • EMA:
    EMA是一种在mean teacher中使用的技术,在系统中使用EMA模型纯粹作为最终的推理模型。EMA可以用来估计变量的局部均值,使得变量的更新与一段时间内的历史取值有关,这里可以取得平滑的作用。如果取n步的平均,就能使得模型更加得鲁棒。

1.3、实验结果

作者为边缘GPU、普通GPU、高性能云GPU三种不同场景设计了三种模型,分别是YOLOv7-Tiny、YOLOv7和YOLOv7-W6。并且通过论文中的复合缩放方法,对整个模型的深度、宽度进行缩放,得到了YOLOv7-X、YOLOv7-E6和YOLOv7-D6。以及在YOLOv7-E6基础上使用了E-ELAN技术来获得YOLOv7-E6E。
在这里插入图片描述

可以看到以下和其他目标检测器的速度、精度对比结果。
在这里插入图片描述

2、测试

以模型 YOLOv7.pt 为例进行测试 下载链接

2.1、官方脚本测试

使用默认脚本参数,设置--device 0使用GPU加速对目录中的所有图片进行推理。代码中当使用GPU加速时,提前进行了warmup。

(yolo_pytorch) E:\DeepLearning\yolov7>python detect.py --weights yolov7.pt --source inference/images --device 0
Namespace(weights=['yolov7.pt'], source='inference/images', img_size=640, conf_thres=0.25, iou_thres=0.45, device='0', view_img=False, save_txt=False, save_conf=False, nosave=False, classes=None, agnostic_nms=False, augment=False, update=False, project='runs/detect', name='exp', exist_ok=False, no_trace=False)
YOLOR  v0.1-122-g3b41c2c torch 1.13.1+cu117 CUDA:0 (NVIDIA GeForce GTX 1080 Ti, 11263.75MB)Fusing layers...
RepConv.fuse_repvgg_block
RepConv.fuse_repvgg_block
RepConv.fuse_repvgg_block
Model Summary: 306 layers, 36905341 parameters, 6652669 gradientsConvert model to Traced-model...traced_script_module saved!model is traced!D:\Python\anaconda3\envs\yolo_pytorch\lib\site-packages\torch\functional.py:504: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at C:\actions-runner\_work\pytorch\pytorch\builder\windows\pytorch\aten\src\ATen\native\TensorShape.cpp:3191.)return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]
4 persons, 1 bus, 1 tie, Done. (28.0ms) Inference, (4.0ms) NMSThe image with the result is saved in: runs\detect\exp19\bus.jpg
1 bicycle, 1 car, 1 truck, 1 dog, Done. (22.0ms) Inference, (1.0ms) NMSThe image with the result is saved in: runs\detect\exp19\dog.jpg
5 horses, Done. (20.0ms) Inference, (1.0ms) NMSThe image with the result is saved in: runs\detect\exp19\horses.jpg
2 persons, 1 tie, 1 cake, Done. (21.0ms) Inference, (2.0ms) NMSThe image with the result is saved in: runs\detect\exp19\image1.jpg
2 persons, 1 sports ball, Done. (19.0ms) Inference, (1.0ms) NMSThe image with the result is saved in: runs\detect\exp19\image2.jpg
1 dog, 1 horse, Done. (18.0ms) Inference, (2.0ms) NMSThe image with the result is saved in: runs\detect\exp19\image3.jpg
3 persons, 1 tie, Done. (17.0ms) Inference, (1.0ms) NMSThe image with the result is saved in: runs\detect\exp19\zidane.jpg
Done. (0.759s)

对于图片bus.jpg 的推理耗时为28ms。切换为CPU时,耗时增大到 770ms。

2.2、opencv dnn测试

导出 onnx 模型:

  • 类似yolov4,三个尺度输出
    三个尺度输出分别为 [1,3,80,80,85]、 [1,3,40,40,85]、 [1,3,20,20,85]
    python export.py --weights yolov7.pt --simplify --img-size 640 640 --max-wh 640
    
  • grid导出,三个尺度输出进行合并
    合并输出结果 [38080 + 34040 + 32020, 85] = [25200, 85]
    python export.py --weights yolov7.pt --grid --simplify --img-size 640 640 --max-wh 640
    
  • end2end
    根据指定参数,添加NMS输出的结果
    python export.py --weights yolov7.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640
    

使用Netron上看上述三个脚本生成的onnx文件模型结构

****
这里为了方便,使用 --grid 导出的模型,直接复用前面 yolov5、yolor、yolov6的代码,识别置信度比yolov6低一些。
在这里插入图片描述

另外,官方在yolov5he yolov6的基础上,提供了 anchor free 的模型文件 yolov7-u6.pt。

2.3、测试统计

python(CPU):797ms
python(GPU):28ms

opencv dnn(CPU):890ms
opencv dnn(GPU):28ms

后面测试包含 预处理+推理+后处理
openvino(CPU):409ms
onnxruntime(GPU):31ms
TensorRT:21ms

end2end模型的测试:
onnxruntime(CPU):460ms
onnxruntime(GPU):32ms
TensorRT:14ms

3、Opencv dnn 批量推理

当使用如下代码进行简单的批量推理时

auto inputImgs = std::vector<cv::Mat>{modelInput, modelInput, modelInput};
blobFromImages(inputImgs, blob, scale, cv::Size2f(inpWidth, inpHeight), mean, swapRB, false);
net.setInput(blob);
net.forward(outs, outNames);

报错如下:

[ERROR:0@4.559] global net_impl.cpp:1172 cv::dnn::dnn4_v20230620::Net::Impl::getLayerShapesRecursively     input[0] = [ 3 1 3 9 80 80 ]
[ERROR:0@4.560] global net_impl.cpp:1182 cv::dnn::dnn4_v20230620::Net::Impl::getLayerShapesRecursively Exception message: OpenCV(4.8.0) D:\opencv\opencv4.8.0\sources\modules\dnn\src\layers\permute_layer.cpp:162: error: (-215:Assertion failed) (int)_numAxes == inputs[0].size() in function 'cv::dnn::PermuteLayerImpl::getMemoryShapes'

yolov7要是实现批量推理,需要增加参数 --dynamic-batch,完成命令为

python export.py --weights runs\train\yolov7-custom3\weights\best.pt --grid --simplify --img-size 640 640 --max-wh 640 --dynamic-batch

这里使用训练模型的类别数为4,因此常规一张图一推理的维度为 [1,25200, 9],按照常识,输入为[1x3,640,640]时,输出应该为[1x3,25200,9],但是实际为 [1, 25200x3, 9] = [1, 75600, 9],查看 转换都后onnx模型,
在这里插入图片描述

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

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

相关文章

Java 之 IO/NIO/OKIO

BIO blocking io AIO Asynchronous IO 从内存读取到写入--输出 从外部到内存 -- 输入 OutputStream //文件不存在则自动创建 try {OutputStream outputStream new FileOutputStream("text.txt");outputStream.write(a);outputStream.write(b);} catch (IOExcep…

Python使用Numba装饰器进行加速

Python使用Numba装饰器进行加速 前言前提条件相关介绍实验环境Numba装饰器进行加速未加速的代码输出结果 numba.jit加速的代码输出结果 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#xff0c;可点击进入Python日常小操作专栏、Ope…

已解决:Rust Error: the trait bound is not satisfied 问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…

python的format函数的用法及实例

目录 1.format函数的语法及用法 &#xff08;1&#xff09;语法&#xff1a;{}.format() &#xff08;2&#xff09;用法&#xff1a;用于格式化字符串。可以接受无限个参数&#xff0c;可以指定顺序。返回结果为字符串。 2.实例 &#xff08;1&#xff09;不设置位置&…

煤矿企业如何选择合适的设备健康管理系统

在煤矿开采的过程中&#xff0c;机电设备发挥着重要的作用。但大量的机电设备的使用也给煤矿企业设备管理提出了一定的要求。随着工业领域数字化的深入应用&#xff0c;煤矿机电设备的自动化、智能化管理已经成为煤矿企业发展的重要手段。保障机电设备的正常运行&#xff0c;减…

Spring Boot框架配置WebSocket【一遍过,不过你评论骂我】

【找了无数的文档资料总结】 【不停的找文档试】 【每一次都显示连接不上】 【终于成了……】 当使用Spring Boot框架配置WebSocket时, 通常会使用@ServerEndpoint注解来标识WebSocket端点, 并通过ServerEndpointExporter来注册这些端点。以下是配置WebSocket的步骤: 步骤…

2023.11.10联测总结

T 1 T1 T1求的是有多少个区间的异或和是 k k k的因子&#xff0c; n , k ≤ 1 0 5 n,k \leq 10^5 n,k≤105。 这道题用前缀和维护一下&#xff0c;暴力枚举所有区间就有 80 80 80分。 有一瞬间想过枚举因数&#xff0c;但是脑抽以为要 O ( n ) \mathcal O(n) O(n)枚举&#x…

传输层中的TCP和UPD协议

一)应用层协议简介:根据需求明确要传输的信息&#xff0c;明确要传输的数据格式&#xff1b; 应用层协议:这个协议&#xff0c;实际上是和程序员打交道最多的协议了 1)其它四层都是操作系统&#xff0c;驱动&#xff0c;硬件实现好了的&#xff0c;咱们是不需要管 2)应用层:当我…

红海云签约和兆服饰,科技引领服饰行业人力资源数字化转型

和兆服饰从事多品牌多品类经营管理&#xff0c;旗下拥有POLOSPORT、POLOKIDS、CARTELO等国际品牌。作为一个主打POLO文化的服饰品牌&#xff0c;诞生于美国的POLOSPORT拥有现代感的产品设计、系列化的产品搭配、全方位的服务&#xff0c;是最具美国马球精神的休闲时尚服饰品牌之…

基于JavaWeb+SSM+Vue微信小程序校园兼职任务平台系统的设计和实现

基于JavaWebSSMVue微信小程序校园兼职任务平台系统的设计和实现 源码传送入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码传送入口 前言 随着社会的发展和全球疫情的冲击&#xff0c;大学生的就业形势越来越严峻。越…

WordPress Modown 6.2付费下载资源/付费查看内容 wp主题模板+erphpdown11.7

模板简介&#xff1a; 自适应响应式设计&#xff0c;兼容主流浏览器 网格样式与瀑布流样式任意切换 内置SEO优化 自带与主题UI完美兼容搭配的erphpdown前端用户中心页面&#xff08;此功能若单独找我们定制也需要几百&#xff09; 收费付费下载资源、付费查看内容、付费观看…

LeetCode(1)合并两个有序数组【数组/字符串】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 88. 合并两个有序数组 1.题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合…

探索经典算法:贪心、分治、动态规划等

1.贪心算法 贪心算法是一种常见的算法范式&#xff0c;通常在解决最优化问题中使用。 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法范式。其核心思想是选择每一步的最佳解决方案&#xff0c;以期望达到最终的全局最优解。这种算法特点在于只考虑局部最优解&am…

【学术综述】-如何写出一篇好综述-写好综述要注意的问题

文章目录 1.前置1.1 SSD 的结构1.2 FTL的架构和作用 2 动机-why&#xff1f;3 做了什么【做了哪些方面的survey】&#xff1f;4 背景知识【上下文】5 研究的问题6 每个问题对应的解决方案 从昨天晚上【2023.11.09 22:00】到今天22:29的&#xff0c;花了一天的时间在读这篇surve…

一文学会Scala【Scala一站式学习笔记】

文章目录 为什么要学习Scala语言什么是Scala如何快速掌握Scala语言Scala环境安装配置Scala命令行 Scala的基本使用变量数据类型操作符if 表达式语句终结符循环高级for循环 Scala的集合体系集合SetListMapArrayArrayBuffer数组常见操作Tuple总结 Scala中函数的使用函数的定义函数…

手握“发展密钥”,TCL科技或迎价值重估?

在高度竞争且快速变化的泛半导体产业&#xff0c;每一次周期性或结构性的变化&#xff0c;都会对企业经营策略带来深远的影响。 2023年前三季度&#xff0c;泛半导体产业迎来结构性复苏。其中&#xff0c;主流显示领域供需关系趋向健康化&#xff0c;半导体显示行业整体上量价…

【Node.js入门】1.1Node.js 简介

Node.js入门之—1.1Node.js 简介 文章目录 Node.js入门之—1.1Node.js 简介什么是 Node.js错误说法 Node.js 的特点跨平台三方类库自带http服务器非阻塞I/O事件驱动单线程 Node.js 的应用场合适合用Node.js的场合不适合用Node.js的场合弥补Node.js不足的解决方案 什么是 Node.j…

获取AAC音频的ADTS固定头部信息

文章目录 前言一、AAC音频中的ADTS二、解析ADTS信息1.标准文档中介绍2.解析3.采样率索引和值4.下载AAC标准文档 前言 调试嵌入式设备中播放aac音频的过程中&#xff0c;了解了aac音频格式&#xff0c;记录在此&#xff0c;防止遗忘。 一、AAC音频中的ADTS ADTS&#xff08;Audi…

2.【自动驾驶与机器人中的SLAM技术】左乘模型推导ESKF

目录 1. 证明题 证明&#xff1a;若某个高斯随机变量为零均值&#xff0c;协方差为对角线矩阵且大小相同&#xff08;各向同性&#xff09;&#xff0c;那么在乘任意旋转矩阵以后&#xff0c;其均值仍为零&#xff0c;且协方差不变&#xff1b; 2. 代码实现运动方程将F矩阵…

Webpack--动态 import 原理及源码分析

前言 在平时的开发中&#xff0c;我们经常使用 import()实现代码分割和懒加载。在低版本的浏览器中并不支持动态 import()&#xff0c;那 webpack 是如何实现 import() polyfill 的&#xff1f; 原理分析 我们先来看看下面的 demo function component() {const btn docume…