Pointpillars模型转onnx
最近在做pointpillars模型部署,从openpcd训练好的模型想转onnx,发现很困难,因为pytorch是动态机制,转换需要读取模型+参数+输入才能完成输出,自己搞了一下老有报错,很困难,调研了一些文章:
PointPillars 工程复现_pointpillars复现-CSDN博客
OpenPCDet模型导出ONNX - 半夜打老虎 - 博客园
这些文章中把model拆解成多个模块,然后单独加载参数和输入,最后输出多个onnx
分析原因,openpcd把模型的各个模块拆解然后单独封装,靠外部yaml模板控制和管理,这样用着比较方便。但是下面onnx的转换要求好像是加载一个完整的类,所以需要根据各个模块单独拆解!
#openpcd各个模块单独封装,然后靠字典把他们串在一起
def build_detector(model_cfg, num_class, dataset):model = __all__[model_cfg.NAME](model_cfg=model_cfg, num_class=num_class, dataset=dataset)return model#而onnx 转换功能上要求加载一个完整的模型if not args.no_cuda:model = PointPillarsCore(nclasses=len(CLASSES)).cuda()model.load_state_dict(torch.load(args.ckpt))else:model = PointPillarsCore(nclasses=len(CLASSES))model.load_state_dict(torch.load(args.ckpt, map_location=torch.device('cpu')))model.eval()
以下是我拆解的结果:可以看出,我加载的openpcdet 训练后的模型 里面拆出4个子模块。也就是我得拆出4个onnx,我感觉这样太麻烦了!openpcd这个技术路线好像不太行啊!
下面是我的调试代码
###############################################3model.load_params_from_file(filename=args.ckpt, logger=logger, to_cpu=dist_test, pre_trained_path=args.pretrained_model)model.cuda()print("------------------")print(dir(model))# print(model.module_list)print(len(model.module_list))print('0',model.module_list[0])print('1',model.module_list[1])print('2',model.module_list[2])print('3',model.module_list[3])print("******************")
##################################################下面是输出4
0 PillarVFE((pfn_layers): ModuleList((0): PFNLayer((linear): Linear(in_features=11, out_features=64, bias=False)(norm): BatchNorm1d(64, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)))
)
1 PointPillarScatter()
2 BaseBEVBackbone((blocks): ModuleList((0): Sequential((0): ZeroPad2d(padding=(1, 1, 1, 1), value=0.0)(1): Conv2d(64, 64, kernel_size=(3, 3), stride=(2, 2), bias=False)(2): BatchNorm2d(64, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)(3): ReLU()(4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
改进方法:
训练的时候,保持完整的模型,这样onnx转换的时候就不需要加载完整的模型!!不知道这样行不行