Pytorch -- ONNX -- ONNXRuntime

本文介绍了如何将一个PyTorch训练好的超分辨率模型进行部署,包括模型转换为ONNX格式以及使用ONNXRuntime进行推理。首先,展示了如何加载预训练模型并进行推理,然后详细讲解了利用torch.onnx.export将PyTorch模型转换为ONNX模型的过程。最后,通过ONNXRuntime进行模型推理验证,确保模型转换无误。
摘要由CSDN通过智能技术生成

开始学习模型部署了。学了一个超简单的部署

模型部署入门教程(一):模型部署简介 - 知乎 (zhihu.com)

总结

  • 模型部署,指把训练好的模型在特定环境中运行的过程。模型部署要解决模型框架兼容性差和模型运行速度慢这两大问题。
  • 模型部署的常见流水线是“深度学习框架-中间表示-推理引擎”。其中比较常用的一个中间表示是 ONNX。
  • 深度学习模型实际上就是一个计算图。模型部署时通常把模型转换成静态的计算图,即没有控制流(分支语句、循环语句)的计算图。
  • PyTorch 框架自带对 ONNX 的支持,只需要构造一组随机的输入,并对模型调用 torch.onnx.export 即可完成 PyTorch 到 ONNX 的转换。
  • 推理引擎 ONNX Runtime 对 ONNX 模型有原生的支持。给定一个 .onnx 文件,只需要简单使用 ONNX Runtime 的 Python API 就可以完成模型推理。
import os
import cv2
import numpy as np
import requests
import torch
import torch.onnx
from torch import nn


class SuperResolutionNet(nn.Module):
    def __init__(self, upscale_factor):
        super().__init__()
        self.upscale_factor = upscale_factor
        self.img_upsampler = nn.Upsample(
            scale_factor=self.upscale_factor,
            mode='bicubic',
            align_corners=False)

        self.conv1 = nn.Conv2d(3, 64, kernel_size=9, padding=4)
        self.conv2 = nn.Conv2d(64, 32, kernel_size=1, padding=0)
        self.conv3 = nn.Conv2d(32, 3, kernel_size=5, padding=2)

        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.img_upsampler(x)
        out = self.relu(self.conv1(x))
        out = self.relu(self.conv2(out))
        out = self.conv3(out)
        return out

    # Download checkpoint and test image


urls = ['https://download.openmmlab.com/mmediting/restorers/srcnn/srcnn_x4k915_1x16_1000k_div2k_20200608-4186f232.pth',
        'https://raw.githubusercontent.com/open-mmlab/mmediting/master/tests/data/face/000001.png']
names = ['srcnn.pth', 'face.png']
for url, name in zip(urls, names):
    if not os.path.exists(name):
        open(name, 'wb').write(requests.get(url).content)


def init_torch_model():
    torch_model = SuperResolutionNet(upscale_factor=3)

    state_dict = torch.load('srcnn.pth')['state_dict']

    # Adapt the checkpoint
    for old_key in list(state_dict.keys()):
        new_key = '.'.join(old_key.split('.')[1:])
        state_dict[new_key] = state_dict.pop(old_key)

    torch_model.load_state_dict(state_dict)
    torch_model.eval()
    return torch_model


model = init_torch_model()
input_img = cv2.imread('face.png').astype(np.float32)

# HWC to NCHW
input_img = np.transpose(input_img, [2, 0, 1])
input_img = np.expand_dims(input_img, 0)

# Inference
torch_output = model(torch.from_numpy(input_img)).detach().numpy()

#为了让模型输出成正确的图片格式,我们把模型的输出转换成 HWC 格式,并保证每一通道的颜色值都在 0~255 之间。
# NCHW to HWC
torch_output = np.squeeze(torch_output, 0)
torch_output = np.clip(torch_output, 0, 255)
torch_output = np.transpose(torch_output, [1, 2, 0]).astype(np.uint8)

#如果脚本正常运行的话,一幅超分辨率的人脸照片会保存在 “face_torch.png” 中
# Show image
cv2.imwrite("face_torch.png", torch_output)


#PyTorch的模型转换成ONNX格式的模型
x = torch.randn(1, 3, 256, 256)
#前三个参数分别是要转换的模型、模型的任意一组输入、导出的 ONNX 文件的文件名
#剩下的参数中,opset_version 表示 ONNX 算子集的版本
#如果上述代码运行成功,目录下会新增一个"srcnn.onnx"的 ONNX 模型文件
with torch.no_grad():
    torch.onnx.export(
        model,
        x,
        "srcnn.onnx",
        opset_version=11,
        input_names=['input'],
        output_names=['output'])

#我们可以用下面的脚本来验证一下模型文件是否正确
import onnx
#其中,onnx.load 函数用于读取一个 ONNX 模型。
#onnx.checker.check_model 用于检查模型格式是否正确,如果有错误的话该函数会直接报错。
#我们的模型是正确的,控制台中应该会打印出"Model correct"
onnx_model = onnx.load("srcnn.onnx")
try:
    onnx.checker.check_model(onnx_model)
except Exception:
    print("Model incorrect")
else:
    print("Model correct")

#用 ONNX Runtime 运行一下模型,完成模型部署的最后一步
#如果代码正常运行的话,另一幅超分辨率照片会保存在"face_ort.png"中
import onnxruntime

ort_session = onnxruntime.InferenceSession("srcnn.onnx")
ort_inputs = {'input': input_img}
ort_output = ort_session.run(['output'], ort_inputs)[0]

ort_output = np.squeeze(ort_output, 0)
ort_output = np.clip(ort_output, 0, 255)
ort_output = np.transpose(ort_output, [1, 2, 0]).astype(np.uint8)
cv2.imwrite("face_ort.png", ort_output)

PSPNet(Pyramid Scene Parsing Network)是一种用于图像分割的深度学习模型,它在场景解析任务中表现突出,能够处理不同尺度的信息。PyTorch是一个广泛使用的深度学习框架,它提供了构建和训练复杂神经网络的工具。将PyTorch模型转换为ONNX(Open Neural Network Exchange)格式是一种常见做法,旨在实现模型在不同深度学习框架之间的兼容性,从而能够在不同的推理引擎上部署和执行。 要使用`pspnet-pytorch-master`模型进行ONNX推理,你需要遵循以下步骤: 1. **模型准备**:确保你已经安装了PyTorch,并且已经获取了`pspnet-pytorch-master`模型的代码和预训练权重。这通常涉及到克隆GitHub仓库并安装所需的依赖项。 2. **模型转换**:使用PyTorchONNX导出功能,将模型转换为ONNX格式。这需要在PyTorch中运行模型并捕获模型的输出,以生成ONNX模型文件。 3. **验证转换**:在转换模型后,你应该验证转换后的ONNX模型是否能够正确地执行推理,与原PyTorch模型的输出保持一致。 4. **ONNX推理**:一旦确认ONNX模型无误,就可以使用支持ONNX的推理引擎(如ONNX Runtime, TensorRT等)来进行高效的推理。 以下是一个简化的代码示例,展示了如何将PyTorch模型导出为ONNX格式: ```python import torch from pspnet import PSPNet # 假设你已经导入了PSPNet类 # 加载预训练的PSPNet模型 model = PSPNet() # 假设这里已经加载了预训练权重 model.eval() # 设置为评估模式 # 创建一个dummy输入,用于模型的前向传播,以便生成ONNX模型 dummy_input = torch.randn(1, 3, 475, 475) # 这里的维度可能需要根据实际模型调整 # 导出模型到ONNX torch.onnx.export(model, dummy_input, "pspnet.onnx", verbose=True, input_names=['input'], output_names=['output']) # 使用ONNX模型进行推理 import onnx import onnxruntime # 加载ONNX模型 onnx_model = onnx.load("pspnet.onnx") onnx.checker.check_model(onnx_model) # 使用ONNX Runtime进行推理 ort_session = onnxruntime.InferenceSession("pspnet.onnx") ort_inputs = {ort_session.get_inputs()[0].name: dummy_input.numpy()} ort_outs = ort_session.run(None, ort_inputs) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值