使用onnx和onnxruntime完成模型部署

news2025/2/22 13:31:50

模型部署定义

深度学习模型部署是指训练好的模型在特定环境中运行的过程。

模型部署的流水线如下:

  1. 使用任意一种深度学习框架来定义网络结构并训练模型
  2. 训练好的模型的网络结构和参数会被转换成一种只描述网络结构的中间表示(如,onnx、torchscript等),一些针对模型的优化会在中间表示上进行(如,onnxsimplify,读取onnx模型,将一些需要动态计算的值转换为静态值,从而对模型进行简化;onnx节点裁剪等)
  3. 用面向硬件的高性能编程框架(如,CUDA,OpenCL等)编写能够高效执行深度学习算子的推理引擎,把中间表示转换成特定的文件格式,并在对应硬件平台上高效运行模型

模型部署示例

1、创建模型部署的虚拟环境

conda create -n modeldeploy python=3.8 -y
conda activate modeldeploy

2、安装模型部署需要用到的第三方库

conda install pytorch torchvision cpuonly -c pytorch
pip install onnxruntime onnx opencv-python

3、定义超分辨率SRCNN的pytorch模型,并对模型进行测试

"""
该代码来自: https://zhuanlan.zhihu.com/p/477743341
"""

import cv2
import numpy as np
import torch
import torch.nn as 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


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)
input_img = cv2.resize(input_img, [256, 256])

# 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()

# 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)
 
# Show image 
cv2.imwrite("face_torch.png", torch_output)

4、pth模型转onnx模型

# convert pth to onnx
x = torch.randn(1, 3, 256, 256)
with torch.no_grad():
    # opset_version为onnx算子集的版本, 版本越高, 支持的算子越多
    torch.onnx.export(model, x, "srcnn.onnx", opset_version=11, 
                    input_names=['input'], output_names=['output'])

5、检验转换后的onnx模型文件是否正确

# verify
import onnx
onnx_model = onnx.load("srcnn.onnx") 
try: 
    onnx.checker.check_model(onnx_model) 
except Exception: 
    print("Model incorrect") 
else: 
    print("Model correct")


"""
================ Diagnostic Run torch.onnx.export version 2.0.1 ================
verbose: False, log level: Level.ERROR
======================= 0 NONE 0 NOTE 0 WARNING 0 ERROR ========================

Model correct
"""

6、利用onnxruntime推理引擎推理onnx模型

# inference
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)
print(torch.equal(torch.from_numpy(ort_output), torch.from_numpy(torch_output)))

参考文章

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Shiro 初识

1,了解Shiro Shiro是一个安全框架,主要用于用户认证,访问授权,会话管理,数据加密 2,实践 2.1 创建文件 这个例子没有链接数据库, 所以需要在resources下创建文件shiro.ini shiro.ini内容&am…

Vant源码解析(三)van-stepper步进器

先说下自己的开发思路,然后在对照下vant组件的思路,来查找下自己的不足。 这个步进器有加和减的功能,还有输入的功能,限制最小和最大的功能。 我理解的Vant组件的思路 点击事件都是onTap,根据变量进行判断是加还是减,数…

vuecli5.x 配置图片输出为base64

解释:webpack的默认配置是小于一定的文件大小就要将图片转为base64, 所以尽量将这个阈值调大你的图片就可以转为base64; 当然这种做法不好, 会导致代码文件变大, 不过为了满足需求也没得办法。这年头大家都用 vite 了, 网上没有 vuecli5.x 这方面的记录, 写篇文章记…

腾讯内推 | 互联网大厂内推

分享 WLB、大厂内推,面经、热点新闻,可内推公司90,累计帮助6000 靠谱的内推君 专注于WLB、大厂精选内推,助力每位粉丝拿到满意的Offer! 公司简述 腾讯以技术丰富互联网用户的生活。通过通信及社交平台微信和 QQ 促…

单模光模块和多模光模块有何区别,如何选择?

随着数据中心和5G应用的高速发展,光模块渐渐被越来越多的人所熟知,也得到了广泛应用。我们都知道,光模块可以根据参数类型来区分,如我们经常提到的单模光模块和多模光模块。那你知道单模光模块和多模光模块中的单模和多模分别代表…

基于物联网、移动互联网、一物一码等技术开发的质量溯源系统源码

什么是溯源系统? 溯源系统是物联网、移动互联网、一物一码等技术的整合应用。在产品生产过程中在重要环节可采集产品数据信息并形成产品溯源档案。从而形成产品从原料、生产加工、质量检测、物流运输等环节的信息监控。 溯源系统技术架构 技术架构:spring bootmy…

服务器数据库的防护策略与360后缀勒索病毒解密方法

在当今数字化时代,服务器数据安全面临着越来越多的挑战。其中,勒索病毒攻击就是一种常见的网络威胁之一,最近,很多的公司服务器数据库遭到了360后缀勒索病毒攻击,导致许多重要数据无法读取,一旦企业的数据库…

vue3和tauri直接下载Binary 数组的二进制文件内容到本地

通过发送url请求,直接获取到一个文件的Binary 数组内容,然后通过tauri的api:writeBinaryFile保存文件到本地电脑。 发送请求的时候,要加上响应类型:responseType: ResponseType.Binary 然后等返回的响应内容&#xf…

权限系统就该这么设计,稳的一批!

对于后台管理系统来说,权限功能已经是必不可少的一部分了。如果你用过一些快速开发脚手架,你会发现很多都直接集成了权限功能。把权限功能做成一个通用功能,非常有利于代码的复用。今天就以我的mall电商实战项目为例,来聊聊权限系…

防止重复请求,防止重复点击,解决:使用分布式锁,redisson,setnx简单实例

防止重复请求,解决:使用分布式锁,redisson,简单实例 通常情况下:synchronize在单机下是可以的,在分布式下不适用,nginx做分发到了不同的服务器后,不同的jvm是锁不住的,这…

【C语言进阶篇】常见动态内存分配的这六个错误你必须避免!

🎬 鸽芷咕:个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言💬 常见的动态内存错误1️⃣ 对NULL指针的解引用操作⌨️ 错误原因💻 解决方法&…

MonoDTR Monocular 3D Object Detection with Depth-Aware Transformer 论文学习

论文链接:MonoDTR: Monocular 3D Object Detection with Depth-Aware Transformer 1. 解决了什么问题? 单目 3D 目标检测对于自动驾驶很重要,也很有挑战性。 现有的一些方法通过深度预测网络得到深度信息,然后辅助 3D 检测&…

总结930

之前本打算每天学12h,践行了一周,一天最多也就学11.5h,在时间利用上感觉已经趋于饱和的了。 这个时候,时间统计法应该能发挥它应有的作用了,但就算详细记录每日时间支出,也不能从根本上解决问题。 一味的进行时间上的…

学习记录——语义分割、实时分割和全景分割的区别、几个Norm的区别

语义分割、实时分割和全景分割区别? semantic segmentation(语义分割) 通常意义上的目标分割指的就是语义分割,图像语义分割,简而言之就是对一张图片上的所有像素点进行分类。   语义分割(下图左&#…

护网实训场景二-

首先攻击者入侵到了web服务器,构建一个socks5代理,去入侵办公区,通过办公区在构建二层代理去拿下核心区就这么一个流程。 攻击:先开始扫描 防御:导入流量包,在分析平台去看告警 这就是一个很明显的目录扫描…

Linux 部署Vue+Spring Boot项目

部署Vue Spring Boot项目 安装redis wget http://download.redis.io/releases/redis-4.0.8.tar.gz tar -zxvf redis-4.0.8.tar.gz yum install gcc-c make make install如果出现下面的问题: yum install tcl make testredis-server myconifg/redis.conf输入客户端…

Vue 安装 Vue-router 路由安装以及使用

vue-router 是 Vue 的一个插件库,适用于构建单页面应用。 单页面应用:整个应用中只有一个完整的页面,切换页面就是替换页面中的内容。 工作原理:当浏览器的路径发生改变时,路由器会自动显示路径所对应的组件。 嵌套…

【主轴线】不规则多边形主轴线计算与显示

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 不规则多边形的主轴线 计算方法与显示方法 1. 正文 主轴线的计算与显示 首先,我们计算多边形的中心点,然后将顶点坐标相对于中…

经典文献阅读之--DAMS-LIO(基于iEKF的轻量级LiDAR惯性里程计)

0. 简介 融合方案是多传感器融合方法的关键,多传感器融合方法是地下矿山和行星表面等复杂极端环境下状态估计的最有前途的解决方案。本文提出了一种基于iEKF的轻量级LiDAR惯性里程计系统,该系统采用可感知退化的模块化传感器融合管道,仅在检…

C语言小项目——通讯录高阶(文件管理版)

通讯录初阶: 点这里 通讯录中阶: 点这里 文件管理版本改进之处通讯录初始化退出通讯录并保存 完整代码contact.hcontact.ctest.c 文件管理版本改进之处 通讯录初始化 contact.c 退出通讯录并保存 test.c contact.c contact.h 完整代码 contact.h #pragma once#include&l…