yolov5转tensorrt c++

2023-11-08

目录

yolo-tensorrt

下载weights模型

onnx_tensorrt_project

编译问题解决

依赖项

自己生成weights模型,以及加载报错解决

生成引擎报错解决

批量预测

自动创建引擎

解决检测框乱的问题

提速


batch_size 大于1的调试:

tensorrt yolov5学习笔记_jacke121的专栏-CSDN博客

yolo-tensorrt

调试ok的地址:

https://github.com/enazoe/yolo-tensorrt

新增了yolov5-6。

也需要tensorrt7.1版本

下载weights模型

../configs/yolov5-5.0/yolov5s6.weights

下载地址:

https://github.com/enazoe/yolo-tensorrt/blob/master/yolov5_tutorial.md

结果是对的:

yolo-tensorrt_dll 报错不能提示。exe生成引擎文件后,也ok了。

yolo-tensorrt_exe结果:

python训练yolov5代码:没验证

F:\project\detect\yolov5\yolov5-5.0_voc

onnx_tensorrt_project

这个:

https://github.com/ttanzhiqiang/onnx_tensorrt_project

编译问题解决

1.cuda版本:

dll_detector.vcxproj

test_dll.vcxproj

可能另外一个项目的:

tiny_tensorrt_onnx.vcxproj

搜索11.1改为安装的版本,但是10.2版本以上,10.2 11.0 11.1

支持列表:

1. cuda10.2 TensorRT-7.2.1.6

2.cuda11 TensorRT-7.2.3.4

依赖项

F:\project\detect\yolov5\tensorrt\onnx_tensorrt_project\3rdparty\TensorRT-7.2.3.4\include
F:\project\detect\yolov5\tensorrt\onnx_tensorrt_project\3rdparty\opencv3.4.0\include\opencv
F:\project\detect\yolov5\tensorrt\onnx_tensorrt_project\3rdparty\opencv3.4.0\include

库文件:
F:\project\detect\yolov5\tensorrt\onnx_tensorrt_project\3rdparty\opencv3.4.0\lib\vc15
F:\project\detect\yolov5\tensorrt\onnx_tensorrt_project\3rdparty\TensorRT-7.2.3.4\lib


compute_30,sm_30

int main_yolov5()

改为:

int main()

yolo_detector.cpp中的int main()

改为:

int main_yolov5()

3.更改tensorrt的版本。

2.报错:

严重性    代码    说明    项目    文件    行    禁止显示状态
错误    LNK2001    无法解析的外部符号 createNvOnnxParser_INTERNAL    tiny_tensorrt_onnx    F:\project\detect\yolov5\tensorrt\onnx_tensorrt_project-main\tiny_tensorrt_onnx\Trt.obj    1    

 

解决:

tensorrt版本:7.2.3.4

添加lib:

nvonnxparser.lib
nvparsers.lib

https://github.com/ttanzhiqiang/onnx_tensorrt_project

cuda11.1 tensorrt 7.2.3版本,我换成6.0版本,int8放弃,编译成功,转onnx成功,转engine失败了

报错代码:

    if(!parser->parseFromFile(onnxModel.c_str(), static_cast<int>(nvinfer1::ILogger::Severity::kWARNING))) {
        spdlog::error("error: could not parse onnx engine");
        return false;
    }

yolov5-4.0,预测出来的值与python的结果稍微不一样:

自己生成weights模型,以及加载报错解决

yolo5各个版本cfg下载:

yolo-tensorrt/yolov5_tutorial.md at master · enazoe/yolo-tensorrt · GitHub

yolov5 tensorrt_jacke121的专栏-CSDN博客_yolov5tensorrt

改之前的:get_weights.py

import torch
import struct
from utils.torch_utils import select_device

# Initialize
device = select_device('cpu')
# Load model
# model = torch.load('yolov5s.pt', map_location=device)['model'].float()  # load to FP32
model = torch.load('_0.9437_5997.pt', map_location=device)['model'].float()  # load to FP32
model.to(device).eval()

f = open('yolov5s.weights', 'w')
f.write('{}\n'.format(len(model.state_dict().keys())))
for k, v in model.state_dict().items():
    vr = v.reshape(-1).cpu().numpy()
    f.write('{} {} '.format(k, len(vr)))
    for vv in vr:
        f.write(' ')
        f.write(struct.pack('>f',float(vv)).hex())
    f.write('\n')

报错解决之后的:get_weights.py

修改代码:f.write('{} '.format(k))

import torch
import struct
from utils.torch_utils import select_device

# Initialize
device = select_device('cpu')
# Load model
# model = torch.load('yolov5s.pt', map_location=device)['model'].float()  # load to FP32
model = torch.load('_0.9437_5997.pt', map_location=device)['model'].float()  # load to FP32
model.to(device).eval()

f = open('yolov5s.weights', 'w')
f.write('{}\n'.format(len(model.state_dict().keys())))
for k, v in model.state_dict().items():
    vr = v.reshape(-1).cpu().numpy()
    #f.write('{} {} '.format(k, len(vr)))
    f.write('{} '.format(k))
    for vv in vr:
        f.write(' ')
        f.write(struct.pack('>f',float(vv)).hex())
    f.write('\n')

c++解析weights,修改之前的:

void Yolo::load_weights_v5(const std::string s_weights_path_,
	std::map<std::string,std::vector<float>> &vec_wts_)
{
	vec_wts_.clear();
	assert(fileExists(s_weights_path_));
	std::cout << "Loading pre-trained weights..." << std::endl;
	std::ifstream file(s_weights_path_, std::ios_base::binary);
	assert(file.good());
	std::string line;
	while (std::getline(file,line))
	{
		if(line.empty())continue;
		std::stringstream iss(line);
		std::string wts_name;
		iss >> wts_name ;
		std::vector<float> weights;
		uint32_t n_str;
		while(iss >> std::hex >> n_str)
		{
			weights.push_back(reinterpret_cast<float&>(n_str));
		}
		vec_wts_[wts_name] = weights;
	}
	std::cout << "Loading complete!" << std::endl;
}

自己导出的weights,导入报错,报错的地方:

     std::cout << size << " size " << map_wts_[s_layer_name_ + ".weight"].size() << std::endl;
    assert(size == (map_wts_[s_layer_name_ + ".weight"].size()));

结果; 3456 3457

发现python保存时,保存名字+空格+长度+空格+数据。

c++读取,读取名字后,直接读取数据,导出实际长度比size大1。

修改后代码:

void Yolo::load_weights_v5(const std::string s_weights_path_,
	std::map<std::string,std::vector<float>> &vec_wts_)
{
	vec_wts_.clear();
	assert(fileExists(s_weights_path_));
	std::cout << "Loading pre-trained weights..." << std::endl;
	std::ifstream file(s_weights_path_, std::ios_base::binary);
	assert(file.good());
	std::string line;
	while (std::getline(file,line))
	{
		if(line.empty())continue;
		std::stringstream iss(line);
		std::string wts_name;
		iss >> wts_name ;

		int size_a;
		iss >> size_a;

		std::vector<float> weights;
		uint32_t n_str;
		while(iss >> std::hex >> n_str)
		{
			weights.push_back(reinterpret_cast<float&>(n_str));
		}
		vec_wts_[wts_name] = weights;
	}
	std::cout << "Loading complete!" << std::endl;
}

参考:Pytorch通过保存为ONNX模型转TensorRT5_连正的博客-CSDN博客_onnx转tensorrt

生成引擎报错解决

ERROR: (Unnamed Layer* 193) [Concatenation]: all concat input tensors must have the same dimensions except on the concatenation axis (0), but dimensions mismatched at index 1. Input 0 shape: [384,18,18], Input 1 shape: [384,17,17]
Assertion failed: d.nbDims == 3, file f:\project\detect\yolov5\tensorrt\yolo-tensorrt_exe\modules\trt_utils.cpp, line 444

后来发现是分辨率给错了,分辨率需要是64的倍数

yolov5s6.cfg 修改内容:

 width和height,需要是64的倍数

nc,实际训练的类别个数。

批量预测

yolo.cpp文件:

m_BatchSize = 2;// std::stoi(trim(block.at("batch")));

自动创建引擎

先检测engine文件不存在,然后自动创建,创建大概要上分钟,需要耐心等待。

void Yolo::create_engine_yolov5(const nvinfer1::DataType dataType,
    Int8EntropyCalibrator* calibrator )
{

yolov5s6-kFLOAT-batch1 

设备 模型 model batch gpu计算耗时/ms 平均耗时
1060 yolov5s6 fp32 1 23 23
1060 yolov5s7 fp32 2 40 20
1060 yolov5s8 fp32 4 72 18
1060 yolov5s9 fp32 8 130 16.25

输出特征维数:

w h anchors 特征数量 类别加box
80 64 3 15360 85 1305600
40 32 3 3840 85 326400
20 16 3 960 85 81600
10 8 3 240 85 20400 173400

打印特征:

std::vector<BBoxInfo> Yolo::decodeDetections(const int& imageIdx,
										     const int& imageH,
                                             const int& imageW)
{
//	Timer timer;
    std::vector<BBoxInfo> binfo;
    for (auto& tensor : m_OutputTensors)
    {

		for (int a = 0; a < 20; a++) {
			std::cout << tensor.hostBuffer[a] << " ";
		}
		std::cout << std::endl;

        std::vector<BBoxInfo> curBInfo = decodeTensor(imageIdx, imageH, imageW, tensor);
        binfo.insert(binfo.end(), curBInfo.begin(), curBInfo.end());
    }
//	timer.out("decodeDetections");
    return binfo;

解决检测框乱的问题

第一步:转化weights文件时,记录anchors,

就是下面代码中的:anchor_grid

代码文件:

gen_weight_new.py

anchor_grid = model.model[-1].anchors * model.model[-1].stride[...,None,None]

print(anchor_grid)
# model.model[-1].anchor_grid = anchor_grid
delattr(model.model[-1], 'anchor_grid')  # model.model[-1] is detect layer
model.model[-1].register_buffer("anchor_grid",anchor_grid)

打印结果:

tensor([[[ 35.18750,   5.43750],

         [ 69.50000,   6.88672],

         [ 49.90625,   9.78906]],

        [[ 75.00000,  10.44531],

         [112.87500,   8.17969],

         [141.87500,  10.35156]],

        [[217.25000,   8.93750],

         [243.00000,  12.73438],

         [320.00000,  10.21875]]])

第二步:保存到cfg中:

D:\work\lbg\yolov5_track\yolo-tensorrt_dll\sln\x64\Release\configs\kuaizi.cfg

width_multiple=0.5

anchors=35.18750,5.4375,69.50,6.88672, 49.90625,9.78906,75.0,10.445,112.870,8.17969,141.875,  10.35156,217.25,8.9375,243.0,12.73438,320.0,10.21875

提速

cfg中修改:

[net]

width=640

height=128

然后删掉kuaizi-kFLOAT-batch5_640.engine文件,重新生成engine文件,

自己的项目速度由16ms提升到8ms。

cfg中修改:

[net]

width=640

height=128

然后删掉kuaizi-kFLOAT-batch5_640.engine文件,重新生成engine文件,

速度右16ms提升到8ms。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

yolov5转tensorrt c++ 的相关文章

随机推荐

  • vscode开发python项目使用flake8、yapf工具格式化pip8编码规范

    前言 使用flake8 yapf工具工具去格式化py文件 有助于生成满足pep8规范 使用快捷键即可完成 提高开发效率 安装配置 1 win10下安装flake8 yapf pip install flake8 pip install ya
  • python 实现批量抠图

    系统 windows10 语言 python 3 6 编辑器 pycharm 安装库 1 paddlepaddle python m pip install paddlepaddle i https mirror baidu com pyp
  • ES Module 和 Commonjs 的区别

    只有静态引入 tree shaking才能够知道哪些引入哪些不引入 动态引入 要引入的代码都没有执行 所以不会引入 所以tree shaking不知道哪些引入哪些不引入
  • 只利用 phpstudy 如何运行PHP文件 超详细教程

    1 先编写好PHP代码 我这里用记事本简单写了一个 2 打开phpstudy 检查下有没有下载PHP环境 启动Apache 3 把编写好的PHP文件复制到phpstudy目录下的www文件中 注 phpstudy可以通过 网站 管理 打开根
  • Vue常见简写 “:“ , “@“ , “#“ :帮助刚入行的伙伴快速看懂代码

    提示 本文仅仅是对Vue中比较常见的简写进行总结 适合刚入行有时看不懂代码的朋友 目录 文章目录 前言 一 是什么 1 是什么意思 2 怎么使用 二 是什么 1 是什么意思 2 怎么使用 三 是什么 1 是什么意思 2 怎么使用 总结 前言
  • JDBC 学习笔记(基础)

    示意图 目录 创建 JDBC 应用 例子 通过本地协议纯 Java 驱动程序实现JDBC 代码具体步骤 1 注册驱动 2 建立与数据库的连接 3 获取执行SQL语句的对象 Statement 4 定义执行 SQL 语句 5 操作结果集对象
  • 100. Same Tree

    Definition for a binary tree node struct TreeNode int val TreeNode left TreeNode right TreeNode int x val x left NULL ri
  • 【Java】SpringBoot使用AOP进行日志解析打印+系统异常全局处理配置

    文章目录 前言 一 导入Lombok 二 创建日志打印Model 三 创建日志切面工具类 四 需要用到的一些常量类 五 创建接口请求切面 六 系统异常全局配置 总结 前言 为了方便项目部署在服务器之后 当出现BUG以及某些特殊需求时 会因为
  • Docker 笔记(全)

    1 关于Docker 1 1 概念 Docker 是一个开源的应用容器引擎 基于Go 语言 并遵从 Apache2 0 协议开源 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级 可移植的容器中 然后发布到任何流行的 Linu
  • 运算符之算术运算符、关系运算符、逻辑运算符、复合赋值运算符、其他运算符

    运算符是一种告诉编译器执行特定的数学或逻辑操作的符号 C 有丰富的内置运算符 分类如下 算术运算符 关系运算符 逻辑运算符 复合赋值运算符 位运算符 其他运算符 运算符优先级 由高到低 类别 运算符 结合性 后缀 gt 从左到右 一元 ty
  • python学得好 监狱进的早_蟒周刊-403-监狱中学 Python 改变人生

    200115 Zoom Quiet 大妈 用时 42 分钟 完成快译 200115 Zoom Quiet 大妈 用时 17 分钟 完成格式转抄 Ned was getting reports for a mysterious disk I
  • 铨顺宏RFID:应用超高频RFID技术智能档案管理系统

    根据超高频率RFID技术性智能化档案智能管理系统将改变这一现况 根据选用先 进的超高频率RFID自动检索技术应用和计算机系统技术性 以超高频率RFIDrfid标签做为信息储存媒体并黏贴在档案袋上 在超高频率RFID集成ic中储存该档案的基本
  • 看完这篇 教你玩转渗透测试靶机vulnhub——FunBox2(ROOKIE)

    Vulnhub靶机FunBox2 ROOKIE 渗透测试详解 Vulnhub靶机介绍 Vulnhub靶机下载 Vulnhub靶机安装 Vulnhub靶机漏洞详解 信息收集 FTP匿名访问 暴力破解 SSH私钥登入获取Shell Sudo提权
  • YOLO V4论文解读

    YOLO V4论文解读 一 YOLOV3回顾 二 YOLOV4中 三 Bag of freebies 数据扩充 模拟对象遮挡 结合多幅图像进行数据扩充 解决类别不平衡 label smoothing bbox Yolov4 use 四 Ba
  • java 字符串示例

    概述 最近项目上 需求 需要Android端在一段字符串分包处理 在此做个笔录 1 code public class Main public static void main String args System out println
  • mysql 1786_mysql错误:Statement violates GTID consistency

    在MYSQL中 执行建表语句时CREATE TABLE aaaa AS SELECT FROM menu 报 错误代码 1786 Statement violates GTID consistency CREATE TABLE SELECT
  • 训练loss不下降的原因总结

    表现 训练过程中loss值一直震荡 没有下降趋势 原因一 梯度消失 多因为网络深度过深 接近输入层的参数 梯度过小 解决方法 调整网络 激活函数relu batch normal 残差网络等 原因二 训练数据分布不均匀 这种情况对训练数据s
  • 力扣:350.两个数组的交集 II

    力扣 350 两个数组的交集 II 题目 给你两个整数数组 nums1 和 nums2 请你以数组形式返回两数组的交集 返回结果中每个元素出现的次数 应与元素在两个数组中都出现的次数一致 如果出现次数不一致 则考虑取较小值 可以不考虑输出结
  • 大数据课程I3——Kafka的消息流与索引机制

    文章作者邮箱 yugongshiye sina cn 地址 广东惠州 本章节目的 掌握Kafka的消息流处理 掌握Kafka的索引机制 掌握Kafka的消息系统语义 一 Kafka消息流处理 1 Producer 写入消息 流程说明 1 p
  • yolov5转tensorrt c++

    目录 yolo tensorrt 下载weights模型 onnx tensorrt project 编译问题解决 依赖项 自己生成weights模型 以及加载报错解决 生成引擎报错解决 批量预测 自动创建引擎 解决检测框乱的问题 提速 b