草庐IT

【YOLOv5】手把手教你使用LabVIEW ONNX Runtime部署 TensorRT加速,实现YOLOv5实时物体识别(含源码)

virobotics 2023-03-28 原文

 

前言

上一篇博客给大家介绍了LabVIEW开放神经网络交互工具包【ONNX】,今天我们就一起来看一下如何使用LabVIEW开放神经网络交互工具包实现TensorRT加速YOLOv5。

以下是YOLOv5的相关笔记总结,希望对大家有所帮助。

内容地址链接
【YOLOv5】LabVIEW+OpenVINO让你的YOLOv5在CPU上飞起来 https://www.cnblogs.com/virobotics/p/16802248.html
【YOLOv5】LabVIEW OpenCV dnn快速实现实时物体识别(Object Detection) https://www.cnblogs.com/virobotics/p/16788146.html

一、TensorRT简介

TensorRT是一个高性能的深度学习推理(Inference)优化器,可以为深度学习应用提供低延迟、高吞吐率的部署推理。TensorRT可用于对超大规模数据中心、嵌入式平台或自动驾驶平台进行推理加速。TensorRT现已能支持TensorFlow、Caffe、Mxnet、Pytorch等几乎所有的深度学习框架,将TensorRT和NVIDIA的GPU结合起来,能在几乎所有的框架中进行快速和高效的部署推理。主要用来针对 NVIDIA GPU进行 高性能推理(Inference)加速。

通常我们做项目,在部署过程中想要加速,无非就那么几种办法,如果我们的设备是CPU,那么可以用openvion,如果我们希望能够使用GPU,那么就可以尝试TensorRT了。那么为什么要选择TensorRT呢?因为我们目前主要使用的还是Nvidia的计算设备,TensorRT本身就是Nvidia自家的东西,那么在Nvidia端的话肯定要用Nvidia亲儿子了。

不过因为TensorRT的入门门槛略微有些高,直接劝退了想要入坑的玩家。其中一部分原因是官方文档比较杂乱;另一部分原因就是TensorRT比较底层,需要一点点C++和硬件方面的知识,学习难度会更高一点。我们做的开放神经网络交互工具包GPU版本在GPU上做推理时,ONNXRuntime可采用CUDA作为后端进行加速,要更快速可以切换到TensorRT,虽然和纯TensorRT推理速度比还有些差距,但也十分快了。如此可以大大降低开发难度,能够更快更好的进行推理。。

二、准备工作

按照 LabVIEW开放神经网络交互工具包(ONNX)下载与超详细安装教程 安装所需软件,因本篇博客主要给大家介绍如何使用TensorRT加速YOLOv5,所以建议大家安装GPU版本的onnx工具包,否则无法实现TensorRT的加速

三、YOLOv5模型的获取

为方便使用,博主已经将yolov5模型转化为onnx格式,可在百度网盘下载 链接:https://pan.baidu.com/s/15dwoBM4W-5_nlRj4G9EhRg?pwd=yiku 提取码:yiku

1.下载源码

将Ultralytics开源的YOLOv5代码Clone或下载到本地,可以直接点击Download ZIP进行下载,

下载地址:https://github.com/ultralytics/yolov5

2.安装模块

解压刚刚下载的zip文件,然后安装yolov5需要的模块,记住cmd的工作路径要在yolov5文件夹下:

打开cmd切换路径到yolov5文件夹下,并输入如下指令,安装yolov5需要的模块

 pip install -r requirements.txt 

3.下载预训练模型

打开cmd,进入python环境,使用如下指令下载预训练模型:

1 import torch
2 3 # Model
4 model = torch.hub.load('ultralytics/yolov5', 'yolov5s')  # or yolov5n - yolov5x6, custom

 


成功下载后如下图所示:

4.转换为onnx模型

在yolov5之前的yolov3和yolov4的官方代码都是基于darknet框架实现的,因此opencv的dnn模块做目标检测时,读取的是.cfg和.weight文件,非常方便。但是yolov5的官方代码是基于pytorch框架实现的。需要先把pytorch的训练模型.pt文件转换到.onnx文件,然后才能载入到opencv的dnn模块里。

将.pt文件转化为.onnx文件,主要是参考了nihate大佬的博客:https://blog.csdn.net/nihate/article/details/112731327

将export.py做如下修改,将def export_onnx()中的第二个try注释掉,即如下部分注释:

 1 '''
 2     try:
 3         check_requirements(('onnx',))
 4         import onnx
 5  6         LOGGER.info(f'\n{prefix} starting export with onnx {onnx.__version__}...')
 7         f = file.with_suffix('.onnx')
 8         print(f)
 9 10         torch.onnx.export(
11             model,
12             im,
13             f,
14             verbose=False,
15             opset_version=opset,
16             training=torch.onnx.TrainingMode.TRAINING if train else torch.onnx.TrainingMode.EVAL,
17             do_constant_folding=not train,
18             input_names=['images'],
19             output_names=['output'],
20             dynamic_axes={
21                 'images': {
22                     0: 'batch',
23                     2: 'height',
24                     3: 'width'},  # shape(1,3,640,640)
25                 'output': {
26                     0: 'batch',
27                     1: 'anchors'}  # shape(1,25200,85)
28             } if dynamic else None)
29 30         # Checks
31         model_onnx = onnx.load(f)  # load onnx model
32         onnx.checker.check_model(model_onnx)  # check onnx model
33 34         # Metadata
35         d = {'stride': int(max(model.stride)), 'names': model.names}
36         for k, v in d.items():
37             meta = model_onnx.metadata_props.add()
38             meta.key, meta.value = k, str(v)
39         onnx.save(model_onnx, f)'''

 

并新增一个函数def my_export_onnx():

 1 def my_export_onnx(model, im, file, opset, train, dynamic, simplify, prefix=colorstr('ONNX:')):
 2     print('anchors:', model.yaml['anchors'])
 3     wtxt = open('class.names', 'w')
 4     for name in model.names:
 5         wtxt.write(name+'\n')
 6     wtxt.close()
 7     # YOLOv5 ONNX export
 8     print(im.shape)
 9     if not dynamic:
10         f = os.path.splitext(file)[0] + '.onnx'
11         torch.onnx.export(model, im, f, verbose=False, opset_version=12, input_names=['images'], output_names=['output'])
12     else:
13         f = os.path.splitext(file)[0] + '_dynamic.onnx'
14         torch.onnx.export(model, im, f, verbose=False, opset_version=12, input_names=['images'],
15                           output_names=['output'], dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # shape(1,3,640,640)
16                                         'output': {0: 'batch', 1: 'anchors'}  # shape(1,25200,85)
17                                         })
18     return f

 

在cmd中输入转onnx的命令(记得将export.py和pt模型放在同一路径下):

python export.py --weights yolov5s.pt --include onnx

如下图所示为转化成功界面

其中yolov5s可替换为yolov5m\yolov5m\yolov5l\yolov5x

四、LabVIEW使用TensorRT加速YOLOv5,实现实时物体识别(yolov5_new_onnx.vi)

1.LabVIEW调用YOLOv5源码

2.识别结果

选择加速方式为:TensorRT

使用TensorRT加速,实时检测推理用时为20~30ms/frame,比单纯使用cuda加速快了30%,同时没有丢失任何的精度。博主使用的电脑显卡为1060显卡,各位如果使用30系列的显卡,速度应该会更快。

五、纯CPU下opencv dnn和onnx工具包加载YOLOv5实现实时物体识别推理用时对比

1、opencv dnn cpu下YOLOv5推理速度为:300ms左右/frame

2、onnx工具包cpu下YOLOv5推理速度为:200ms左右/frame

对比我们发现,同样使用cpu进行推理,onnx工具包推理速度要比opencv dnn推理速度快30%左右。

六、源码及模型下载

可关注微信公众号:VIRobotics ,回复关键词:yolov5_onnx ,进行源码下载

附加说明:计算机环境

  • 操作系统:Windows10

  • python:3.6及以上

  • LabVIEW:2018及以上 64位版本

  • 视觉工具包:virobotics_lib_onnx_cuda_tensorrt-1.0.0.11以上版本

总结

以上就是今天要给大家分享的内容。大家可根据链接下载相关源码与模型。

如果有问题可以在评论区里讨论,提问前请先点赞支持一下博主哦,如您想要探讨更多关于LabVIEW与人工智能技术,欢迎加入我们的技术交流群:705637299,进群请备注暗号:LabVIEW机器学习

如果文章对你有帮助,欢迎关注、点赞、收藏

 

有关【YOLOv5】手把手教你使用LabVIEW ONNX Runtime部署 TensorRT加速,实现YOLOv5实时物体识别(含源码)的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  10. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

随机推荐