分类模型部署-ONNX

分类模型部署-ONNX

  • 0 引入:
  • 1 模型部署实战测试:
    • 1 安装配置环境:
    • 2 Pytorch图像分类模型转ONNX-ImageNet1000类
    • 3 推理引擎ONNX Runtime部署-预测单张图像:
  • 2 扩展阅读
  • 参考

0 引入:

在软件工程中,部署指把开发完毕的软件投入使用的过程,包括环境配置、软件安装等步骤。类似地,对于深度学习模型来说,模型部署指让训练好的模型在特定环境中运行的过程。相比于软件部署,模型部署会面临更多的难题:

  1. 运行模型所需的环境难以配置。深度学习模型通常是由一些框架编写,比如 PyTorch、TensorFlow。由于框架规模、依赖环境的限制,这些框架不适合在手机、开发板等生产环境中安装。
  2. 深度学习模型的结构通常比较庞大,需要大量的算力才能满足实时运行的需求。模型的运行效率需要优化。

因为这些难题的存在,模型部署不能靠简单的环境配置与安装完成。经过工业界和学术界数年的探索,模型部署有了一条流行的流水线:

为了让模型最终能够部署到某一环境上,开发者们可以使用任意一种深度学习框架来定义网络结构,并通过训练确定网络中的参数。之后,模型的结构和参数会被转换成一种只描述网络结构的中间表示,一些针对网络结构的优化会在中间表示上进行。最后,用面向硬件的高性能编程框架(如 CUDA,OpenCL)编写,能高效执行深度学习网络中算子的推理引擎会把中间表示转换成特定的文件格式,并在对应硬件平台上高效运行模型。
这一条流水线解决了模型部署中的两大问题:使用对接深度学习框架和推理引擎的中间表示,开发者不必担心如何在新环境中运行各个复杂的框架;通过中间表示的网络结构优化和推理引擎对运算的底层优化,模型的运算效率大幅提升。

1 模型部署实战测试:

这里以部署流水线: Pytorch-ONNX-ONNX Runtime/TensorRT 为流程,进行测试:
流程:分类模型,转成onnx,onnxRuntime部署;
这里以部署分类模型为例,参考同济子豪兄:

1 安装配置环境:

torch
torchvision
onnx
onnxruntime
numpy
pandas	
matplotlib
tqdm
opencv-python
pillow

2 Pytorch图像分类模型转ONNX-ImageNet1000类

把Pytorch预训练ImageNet图像分类模型,导出为ONNX格式,用于后续在推理引擎上部署。
导入工具包:

import torch
from torchvision import models# 有 GPU 就用 GPU,没有就用 CPU
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
print('device', device)

载入与训练pytorch图像分类模型:

model = models.resnet18(pretrained=True)
model = model.eval().to(device)

构建一个输入Tensor:

x = torch.randn(1, 3, 256, 256).to(device)

输入pytorch模型推理预测,获得1000个类别的预测结果:

output = model(x)
output.shape

torch.Size([1, 1000])

pytorch模型转onnx格式:

with torch.no_grad():torch.onnx.export(model,                       # 要转换的模型x,                           # 模型的任意一组输入'resnet18_imagenet.onnx',    # 导出的 ONNX 文件名opset_version=11,            # ONNX 算子集版本input_names=['input'],       # 输入 Tensor 的名称(自己起名字)output_names=['output']      # 输出 Tensor 的名称(自己起名字)) 

验证onnx模型导出成功:

import onnx# 读取 ONNX 模型
onnx_model = onnx.load('resnet18_imagenet.onnx')# 检查模型格式是否正确
onnx.checker.check_model(onnx_model)print('无报错,onnx模型载入成功')

以可读的形式打印计算图:

print(onnx.helper.printable_graph(onnx_model.graph))
graph main_graph (%input[FLOAT, 1x3x256x256]
) initializers (%fc.weight[FLOAT, 1000x512]%fc.bias[FLOAT, 1000]%onnx::Conv_193[FLOAT, 64x3x7x7]%onnx::Conv_194[FLOAT, 64]%onnx::Conv_196[FLOAT, 64x64x3x3]%onnx::Conv_197[FLOAT, 64]%onnx::Conv_199[FLOAT, 64x64x3x3]%onnx::Conv_200[FLOAT, 64]%onnx::Conv_202[FLOAT, 64x64x3x3]%onnx::Conv_203[FLOAT, 64]%onnx::Conv_205[FLOAT, 64x64x3x3]%onnx::Conv_206[FLOAT, 64]%onnx::Conv_208[FLOAT, 128x64x3x3]%onnx::Conv_209[FLOAT, 128]%onnx::Conv_211[FLOAT, 128x128x3x3]%onnx::Conv_212[FLOAT, 128]%onnx::Conv_214[FLOAT, 128x64x1x1]%onnx::Conv_215[FLOAT, 128]%onnx::Conv_217[FLOAT, 128x128x3x3]%onnx::Conv_218[FLOAT, 128]%onnx::Conv_220[FLOAT, 128x128x3x3]%onnx::Conv_221[FLOAT, 128]%onnx::Conv_223[FLOAT, 256x128x3x3]%onnx::Conv_224[FLOAT, 256]%onnx::Conv_226[FLOAT, 256x256x3x3]%onnx::Conv_227[FLOAT, 256]%onnx::Conv_229[FLOAT, 256x128x1x1]%onnx::Conv_230[FLOAT, 256]%onnx::Conv_232[FLOAT, 256x256x3x3]%onnx::Conv_233[FLOAT, 256]%onnx::Conv_235[FLOAT, 256x256x3x3]%onnx::Conv_236[FLOAT, 256]%onnx::Conv_238[FLOAT, 512x256x3x3]%onnx::Conv_239[FLOAT, 512]%onnx::Conv_241[FLOAT, 512x512x3x3]%onnx::Conv_242[FLOAT, 512]%onnx::Conv_244[FLOAT, 512x256x1x1]%onnx::Conv_245[FLOAT, 512]%onnx::Conv_247[FLOAT, 512x512x3x3]%onnx::Conv_248[FLOAT, 512]%onnx::Conv_250[FLOAT, 512x512x3x3]%onnx::Conv_251[FLOAT, 512]
) 

也可以使用netron可视化模型结构:
image.png

3 推理引擎ONNX Runtime部署-预测单张图像:

使用推理引擎,ONNX Runtime,读取 ONNX 格式的模型文件,对单张图像文件进行预测。

应用场景:
以下代码在需要部署的硬件上运行(本地PC、嵌入式开发板、树莓派、Jetson Nano、服务器)
只需把`onnx`模型文件发到部署硬件上,并安装 ONNX Runtime 环境,用下面几行代码就可以运行模型了。

导入工具包:

import onnxruntime
import numpy as np
import torch
import torch.nn.functional as Fimport pandas as pd

载入Onnx模型,获取 ONNX Runtime 推理器

ort_session = onnxruntime.InferenceSession('resnet18_imagenet.onnx')

构造随机输入,获取输出结果:

x = torch.randn(1, 3, 256, 256).numpy()
x.shape
# onnx runtime 输入
ort_inputs = {'input': x}# onnx runtime 输出
ort_output = ort_session.run(['output'], ort_inputs)[0]

注意,输入输出张量的名称需要和 torch.onnx.export 中设置的输入输出名对应

ort_output.shape

(1, 3, 256, 256)
(1, 1000)

载入真实图片预处理;

img_path = 'banana1.jpg'# 用 pillow 载入
from PIL import Image
img_pil = Image.open(img_path)from torchvision import transforms#预处理
# 测试集图像预处理-RCTN:缩放裁剪、转 Tensor、归一化
test_transform = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(256),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])input_img = test_transform(img_pil)
input_img.shape
input_tensor = input_img.unsqueeze(0).numpy()
input_tensor.shape

推理预测:

# ONNX Runtime 输入
ort_inputs = {'input': input_tensor}# ONNX Runtime 输出
pred_logits = ort_session.run(['output'], ort_inputs)[0]
pred_logits = torch.tensor(pred_logits)
pred_logits.shape
# 对 logit 分数做 softmax 运算,得到置信度概率
pred_softmax = F.softmax(pred_logits, dim=1) 
pred_softmax.shape

解析结果:将数字映射到物品种类上:

# 取置信度最高的前 n 个结果
n = 3
top_n = torch.topk(pred_softmax, n)
top_n# 预测类别
pred_ids = top_n.indices.numpy()[0]
pred_ids# 预测置信度
confs = top_n.values.numpy()[0]

载入类别ID和类别名称对应关系:

df = pd.read_csv('imagenet_class_index.csv')
idx_to_labels = {}
for idx, row in df.iterrows():idx_to_labels[row['ID']] = row['class']   # 英文
#     idx_to_labels[row['ID']] = row['Chinese'] # 中文

打印预测结果:

for i in range(n):class_name = idx_to_labels[pred_ids[i]] # 获取类别名称confidence = confs[i] * 100             # 获取置信度text = '{:<20} {:>.3f}'.format(class_name, confidence)print(text)

image.png
imagenet_class_index.csv

2 扩展阅读

ONNX主页: https://onnx.ai
ONNX Github主页: https://github.com/onnx/onnx
ONNX支持的深度学习框架:https://onnx.ai/supported-tools.html
ONNX支持的计算平台:https://onnx.ai/supported-tools.html
ONNX算子:https://onnx.ai/onnx/operators
模型在线可视化网站 Netron:https://netron.app
Netron视频教程:https://www.bilibili.com/video/BV1TV4y1P7AP

周奕帆博客:
模型部署入门教程(一):模型部署简介
https://zhuanlan.zhihu.com/p/477743341
模型部署入门教程(二):解决模型部署中的难题
https://zhuanlan.zhihu.com/p/479290520
模型部署入门教程(三):PyTorch 转 ONNX 详解
https://zhuanlan.zhihu.com/p/498425043

参考

https://mmdeploy.readthedocs.io/zh-cn/latest/tutorial/01_introduction_to_model_deployment.html

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

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

相关文章

kubeadm快速部署K8S

目录 一、kubeadm安装K8S 1.1 环境准备 1.2 初始化配置 1.3 所有节点安装docker 1.3.1 安装依赖环境和docker 1.3.2 定义docker 配置文件 1.3.3 重启并开机自启docker 1.3.4 查看docker 是否配置成功 1.4 master、node01 、node02安装kubeadm&#xff0c;kubelet和kub…

2.线上论坛项目

一、项目介绍 线上论坛 相关技术&#xff1a;SpringBootSpringMvcMybatisMysqlSwagger项目简介&#xff1a;本项目是一个功能丰富的线上论坛&#xff0c;用户可编辑、发布、删除帖子&#xff0c;并评论、点赞。帖子按版块分类&#xff0c;方便查找。同时&#xff0c;用户可以…

图像处理:Python使用OpenCV进行图像锐化 (非锐化掩模、拉普拉斯滤波器)

文章目录 非锐化掩模 (Unsharp Masking)拉普拉斯滤波器 (Laplacian Filter)效果对比总结 在图像处理中&#xff0c;锐化操作用于增强图像的边缘和细节&#xff0c;使图像看起来更清晰。常见的图像锐化方法包括非锐化掩模&#xff08;Unsharp Masking&#xff09;和拉普拉斯滤波…

轻松实现H5页面下拉刷新:滑动触发、高度提示与数据刷新全攻略

前段时间在做小程序到H5的迁移&#xff0c;其中小程序中下拉刷新的功能引起了产品的注意。他说到&#xff0c;哎&#xff0c;我们迁移后的H5页面怎么没有下拉刷新&#xff0c;于是乎&#xff0c;我就急忙将这部分的内容给填上。 本来是计划使用成熟的组件库来实现&#xff0c;…

Windows修改CMD窗口编码为UTF-8

windows下的cmd的默认编码是GBK编码&#xff0c;有时可能造成乱码问题&#xff0c;下面是我找到的两种更换编码方式为UTF-8的方法。 1、临时修改 &#xff08;1&#xff09;先进入cmd命令窗口&#xff08;快捷键win键R&#xff09; &#xff08;2&#xff09;直接输入“chcp…

畅想智能美颜工具的未来:美颜SDK技术详解

美颜SDK作为技术的核心&#xff0c;承载了美颜工具的实现和创新。本篇文章&#xff0c;小编将深入探讨美颜SDK技术的细节。 一、技术原理 美颜SDK是一种软件开发工具包&#xff0c;集成了一系列图像处理算法和技术&#xff0c;旨在实现对照片和视频中人物的实时美化。其主要技…

逢3必过报数游戏-第13届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第84讲。 逢3必过报数游戏&…

c++_0基础_讲解7 练习

这一讲我为大家准备了几道题目&#xff0c;大家试着独自做一下&#xff08;可能来自不同网站&#xff09; 整数大小比较 - 洛谷 题目描述 输入两个整数&#xff0c;比较它们的大小。若 x>yx>y &#xff0c;输出 > &#xff1b;若 xyxy &#xff0c;输出 &#xff…

---异常---

我们在运行程序时总遇到各种与报错&#xff0c;数组越界&#xff0c;空指针的引用&#xff0c;这些在java中都称为异常 对于不同的错误都具有一个与他对应的异常类来秒描述 这是对于数组越界这个类里有的方法&#xff0c;这些是描述异常的 在java中有一个完整的描述异常的类的…

嵌入式数据库的一般架构

嵌入式数据库的架构与应用对象紧密相关&#xff0c;其架构是以内存、文件和网络等三种方式为主。 1.基于内存的数据库系统 基于内存的数据库系统中比较典型的产品是每个McObject公司的eXtremeDB嵌入式数据库&#xff0c;2013年3月推出5.0版&#xff0c;它采用内存数据结构&…

2024年黑龙江省特岗招聘公告出了!!!

2024年黑龙江省农村义务教育阶段学校特设岗位教师招聘822人公告 (1、网上报名 时间&#xff1a;6月17日9&#xff1a;00—6月22日17&#xff1a;00。 网址&#xff1a; https&#xff1a;//sfyz.hljea.org.cn&#xff1a;7006/tgjs 2、网上资格审查 资格审查时间&#xff1a;6月…

英语学习笔记36——Where ... ?

Where … ? ……在哪里&#xff1f; 词汇 Vocabulary beside prep. 在……旁边 同义词&#xff1a; near by 构成&#xff1a;be side side n. 边 搭配&#xff1a;side walk 人行道 例句&#xff1a;Bobby在我旁边。    Bobby is beside me. off prep. 离开&#xff…

C/C++中内存开辟与柔性数组

C/C中内存的开辟 在C中&#xff0c;我们都知道有三个区&#xff1a; 1. 栈区&#xff08;stack&#xff09;&#xff1a;在执行函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结 束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指…

使用itextPDF实现PDF电子公章工具类

一、制作公章 在线网站&#xff1a;印章生成器 - Kalvin在线工具 (kalvinbg.cn) 然后对公章进行下载保存 盖章图片&#xff1a; 二、生成数字签名 2.1&#xff1a; java工具keytool生成p12数字证书文件 Keytool是用于管理和证书的工具&#xff0c;位于%JAVA_HOME%/bin目录。…

代码随想录——组合总数Ⅲ(Leetcode216)

题目链接 回溯 class Solution {List<List<Integer>> res new ArrayList<List<Integer>>();List<Integer> list new ArrayList<Integer>();public List<List<Integer>> combinationSum3(int k, int n) {backtracking(k, …

揭秘最强气象武器的库,SPEI-Python不可思议之处.

spei-python是一个专门用于计算标准化降水蒸散指数&#xff08;Standardized Precipitation Evapotranspiration Index,SPEI&#xff09;的Python库.SPEI是一种综合考虑降水和潜在蒸散发的干旱指数,用于评估干旱的严重程度和持续时间. 安装 ## 可以使用 pip 来安装 spei-pyth…

【EtherCAT电机板】CiA402增加cst模式

在EtherCAT电机板上实现cst功能&#xff0c;在xml中增加cst相关pdo&#xff0c;在402程序增加cst模式。 1、XML配置修改 cst模式需要用到目标转矩和反馈实际转矩PDO&#xff0c;结合CiA402手册&#xff0c;这两个PDO对应的索引号分别为&#xff1a;0x6071&#xff08;Target t…

基于微信小程序的在线答题小程序设计与实现

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

JavaFX VBox

VBox布局将子节点堆叠在垂直列中。新添加的子节点被放置在上一个子节点的下面。默认情况下&#xff0c;VBox尊重子节点的首选宽度和高度。 当父节点不可调整大小时&#xff0c;例如Group节点&#xff0c;最大垂直列的宽度基于具有最大优选宽度的节点。 默认情况下&#xff0c;…

分数布朗运动FBM期权定价模型

BS定价模型和蒙特卡洛模拟期权定价方法都 假设标的资产价格的对数服从布朗运动 &#xff0e; 但是实际 的金融市场中标的资产价格运动过程具有 “尖峰厚尾 ” 现象 &#xff0c; 运用分数布朗运动 &#xff08;FBM &#xff09;来刻画标的资产 价格的运动过程可能更加合适。 …