YOLOv4 tensorrt推理 python版【附代码】

学了几天的tensorRT,又经过了几天的努力终于实现了YOLOv4 tensorRT推理,这篇文章将把这些成果开源出来,供大家免费使用。

YOLOv4代码我采用的是b站up主Bubbliiiing,相信大家应该都比较熟悉这位大佬。

关于trt的推理部分我是参考了官方YOLOV5 6.2版本。

有关YOLOv4的libtorch部署可以参考我另一篇文章:YOLOV4 libtorch

有关YOLOv4剪枝参考我另一篇文章: YOLOV4剪枝

剪枝以后的模型也可以用tensorrt进行推理【理论是可行的,虽然我还没试】 


环境说明

windows10

cuda10.2

cudnn8.2.1

pytorch1.7

tensorrt8.2.5.1

python 3.7

显卡:NVIDIA 1650 4G(比较拉跨)

注:linux下我还没有试,可能有些代码需要改,而且trt的版本也会受影响


  tensorrt安装可以看我另一篇文章:tensorrt安装与yolov5部署C++

 注意python版本的在下载完tensorrt后的文件夹中有个python文件夹,然后用pip安装【注意:TRT应该是8.2X以上可以安装python般的,其他的是C++】

其他tensorrt的学习资料可以看我tensorrt专栏。


目录

torch2onnx

torch推理

onnx推理

engine推理

检测结果:

代码:

权重:

所遇问题:


torch2onnx

改功能的实现在torch2onnx.py中。

你需要修改的地方有:

simplity:是否开启simplity模式

output_path: # 输出onnx路径

num_classes: # 类的数量

ckpt_path: # torch权重路径

input_shape: # 输入网络图像尺寸大小

python torch2onnx.py


转换过程如下:
graph(%images : Float(1:1108992, 3:369664, 608:608, 608:1, requires_grad=0, device=cpu),
      %yolo_head3.1.weight : Float(255:256, 256:1, 1:1, 1:1, requires_grad=1, device=cpu),
      %yolo_head3.1.bias : Float(255:1, requires_grad=1, device=cpu),
      %yolo_head2.1.weight : Float(255:512, 512:1, ...
```

可以通过Netron工具对onnx可视化


 onnx2engine

改功能的实现在onnx2trt.py中。

你需要修改的地方有:

onnx_path: # onnx文件路径

engine_path: # 输出engine路径

python onnx2trt.py

生成engine的时间比较长,在我电脑上大概用了10分钟左右,如果用trtexec也可以生成engine,这个构建时间会快很多。 


推理功能在predict.py中。

参数说明:
--weights: # 权重路径
--img: # 开启图像预测
--video: # 开启视频预测
--video_path: # 视频路径
--fps: # FPS测试
--onnx: # 开启onnx推理
--engine: # 开启trt预测
--input_shape: # 输入大小,默认608 * 608
--conf: # 置信度阈值
--nms: # NMS阈值

torch推理

图像推理:

python predict.py --weights model_data/yolo4_weights.pth --img --conf 0.5 --nms 0.4

视频推理:

python predict.py --weights model_data/yolo4_weights.pth --video --video_path 0

FPS测试:

python predict.py --weights model_data/yolo4_weights.pth --fps

onnx推理

图像推理:

python predict.py --weights model_data/yolov4.onnx --img --conf 0.5 --nms 0.4

视频推理:

python predict.py --weights model_data/yolov4.onnx --video --video_path 0

FPS测试:

python predict.py --weights model_data/yolov4.onnx --fps

engine推理

图像推理:

python predict.py --weights model_data/yolov4.engine --img --conf 0.5 --nms 0.4

视频推理:

python predict.py --weights model_data/yolov4.engine --video --video_path 0

FPS测试:

python predict.py --weights model_data/yolov4.engine --fps

检测结果:


代码:

git clone https://github.com/YINYIPENG-EN/YOLOv4_tensorRT_pytorch.git

权重:

链接:https://pan.baidu.com/s/1mlBMuiKqH3glZPqFGunXmw 
提取码:yypn

项目新增加了语音报警功能【看v2.0版本即可】

v2.0下载:

git clone --branch v2.0 https://github.com/YINYIPENG-EN/YOLOv4_tensorRT_pytorch.git

项目新增:目标跟踪(利用iou进行跟踪),可选用diou。看v3.0版本

git clone --branch v3.0 https://github.com/YINYIPENG-EN/YOLOv4_tensorRT_pytorch.git

 运行(可结合其他功能使用):

python predict.py --weights [weight path] --video --video_path 0 --engine --track --track_class

 

说明:本项目暂时未添加动态输入

所遇问题:

如果报下面的错误:

一般有这么几种情况:

1.cuda10.2需要打两个补丁(官网就有)

2.如果打了补丁还报错,一种是可能遇到了不支持的算子,一种是内存不够。

我trt8.2x版本中发现如果有包含全连接层的onnx不能转成engine,即便用trrexec强行转也会报这种错误,但如果我把全连接层用卷积层代替就没问题,我不知道更高版本的会不会解决这个问题。


[10/21/2022-18:32:29] [TRT] [E] 2:[ltWrapper.cpp::nvinfer1::rt::CublasLtWrapper::setupHeuristic::334] Error C
ode 2: Internal Error (Assertion cublasStatus == CUBLAS_STATUS_SUCCESS failed. )

 刚开始在用trt推理的时候发现准确率极差,但onnx和torch都很正常,于是我将预测代码中的图像处理由PIL度图像方式改为了opencv后有非常大的改善,但出现慢屏的框,于是通过分析onnx和engine推理的ouputs发现engine将yolo 的三个head顺序颠倒了,这个问题不知道为什么,重新调整顺序后就可以正常检测了【不过在测试FPS和map部分我没修改图像处理代码,因为FPS就只是算个model推理时间而已不用管他推理结果好坏,而测试map部分还是建议大家用训练torch模型测试或者你自己修改也可以】

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
TensorRT是NVIDIA开发的高性能推理引擎,可以用于加速深度学习模型的推理。而YoloV5是一种目标检测模型,可以用于检测图像中的物体。 下面是使用TensorRT进行YoloV5推理Python流程: 1. 导入必要的库和模块: ```python import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2 import os import time ``` 2. 加载YoloV5模型并构建TensorRT引擎: ```python def build_engine(onnx_file_path, engine_file_path): TRT_LOGGER = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(TRT_LOGGER) explicit_batch = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) network = builder.create_network(explicit_batch) parser = trt.OnnxParser(network, TRT_LOGGER) with open(onnx_file_path, 'rb') as model: if not parser.parse(model.read()): for error in range(parser.num_errors): print(parser.get_error(error)) return None builder.max_batch_size = 1 builder.max_workspace_size = 1 << 30 engine = builder.build_cuda_engine(network) with open(engine_file_path, "wb") as f: f.write(engine.serialize()) return engine ``` 3. 加载TensorRT引擎: ```python def load_engine(engine_file_path): with open(engine_file_path, "rb") as f, trt.Runtime(TRT_LOGGER) as runtime: engine = runtime.deserialize_cuda_engine(f.read()) return engine ``` 4. 加载测试图片并预处理: ```python def preprocess(image, input_shape): image = cv2.resize(image, (input_shape[1], input_shape[0])) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = np.transpose(image, (2, 0, 1)).astype(np.float32) image /= 255.0 image = np.expand_dims(image, axis=0) return image ``` 5. 执行推理: ```python def do_inference(context, bindings, inputs, outputs, stream, batch_size=1): [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs] context.execute_async(bindings=bindings, batch_size=batch_size, stream_handle=stream.handle) [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs] stream.synchronize() return [out.host for out in outputs] ``` 6. 解析推理结果: ```python def postprocess(outputs, anchors, masks, input_shape, image_shape, conf_thres=0.5, iou_thres=0.5): num_classes = 80 num_anchors = 3 num_layers = 3 anchor_masks = masks anchors = np.array(anchors).reshape(num_layers, -1, 2) input_h, input_w = input_shape image_h, image_w, _ = image_shape scale_h, scale_w = image_h / input_h, image_w / input_w box_mins = np.zeros((0, 2)) box_maxes = np.zeros((0, 2)) box_classes = np.zeros((0)) box_scores = np.zeros((0)) for i in range(num_layers): grid_h, grid_w = input_h // 32 // (2 ** i), input_w // 32 // (2 ** i) outputs_i = outputs[i] outputs_i = np.reshape(outputs_i, (batch_size, num_anchors * (5 + num_classes), grid_h * grid_w)).transpose(0, 2, 1) outputs_i[..., :2] = 1 / (1 + np.exp(-outputs_i[..., :2])) outputs_i[..., 2:4] = np.exp(outputs_i[..., 2:4]) outputs_i[..., 4:] = 1 / (1 + np.exp(-outputs_i[..., 4:])) anchors_scale = anchors[i] anchors_scale = anchors_scale[np.newaxis, :, :] box_xy = outputs_i[..., :2] box_wh = outputs_i[..., 2:4] box_confidence = outputs_i[..., 4:5] box_class_probs = outputs_i[..., 5:] box_xy += (np.arange(grid_w, dtype=np.float32) + 0.5)[np.newaxis, :, np.newaxis] box_xy += (np.arange(grid_h, dtype=np.float32) + 0.5)[:, np.newaxis, np.newaxis] box_xy *= 32 * (2 ** i) box_wh *= anchors_scale box_wh *= np.array([image_w / input_w, image_h / input_h])[np.newaxis, np.newaxis, :] box_mins = np.concatenate([box_mins, box_xy - box_wh / 2], axis=0) box_maxes = np.concatenate([box_maxes, box_xy + box_wh / 2], axis=0) box_scores = np.concatenate([box_scores, box_confidence], axis=0) box_classes = np.concatenate([box_classes, np.argmax(box_class_probs, axis=-1).flatten()], axis=0) boxes = np.concatenate([box_mins, box_maxes], axis=-1) boxes /= np.array([scale_w, scale_h, scale_w, scale_h])[np.newaxis, :] nms_indices = cv2.dnn.NMSBoxes(boxes.tolist(), box_scores.flatten().tolist(), conf_thres, iou_thres) results = [] for i in nms_indices: i = i[0] box = boxes[i] score = box_scores.flatten()[i] label = box_classes.flatten()[i] results.append((box[0], box[1], box[2], box[3], score, label)) return results ``` 完整代码请参考:https://github.com/wang-xinyu/tensorrtx/tree/master/yolov5 需要注意的是,使用TensorRT进行YoloV5推理需要先将YoloV5模型转换为ONNX格式,然后再使用TensorRT构建引擎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃肉的鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值