python pytorch模型转onnx模型(多输入+动态维度)

这篇具有很好参考价值的文章主要介绍了python pytorch模型转onnx模型(多输入+动态维度)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

(多输入+动态维度)整理的自定义神经网络pt转onnx过程的python代码,记录了pt文件转onnx全过程,简单的修改即可应用。

1、编写预处理代码

预处理代码 与torch模型的预处理代码一样

def preprocess(img):
	img = (cv2.cvtColor(img, cv2.COLOR_BGR2RGB)).transpose(2, 0, 1)
	img = np.expand_dims(img, 0)
	sh_im = img.shape
	if sh_im[2]%2==1:
    	img = np.concatenate((img, img[:, :, -1, :][:, :, np.newaxis, :]), axis=2)

	if sh_im[3]%2==1:
    	img = np.concatenate((img, img[:, :, :, -1][:, :, :, np.newaxis]), axis=3)

	img = normalize(img)
	img = torch.Tensor(img)
	return img

2、用onnxruntime导出onnx

def export_onnx(net, model_path, img, nsigma, onnx_outPath):
	nsigma /= 255.
	if torch.cuda.is_available():
    	state_dict = torch.load(model_path)
    	model = net.cuda()
    	dtype = torch.cuda.FloatTensor
    else:
    	state_dict = torch.load(model_path, map_location='cpu')
    	state_dict = remove_dataparallel_wrapper(state_dict)
    	model = net
    	dtype = torch.FloatTensor

	img = Variable(img.type(dtype))
	nsigma = Variable(torch.FloatTensor([nsigma]).type(dtype))

	# 我这里预训练权重中参数名字与网络名字不同
	# 相同的话可直接load_state_dict(state_dict)
	new_state_dict = {}
	for k, v in state_dict.items():
    	new_state_dict[k[7:]] = v
	model.load_state_dict(new_state_dict)
		
	# 设置onnx的输入输出列表,多输入多输出就设置多个
	input_list = ['input', 'nsigma']
	output_list = ['output']

	# onnx模型导出
	# dynamic_axes为动态维度,如果自己的输入输出是维度变化的建议设置,否则只能输入固定维度的tensor
	torch.onnx.export(model, (img, nsigma), onnx_outPath, verbose=True, opset_version=11, export_params=True,
		 				input_names=input_list, output_names=output_list,
		 				dynamic_axes={'input_img': {0: 'batch', 1: 'channel', 2: 'height', 3: 'width'},
		 				'output': {0: 'batch', 1: 'channel', 2: 'height', 3: 'width'}}) 

导出结果
onnx多个输入,python,pytorch,开发语言
onnx多个输入,python,pytorch,开发语言

3、对导出的模型进行检查

此处为检查onnx模型节点,后面如果onnx算子不支持转engine时,方便定位节点,找到不支持的算子进行修改

def check_onnx(onnx_model_path):
	model = onnx.load(onnx_model_path)
	onnx.checker.check_model((model))
	print(onnx.helper.printable_graph(model.graph))

下面贴出输出结果
onnx多个输入,python,pytorch,开发语言
onnx多个输入,python,pytorch,开发语言
netron可视化
onnx多个输入,python,pytorch,开发语言

4、推理onnx模型,查看输出是否一致

    def run_onnx(onnx_model_path, test_img, nsigma):
		nsigma /= 255.
		with torch.no_grad:
    	# 这里默认是cuda推理torch.cuda.FloatTensor
    	img = Variable(test_img.type(torch.cuda.FloatTensor))
    	nsigma = Variable(torch.FloatTensor([nsigma]).type(torch.cuda.FloatTensor))
    	# 设置GPU推理
    	device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    	providers = ['CUDAExecutionProvider'] if device != "cpu" else ['CPUExecutionProvider']

    	# 通过创建onnxruntime session来运行onnx模型
    	ort_session = ort.InferenceSession(onnx_model_path, providers=providers)
    	output = ort_session.run(output_names=['output'],
                             	input_feed={'input_img': np.array(img.cpu(), dtype=np.float32),
                                'nsigma':  np.array(nsigma.cpu(), dtype=np.float32)})
		return output

5、对onnx模型的输出进行处理,显示cv图像

def postprocess(img, img_noise_estime):
    out = torch.clamp(img-img_noise_estime, 0., 1.)
    outimg = variable_to_cv2_image(out)
    cv2.imshow(outimg)

6、编辑主函数进行测试

def main():

    ##############################
    #
    #        onnx模型导出
    #
    ##############################

    # pt权重路径:自己的路径 + mypt.pt
    model_path = "D:/python/ffdnet-pytorch/models/net_rgb.pth"
    # export onnx模型时输入进去数据,用于onnx记录网络的计算过程
    export_feed_path = "D:/python/ffdnet-pytorch/noisy.png"
    # onnx模型导出的路径
    onnx_outpath = "D:/python/ffdnet-pytorch/models/myonnx.onnx"

    # 实例化自己的网络模型并设置输入参数
    net = FFDNet(num_input_channels=3)
    nsigma = 25

    # onnx 导出
    img = cv2.imread(export_feed_path)
    input = preprocess(img)

    export_onnx(net, model_path, input, nsigma, onnx_outpath)
    print("export success!")
    ##############################
    #
    #        检查onnx模型
    #
    ##############################

    check_onnx(onnx_outpath)
    # netron可视化网络,可视化用节点记录的网络推理流程
    netron.start(onnx_outpath)

    ##############################
    #
    #        运行onnx模型
    #
    ##############################

    # 此处过程是数据预处理 ---> 调用run_onnx函数 ---> 对模型输出后处理
    # 具体代码就不再重复了

#完整代码文章来源地址https://www.toymoban.com/news/detail-754149.html

import time
import netron
import cv2
import torch
import onnx
import numpy as np
from torch.autograd import Variable
import onnxruntime as ort

from models import FFDNet
from utils import remove_dataparallel_wrapper, normalize, variable_to_cv2_image


# 此处为预处理代码 与torch模型的预处理代码一样
def preprocess(img):
    img = (cv2.cvtColor(img, cv2.COLOR_BGR2RGB)).transpose(2, 0, 1)
    img = np.expand_dims(img, 0)
    sh_im = img.shape
    if sh_im[2]%2==1:
        img = np.concatenate((img, img[:, :, -1, :][:, :, np.newaxis, :]), axis=2)

    if sh_im[3]%2==1:
        img = np.concatenate((img, img[:, :, :, -1][:, :, :, np.newaxis]), axis=3)

    img = normalize(img)
    img = torch.Tensor(img)
    return img

# 此处为onnx模型导出的代码,包括torch模型的pt权重加载,onnx模型的导出
def export_onnx(net, model_path, img, nsigma, onnx_outPath):

    nsigma /= 255.
    if torch.cuda.is_available():
        state_dict = torch.load(model_path)
        model = net.cuda()
        dtype = torch.cuda.FloatTensor
    else:
        state_dict = torch.load(model_path, map_location='cpu')
        state_dict = remove_dataparallel_wrapper(state_dict)
        model = net
        dtype = torch.FloatTensor

    img = Variable(img.type(dtype))
    nsigma = Variable(torch.FloatTensor([nsigma]).type(dtype))

    # 我这里预训练权重中参数名字与网络名字不同
    # 相同的话可直接load_state_dict(state_dict)
    new_state_dict = {}
    for k, v in state_dict.items():
        new_state_dict[k[7:]] = v

    model.load_state_dict(new_state_dict)

    # 设置onnx的输入输出列表,多输入多输出就设置多个
    input_list = ['input', 'nsigma']
    output_list = ['output']

    # onnx模型导出
    # dynamic_axes为动态维度,如果自己的输入输出是维度变化的建议设置,否则只能输入固定维度的tensor
    torch.onnx.export(model, (img, nsigma), onnx_outPath, verbose=True, opset_version=11, export_params=True,
                      input_names=input_list, output_names=output_list,
                      dynamic_axes={'input_img': {0: 'batch', 1: 'channel', 2: 'height', 3: 'width'},
                                    'output': {0: 'batch', 1: 'channel', 2: 'height', 3: 'width'}})


# 此处为检查onnx模型节点,后面如果onnx算子不支持转engine时,方便定位节点,找到不支持的算子进行修改
def check_onnx(onnx_model_path):
    model = onnx.load(onnx_model_path)
    onnx.checker.check_model((model))
    print(onnx.helper.printable_graph(model.graph))

# 此处为推理onnx模型的代码,检查输出是否跟torch模型相同
def run_onnx(onnx_model_path, test_img, nsigma):
    nsigma /= 255.
    with torch.no_grad:
        # 这里默认是cuda推理torch.cuda.FloatTensor
        img = Variable(test_img.type(torch.cuda.FloatTensor))
        nsigma = Variable(torch.FloatTensor([nsigma]).type(torch.cuda.FloatTensor))

        # 设置GPU推理
        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        providers = ['CUDAExecutionProvider'] if device != "cpu" else ['CPUExecutionProvider']

        # 通过创建onnxruntime session来运行onnx模型
        ort_session = ort.InferenceSession(onnx_model_path, providers=providers)
        output = ort_session.run(output_names=['output'],
                                 input_feed={'input_img': np.array(img.cpu(), dtype=np.float32),
                                             'nsigma':  np.array(nsigma.cpu(), dtype=np.float32)})
    return output

# 此处是后处理代码,将onnx模型的输出处理成可显示cv图像
# 与torch模型的后处理一样
def postprocess(img, img_noise_estime):
    out = torch.clamp(img-img_noise_estime, 0., 1.)
    outimg = variable_to_cv2_image(out)
    cv2.imshow(outimg)

def main():

    ##############################
    #
    #        onnx模型导出
    #
    ##############################

    # pt权重路径:自己的路径 + mypt.pt
    model_path = "D:/python/ffdnet-pytorch/models/net_rgb.pth"
    # export onnx模型时输入进去数据,用于onnx记录网络的计算过程
    export_feed_path = "D:/python/ffdnet-pytorch/noisy.png"
    # onnx模型导出的路径
    onnx_outpath = "D:/python/ffdnet-pytorch/models/myonnx.onnx"

    # 实例化自己的网络模型并设置输入参数
    net = FFDNet(num_input_channels=3)
    nsigma = 25

    # onnx 导出
    img = cv2.imread(export_feed_path)
    input = preprocess(img)

    export_onnx(net, model_path, input, nsigma, onnx_outpath)
    print("export success!")
    ##############################
    #
    #        检查onnx模型
    #
    ##############################
    onnx_outpath = "D:/python/ffdnet-pytorch/models/myonnx.onnx"
    check_onnx(onnx_outpath)
    # netron可视化网络,可视化用节点记录的网络推理流程
    netron.start(onnx_outpath)

    ##############################
    #
    #        运行onnx模型
    #
    ##############################

    # 此处过程是数据预处理 ---> 调用run_onnx函数 ---> 对模型输出后处理
    # 具体代码就不再重复了

if __name__ == '__main__':
    main()

到了这里,关于python pytorch模型转onnx模型(多输入+动态维度)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • pytorch模型(.pt)转onnx模型(.onnx)的方法详解(1)

    1. pytorch模型转换到onnx模型 2.运行onnx模型 3.比对onnx模型和pytorch模型的输出结果  我这里重点是第一点和第二点,第三部分  比较容易 首先你要安装 依赖库:onnx 和 onnxruntime, 也可以使用清华源镜像文件安装  速度会快些。 开始: 1. pytorch模型转换到onnx模型 pytorch 转 onnx

    2023年04月09日
    浏览(22)
  • 【深度学习】pytorch pth模型转为onnx模型后出现冗余节点“identity”,onnx模型的冗余节点“identity”

    onnx模型的冗余节点“identity”如下图。 首先,确保您已经安装了onnx-simplifier库: 然后,您可以按照以下方式使用onnx-simplifier库: 通过这个过程,onnx-simplifier库将会检测和移除不必要的\\\"identity\\\"节点,从而减少模型中的冗余。 请注意,使用onnx-simplifier库可能会改变模型的计算

    2024年02月09日
    浏览(33)
  • 【ONNX】使用 C++ 调用 ONNX 格式的 PyTorch 深度学习模型进行预测(Windows, C++, PyTorch, ONNX, Visual Studio, OpenCV)

    要使用 ONNX 模型进行预测,就需要使用 onnx runtime 首先到 ONNX 官网查询所需的版本 这里使用的 Windows,同时装了 CUDA 下面的链接可以进入到安装网址 https://www.nuget.org/packages/Microsoft.ML.OnnxRuntime.Gpu 安装命令为: 首先打开 Visual Studio 2019 新建一个用于测试的项目 右键点击项目,可

    2024年02月09日
    浏览(43)
  • onnxruntime推理时切换CPU/GPU以及修改onnx输入输出为动态

    前言 onnx模型作为中间模型,相较于pytorch直接推理,是有加速度效果的,且推理代码简单,不需要load各种网络。最近某些项目因为显存不够,onnxruntime推理时切换CPU/GPU,实现某些模型在CPU上推理,某些在GPU上推理。 查了一些别人的文章发现很多人都说onnxruntime推理没法像py

    2024年02月12日
    浏览(42)
  • Pytorch图像分类模型转ONNX(同济子豪兄学习笔记)

    安装配置环境 代码运行云GPU平台:公众号 人工智能小技巧 回复 gpu 同济子豪兄 2022-8-22 2023-4-28 2023-5-8 安装 Pytorch 安装 ONNX 安装推理引擎 ONNX Runtime 安装其它第三方工具包 验证安装配置成功 Pytorch图像分类模型转ONNX-ImageNet1000类 把Pytorch预训练ImageNet图像分类模型,导出为ONNX格

    2024年02月09日
    浏览(37)
  • pytorch框架:conv1d、conv2d的输入数据维度是什么样的

    Conv1d 的输入数据维度通常是一个三维张量,形状为 (batch_size, in_channels, sequence_length),其中: batch_size 表示当前输入数据的批次大小; in_channels 表示当前输入数据的通道数,对于文本分类任务通常为 1,对于图像分类任务通常为 3(RGB)、1(灰度)等; sequence_length 表示当前输

    2024年01月16日
    浏览(33)
  • 【深度学习】ONNX 模型文件修改节点的名称,修改输入名称,修改输出名称

    想要修改onnx模型文件的节点名称,要么在最初的pytorch代码里去改,要么就直接在onnx模型文件里改。 而我这里直接在onnx模型文件改,我有一个onnx文件,输出节点的名字是这样的: 这不改就看着真难受,那么就用python改: 改完后: 其实修改其他节点的名称也可以这样去做,

    2024年02月15日
    浏览(30)
  • PyTorch开放神经网络交换(Open Neural Network Exchange)ONNX通用格式模型的熟悉

    我们在深度学习中可以发现有很多不同格式的模型文件,比如不同的框架就有各自的文件格式: .model、.h5、.pb、.pkl、.pt、.pth等等 ,各自有标准就带来互通的不便,所以微软、Meta和亚马逊在内的合作伙伴社区一起搞一个 ONNX(Open Neural Network Exchange) 文件格式的通用标准,这样

    2024年02月12日
    浏览(29)
  • 深度学习-Python调用ONNX模型

    目录 ONNX模型使用流程 获取ONNX模型方法 使用ONNX模型 手动编写ONNX模型 Python调用ONNX模型 常见错误 错误raise ValueError...: 错误:Load model model.onnx failed 错误:\\\'CUDAExecutionProvider\\\' is not in available provider 错误:ONNXRuntimeError 错误:\\\'CUDAExecutionProvider\\\' is not in available provider ONNX(Open Ne

    2024年02月05日
    浏览(38)
  • python使用onnx模型进行推理

    我们可以看到基于YoloV7训练的cfg有两种yaml文件,一个是training文件夹,一个是deploy文件夹,这两种文件夹有啥不一样呢??? 大家可以看下下面别人的issuse,,记住这个很关键,就是你选择哪个yaml训练对你后面导出的onnx是很关键的,后面我们会说到。 1、training中的yaml文件

    2024年02月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包