pytorch模型转ONNX、并进行比较推理

简介: pytorch模型转ONNX、并进行比较推理

13.png

pytorch模型转ONNX


概述


ONNX(Open Neural Network Exchange)是一种开放式的深度学习模型交换格式,旨在促进不同深度学习框架之间的互操作性。通过将深度学习模型转换为ONNX格式,可以将其从一个深度学习框架移植到另一个框架中,而无需重新训练模型或手动重新实现模型结构。


ONNX是由微软和Facebook于2017年联合发布的,目前得到了众多公司和社区的支持和贡献。ONNX格式支持多种深度学习模型类型,包括卷积神经网络(CNN)、循环神经网络(RNN)和变换器(Transformer)等。


在使用ONNX时,通常需要两个步骤:模型的导出和模型的导入。首先,将模型从一个深度学习框架中导出到ONNX格式。导出后,可以使用ONNX运行时(ONNX Runtime)或其他支持ONNX格式的深度学习框架将模型导入到所需的平台中进行推理。


在导出模型时,需要注意确保模型的兼容性。由于每个框架实现深度学习算法的方式不同,因此在转换模型时可能会出现一些限制或不兼容性。此外,由于ONNX不支持某些框架特有的操作或层,因此在导出模型时可能需要进行一些自定义操作或调整模型结构,以便使模型兼容ONNX格式。


总的来说,ONNX是一个非常有用的工具,可以简化深度学习模型的转换和部署过程,促进不同框架之间的互操作性和合作。


PT转ONNX

import torch
import onnx
import onnxruntime
from efficient_net import build_model
# Step 1: 加载 PyTorch 模型
# model = EfficientNet.from_pretrained('efficientnet-b0')
model = build_model(model_name="efficientnet-b2",weights_path="ef_classify/models/best.pt", num_classes=2)
model.eval()
# Step 2: 将模型转换为 ONNX 格式(包含动态批次)
output_path = "efficientnet-b2.onnx"  # ONNX 模型保存路径
# 导出 ONNX 模型
dummy_input = torch.randn(1, 3, 260, 260)
dynamic_axes = {'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}}
torch.onnx.export(model, dummy_input, output_path, verbose=True, input_names=['input'], output_names=['output'],
                  dynamic_axes=dynamic_axes)

比较PT和ONNX


要比较转换后的ONNX模型和原始的PyTorch模型之间的差异,可以使用ONNX Runtime工具包。


1.加载模型:在使用ONNX Runtime进行模型比较之前,您需要加载PyTorch模型和转换后的ONNX模型。您可以使用PyTorch或ONNX Runtime加载模型。

# 加载 PyTorch 模型
import torch
from efficient_net import build_model
# model_pt = torch.load('model.pt')
model_pt = build_model(model_name="efficientnet-b2",weights_path="ef_classify/models/best.pt", num_classes=2)
# 加载转换后的 ONNX 模型
import onnxruntime as ort
model_onnx = ort.InferenceSession('efficientnet-b2.onnx',providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])

2.输入数据:为了比较模型,需要提供相同的输入数据。可以生成一些随机数据并将其提供给模型进行比较。

import numpy as np
input_shape = (1, 3, 260, 260)
input_data = np.random.random(input_shape).astype(np.float32)

3.推理和比较:使用PyTorch和ONNX Runtime对相同的输入数据进行推理并比较输出结果。如果输出相同,则说明两个模型在这些输入数据上是等价的。

# 使用 PyTorch 进行推理
model_pt.eval()
with torch.no_grad():
    output_pt = model_pt(torch.tensor(input_data))
# 使用 ONNX Runtime 进行推理
output_onnx = model_onnx.run(None, {'input': input_data})[0]
# 比较输出结果
if np.allclose(output_pt.numpy(), output_onnx, rtol=1e-3, atol=1e-5):
    print("模型输出相同!")
else:
    print("模型输出不同!")

使用这种方法,可以比较转换后的ONNX模型和原始的PyTorch模型在相同输入数据上的输出结果是否相同,从而评估模型的差距。


ONNX批量推理图片


在下面的代码中,我们使用了一个批处理的方式来进行推理。我们首先获取了所有图像文件的路径,然后将其分成了多个大小为batch_size的批次进行推理。在每个批次中,我们将多张图像一次性输入模型进行推理,并将输出结果保存在outputs列表中。最后,我们将所有输出结果合并并输出每个图像的预测结果。

import os
import cv2
import numpy as np
import onnxruntime as ort
# 加载ONNX模型
model_path = "efficientnet-b2.onnx"
session =  ort.InferenceSession(model_path,providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
input_name = session.get_inputs()[0].name
# 获取所有图像文件的路径
images_path = "ef_classify/dataset/dog"
image_paths = [os.path.join(images_path, f) for f in os.listdir(images_path) if os.path.isfile(os.path.join(images_path, f))]
# 批量读取、预处理和推理图像
batch_size = 8
outputs = []
for i in range(0, len(image_paths), batch_size):
    batch_images = []
    for image_path in image_paths[i:i+batch_size]:
        # 读取图像并进行预处理
        image = cv2.imread(image_path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = cv2.resize(image, (260, 260))
        img = image.astype(np.float32)
        img /= 255.0
        img_mean = (0.485,0.456,0.406)
        img_std = (0.229,0.224,0.225)
        img = img - img_mean
        img = (img/img_std)
        image = img.transpose((2, 0, 1))
        image = np.expand_dims(image, axis=0).astype(np.float32)
        batch_images.append(image)
    # 进行推理并保存输出结果
    batch_images = np.concatenate(batch_images, axis=0)
    batch_outputs = session.run(None, {input_name: batch_images})
    outputs.append(batch_outputs[0])
# 将所有输出结果合并并输出每个图像的预测结果
outputs = np.concatenate(outputs, axis=0)
for i, image_path in enumerate(image_paths):
    predicted_class = np.argmax(outputs[i])
    print(f"Image: {image_path} - Predicted Class: {predicted_class}")
目录
相关文章
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】26.卷积神经网络之AlexNet模型介绍及其Pytorch实现【含完整代码】
【从零开始学习深度学习】26.卷积神经网络之AlexNet模型介绍及其Pytorch实现【含完整代码】
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】28.卷积神经网络之NiN模型介绍及其Pytorch实现【含完整代码】
【从零开始学习深度学习】28.卷积神经网络之NiN模型介绍及其Pytorch实现【含完整代码】
|
1月前
|
机器学习/深度学习 并行计算 PyTorch
使用PyTorch Profiler进行模型性能分析,改善并加速PyTorch训练
加速机器学习模型训练是工程师的关键需求。PyTorch Profiler提供了一种分析工具,用于测量CPU和CUDA时间,以及内存使用情况。通过在训练代码中嵌入分析器并使用tensorboard查看结果,工程师可以识别性能瓶颈。Profiler的`record_function`功能允许为特定操作命名,便于跟踪。优化策略包括使用FlashAttention或FSDP减少内存使用,以及通过torch.compile提升速度。监控CUDA内核执行和内存分配,尤其是避免频繁的cudaMalloc,能有效提升GPU效率。内存历史记录分析有助于检测内存泄漏和优化批处理大小。
55 1
|
12天前
|
机器学习/深度学习 数据采集 PyTorch
使用 PyTorch 创建的多步时间序列预测的 Encoder-Decoder 模型
本文提供了一个用于解决 Kaggle 时间序列预测任务的 encoder-decoder 模型,并介绍了获得前 10% 结果所涉及的步骤。
13 0
|
23天前
|
机器学习/深度学习 算法 PyTorch
Pytorch实现线性回归模型
在机器学习和深度学习领域,线性回归是一种基本且广泛应用的算法,它简单易懂但功能强大,常作为更复杂模型的基础。使用PyTorch实现线性回归,不仅帮助初学者理解模型概念,还为探索高级模型奠定了基础。代码示例中,`creat_data()` 函数生成线性回归数据,包括噪声,`linear_regression()` 定义了线性模型,`square_loss()` 计算损失,而 `sgd()` 实现了梯度下降优化。
|
23天前
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch中的模型创建(一)
最全最详细的PyTorch神经网络创建
|
23天前
|
机器学习/深度学习 PyTorch 算法框架/工具
|
2天前
|
机器学习/深度学习 PyTorch TensorFlow
在深度学习中,数据增强是一种常用的技术,用于通过增加训练数据的多样性来提高模型的泛化能力。`albumentations`是一个强大的Python库,用于图像增强,支持多种图像变换操作,并且可以与深度学习框架(如PyTorch、TensorFlow等)无缝集成。
在深度学习中,数据增强是一种常用的技术,用于通过增加训练数据的多样性来提高模型的泛化能力。`albumentations`是一个强大的Python库,用于图像增强,支持多种图像变换操作,并且可以与深度学习框架(如PyTorch、TensorFlow等)无缝集成。
8 0
|
1月前
|
机器学习/深度学习 人工智能 PyTorch
人工智能平台PAI产品使用合集之Alink是否加载预训练好的pytorch模型
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】27.卷积神经网络之VGG11模型介绍及其Pytorch实现【含完整代码】
【从零开始学习深度学习】27.卷积神经网络之VGG11模型介绍及其Pytorch实现【含完整代码】