OpenMMlab导出PointPillars模型并用onnxruntime推理

2024-01-07 20:52

本文主要是介绍OpenMMlab导出PointPillars模型并用onnxruntime推理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

导出onnx文件

通过mmdeploy的tool/deploy.py脚本容易转换得到PointPillars的end2end.onnx模型。
在这里插入图片描述
根据https://github.com/open-mmlab/mmdeploy/blob/main/docs/zh_cn/04-supported-codebases/mmdet3d.md显示,截止目前 mmdet3d 的 voxelize 预处理和后处理未转成 onnx 操作;C++ SDK 也未实现 voxelize 计算。

onnxruntime推理

需要安装mmdetection3d等包:

import torch
import onnxruntime
import numpy as np
from torch.nn import functional as F
from mmdet3d.apis import init_model, inference_detector
from mmcv.ops import nms, nms_rotated
from ops.voxel_module import Voxelization
from ops.iou3d_op import nms_gpuconfig_file = 'pointpillars_hv_secfpn_8xb6-160e_kitti-3d-car.py'
checkpoint_file = 'hv_pointpillars_secfpn_6x8_160e_kitti-3d-car_20220331_134606-d42d15ed.pth'class PointPillars(torch.nn.Module):def __init__(self):super().__init__()self.model = init_model(config_file, checkpoint_file, device='cpu')self.box_code_size = 7self.num_classes = 1self.nms_pre = 100self.max_num = 50self.score_thr = 0.1self.nms_thr = 0.01self.voxel_layer = Voxelization(voxel_size= [0.16, 0.16, 4], point_cloud_range=[0, -39.68, -3, 69.12, 39.68, 1], max_num_points=32, max_voxels=[16000, 40000])self.mlvl_priors = self.model.bbox_head.prior_generator.grid_anchors([torch.Size([248, 216])])self.mlvl_priors = [prior.reshape(-1, self.box_code_size) for prior in self.mlvl_priors]def pre_process(self, x):res_voxels, res_coors, res_num_points = self.voxel_layer(x)return res_voxels, res_coors, res_num_pointsdef xywhr2xyxyr(self, boxes_xywhr):boxes = torch.zeros_like(boxes_xywhr)half_w = boxes_xywhr[..., 2] / 2half_h = boxes_xywhr[..., 3] / 2boxes[..., 0] = boxes_xywhr[..., 0] - half_wboxes[..., 1] = boxes_xywhr[..., 1] - half_hboxes[..., 2] = boxes_xywhr[..., 0] + half_wboxes[..., 3] = boxes_xywhr[..., 1] + half_hboxes[..., 4] = boxes_xywhr[..., 4]return boxesdef box3d_multiclass_nms(self, mlvl_bboxes, mlvl_bboxes_for_nms, mlvl_scores, mlvl_dir_scores):num_classes = mlvl_scores.shape[1] - 1bboxes = []scores = []labels = []dir_scores = []for i in range(0, num_classes):cls_inds = mlvl_scores[:, i] > self.score_thrif not cls_inds.any():continue_scores = mlvl_scores[cls_inds, i]_bboxes_for_nms = mlvl_bboxes_for_nms[cls_inds, :].cuda()keep = torch.zeros(_bboxes_for_nms.size(0), dtype=torch.long)num_out = nms_gpu(_bboxes_for_nms.cuda(), keep, self.nms_thr, _bboxes_for_nms.device.index)selected = keep[:num_out]bboxes.append(mlvl_bboxes[selected])scores.append(_scores[selected])cls_label = mlvl_bboxes.new_full((len(selected), ), i, dtype=torch.long)labels.append(cls_label)dir_scores.append(mlvl_dir_scores[selected])if bboxes:bboxes = torch.cat(bboxes, dim=0)scores = torch.cat(scores, dim=0)labels = torch.cat(labels, dim=0)dir_scores = torch.cat(dir_scores, dim=0)if bboxes.shape[0] > self.max_num:_, inds = scores.sort(descending=True)inds = inds[:self.max_num]bboxes = bboxes[inds, :]labels = labels[inds]scores = scores[inds]dir_scores = dir_scores[inds]else:bboxes = mlvl_scores.new_zeros((0, mlvl_bboxes.size(-1)))scores = mlvl_scores.new_zeros((0, ))labels = mlvl_scores.new_zeros((0, ), dtype=torch.long)dir_scores = mlvl_scores.new_zeros((0, ))return (bboxes, scores, labels, dir_scores)def decode(self, anchors, deltas):xa, ya, za, wa, la, ha, ra = torch.split(anchors, 1, dim=-1)xt, yt, zt, wt, lt, ht, rt = torch.split(deltas, 1, dim=-1)za = za + ha / 2diagonal = torch.sqrt(la**2 + wa**2)xg = xt * diagonal + xayg = yt * diagonal + yazg = zt * ha + zalg = torch.exp(lt) * lawg = torch.exp(wt) * wahg = torch.exp(ht) * harg = rt + razg = zg - hg / 2return torch.cat([xg, yg, zg, wg, lg, hg, rg], dim=-1)def predict_by_feat_single(self, cls_score, bbox_pred, dir_cls_pred):priors = self.mlvl_priors[0]dir_cls_pred = dir_cls_pred.permute(1, 2, 0).reshape(-1, 2)dir_cls_scores = torch.max(dir_cls_pred, dim=-1)[1]cls_score = cls_score.permute(1, 2, 0).reshape(-1, self.num_classes)scores = cls_score.sigmoid()bbox_pred = bbox_pred.permute(1, 2, 0).reshape(-1, self.box_code_size)       max_scores, _ = scores.max(dim=1)_, topk_inds = max_scores.topk(self.nms_pre)    priors = priors[topk_inds, :].cpu()bbox_pred = bbox_pred[topk_inds, :]scores = scores[topk_inds, :]dir_cls_scores = dir_cls_scores[topk_inds]bboxes = self.decode(priors, bbox_pred)mlvl_bboxes_bev =  torch.cat([bboxes[:, 0:2], bboxes[:, 3:5], bboxes[:, 5:6]], dim=1)mlvl_bboxes_for_nms = self.xywhr2xyxyr(mlvl_bboxes_bev)    padding = scores.new_zeros(scores.shape[0], 1)scores = torch.cat([scores, padding], dim=1)       results = self.box3d_multiclass_nms(bboxes, mlvl_bboxes_for_nms, scores, dir_cls_scores)bboxes, scores, labels, dir_scores = resultsif bboxes.shape[0] > 0:   dir_rot = bboxes[..., 6] + np.pi/2 - torch.floor(bboxes[..., 6] + np.pi/2 / np.pi ) * np.pibboxes[..., 6] = (dir_rot - np.pi/2 + np.pi * dir_scores.to(bboxes.dtype))         return bboxes, scores, labelsdef forward(self, res_voxels, res_coors, res_num_points):  voxels, coors, num_points = [], [], []res_coors = F.pad(res_coors, (1, 0), mode='constant', value=0)voxels.append(res_voxels)coors.append(res_coors)num_points.append(res_num_points)voxels = torch.cat(voxels, dim=0)coors = torch.cat(coors, dim=0)num_points = torch.cat(num_points, dim=0)x = self.model.voxel_encoder(voxels, num_points, coors) x = self.model.middle_encoder(x, coors, batch_size=1)         x = self.model.backbone(x)x = self.model.neck(x)  cls_scores, bbox_preds, dir_cls_preds = self.model.bbox_head(x)    return cls_scores[0], bbox_preds[0], dir_cls_preds[0]points = np.fromfile('demo/data/kitti/000008.bin', dtype=np.float32)
points = torch.from_numpy(points.reshape(-1, 4))  voxel_layer = Voxelization(voxel_size= [0.16, 0.16, 4], point_cloud_range=[0, -39.68, -3, 69.12, 39.68, 1], max_num_points=32, max_voxels=[16000, 40000])     
res_voxels, res_coors, res_num_points = voxel_layer(points)
res_coors = torch.cat([torch.zeros([res_coors.shape[0], 1]), res_coors], axis=1)onnx_session = onnxruntime.InferenceSession("../work_dir/onnx/pointpillars/end2end.onnx", providers=['CPUExecutionProvider'])input_name = []
for node in onnx_session.get_inputs():input_name.append(node.name)output_name = []
for node in onnx_session.get_outputs():output_name.append(node.name)inputs = {}
inputs['voxels'] = res_voxels.numpy()
inputs['num_points'] = res_num_points.type(torch.int32).numpy()
inputs['coors'] = res_coors.type(torch.int32).numpy()outputs = onnx_session.run(None, inputs)
cls_score = torch.from_numpy(outputs[0][0])
bbox_pred = torch.from_numpy(outputs[1][0])
dir_cls_pred = torch.from_numpy(outputs[2][0])pointpillars = PointPillars()
result = pointpillars.predict_by_feat_single(cls_score, bbox_pred, dir_cls_pred)
print(result)

其中ops包来自:https://github.com/zhulf0804/PointPillars/tree/main/ops
结果输出:
在这里插入图片描述

这篇关于OpenMMlab导出PointPillars模型并用onnxruntime推理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/581202

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

AI Toolkit + H100 GPU,一小时内微调最新热门文生图模型 FLUX

上个月,FLUX 席卷了互联网,这并非没有原因。他们声称优于 DALLE 3、Ideogram 和 Stable Diffusion 3 等模型,而这一点已被证明是有依据的。随着越来越多的流行图像生成工具(如 Stable Diffusion Web UI Forge 和 ComyUI)开始支持这些模型,FLUX 在 Stable Diffusion 领域的扩展将会持续下去。 自 FLU

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号