您现在的位置是:首页 > 技术教程 正文

深度学习-Python调用ONNX模型

admin 阅读: 2024-03-22
后台-插件-广告管理-内容页头部广告(手机)

目录

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模型使用流程

ONNX(Open Neural Network Exchange)是一种开放的、跨平台的深度学习模型格式和编译器,可以帮助用户在不同的深度学习框架中转换和部署模型。下面介绍ONNX如何使用的流程:

  1. 导出模型:在训练好深度学习模型后,通过ONNX的支持的框架,比如PyTorch、TensorFlow等将模型导出为ONNX格式。

  2. 加载模型:使用ONNX的支持库,比如ONNX Runtime,加载ONNX文件格式的模型。

  3. 部署模型:通过ONNX Runtime在不同的硬件设备上运行模型,支持常见的CPU、GPU、FPGA等。

  4. 进行推理:将输入数据加载到模型中,进行推理或分类任务,输出结果。

ONNX还有其他的特点,比如具有可扩展性、良好的跨平台支持、对多种硬件设备的支持等。因此,ONNX是一种强大的深度学习模型转换和部署工具,可以大大加速深度学习模型的开发和部署过程。

获取ONNX模型方法

获取ONNX模型有以下几种方法:

        1. 使用ONNX标准工具导出已有的深度学习模型

许多深度学习框架都支持直接导出ONNX格式的模型,如PyTorch、TensorFlow、Keras等。可参考相应框架的文档,使用ONNX标准工具将模型导出为ONNX格式。

        2. 使用第三方工具转换

也可以使用一些第三方工具将已有的模型进行转换,例如mmcv中的convert_to_onnx.py工具。

        3. 手动编写ONNX模型

如果没有原始模型或无法导出,则需要手动编写ONNX模型。ONNX模型由计算图和模型参数组成。计算图用于定义模型结构和计算流程,可以使用ONNX工具或第三方工具进行编写,也可以手动编写。模型参数用于定义模型权重,可以使用Python脚本或其他工具进行生成或导入。

总之,获取ONNX模型的方法取决于具体情况,不同场景下合适的方法也会有所不同。

使用ONNX模型

手动编写ONNX模型

手动编写ONNX模型需要了解ONNX模型的结构和语法,以及具体深度学习框架的计算图结构和权重参数格式。

以下是一个手动编写的简单ONNX模型例子,用于对一维张量进行线性变换和ReLU激活:

  1. import onnx
  2. import numpy as np
  3. from onnx import numpy_helper
  4. from onnx import helper
  5. # 定义输入张量
  6. input_tensor = helper.make_tensor_value_info('input', onnx.TensorProto.FLOAT, [1, 10])
  7. # 定义权重张量
  8. weight = np.random.rand(10, 5).astype(np.float32)
  9. weight_initializer = numpy_helper.from_array(weight, 'weight')
  10. # 定义偏置张量
  11. bias = np.random.rand(5).astype(np.float32)
  12. bias_initializer = numpy_helper.from_array(bias, 'bias')
  13. # 定义节点1:矩阵乘法
  14. matmul_node = helper.make_node(
  15. 'MatMul',
  16. inputs=['input', 'weight'],
  17. outputs=['matmul_output']
  18. )
  19. # 定义节点2:加法
  20. add_node = helper.make_node(
  21. 'Add',
  22. inputs=['matmul_output', 'bias'],
  23. outputs=['add_output']
  24. )
  25. # 定义节点3:ReLU激活
  26. relu_node = helper.make_node(
  27. 'Relu',
  28. inputs=['add_output'],
  29. outputs=['output']
  30. )
  31. # 定义计算图
  32. graph_def = helper.make_graph(
  33. [matmul_node, add_node, relu_node],
  34. 'test-model',
  35. [input_tensor],
  36. [helper.make_tensor_value_info('output', onnx.TensorProto.FLOAT, [1, 5])],
  37. initializer=[weight_initializer, bias_initializer]
  38. )
  39. # 定义模型
  40. model_def = helper.make_model(
  41. graph_def,
  42. producer_name='my-model',
  43. opset_imports=[helper.make_opsetid('', 12)]
  44. )
  45. # 保存模型
  46. onnx.save(model_def, 'test-model.onnx')

此例中,通过手动定义输入张量、权重张量、偏置张量和节点(矩阵乘法、加法、ReLU激活)构建了一个简单的计算图,并通过ONNX工具生成了ONNX格式的模型文件test-model.onnx。可以使用ONNX工具或特定框架工具加载此模型进行推理。

Python调用ONNX模型

下面以使用Python调用ONNX模型为例子,具体步骤如下:

  1. 安装ONNX Runtime库
  2. 加载ONNX模型
  3. 准备输入数据
  4. 进行推理
  1. import onnxruntime
  2. import numpy as np
  3. import onnxruntime as ort
  4. model_path = 'test-model.onnx'
  5. providers = ['CPUExecutionProvider']
  6. ort_session = ort.InferenceSession(model_path, providers=providers)
  7. # ort_session = onnxruntime.InferenceSession('test-model.onnx', providers=['CPUExecutionProvider', 'CUDAExecutionProvider'])
  8. batch_size = 1
  9. input_size = 10 # set input size to 10
  10. input_data = np.random.rand(batch_size, input_size).astype(np.float32)
  11. input_data = input_data.reshape(batch_size, input_size) # reshape input_data to (batch_size, 10)
  12. # batch_size = 1
  13. # input_size = 784 # assuming you have a model that takes 784 inputs
  14. #
  15. # input_data = np.random.rand(batch_size, input_size).astype(np.float32)
  16. output = ort_session.run(None, {'input': input_data})[0]
  17. print(output)

执行结果:

[[2.5079055 3.4431007 2.5739892 2.332235  1.9329181]]

在这个例子中,我们使用Python调用ONNX Runtime库来加载ONNX模型,并使用随机生成的输入数据进行推理。在ONNX模型的输入中,我们以字典的形式传递输入数据。推理的结果是一个输出数组,这是由ONNX模型定义的。

这就是Python调用深度学习模型ONNX的基本步骤,可以根据具体的模型和任务,在此基础上进行调整和扩展。

常见错误

错误raise ValueError...

raise ValueError( ValueError: This ORT build has ['AzureExecutionProvider', 'CPUExecutionProvider'] enabled. Since ORT 1.9, you are required to explicitly set the providers parameter when instantiating InferenceSession. For example, onnxruntime.InferenceSession(..., providers=['AzureExecutionProvider', 'CPUExecutionProvider'], ...) 解决方法

该错误是由于在ORT 1.9版本中,调用InferenceSession时必须显式地设置providers参数来指定要使用的执行提供程序,否则会引发此错误。

要解决此错误,您需要在调用InferenceSession时设置providers参数。例如,如果您要使用CPUExecutionProvider和CUDAExecutionProvider,请按以下方式调用InferenceSession:

  1. import onnxruntime
  2. session = onnxruntime.InferenceSession('model.onnx', providers=['CPUExecutionProvider', 'CUDAExecutionProvider'])

在这里,我们将providers参数设置为包含CPUExecutionProvider和CUDAExecutionProvider的列表。根据您的需求,您可以选择其他ExecutionProvider。

请注意,如果您在调用InferenceSession时不设置providers参数,将会发生上述错误,即使您在构建模型时已经定义了ExecutionProvider。

错误:Load model model.onnx failed

onnxruntime.capi.onnxruntime_pybind11_state.NoSuchFile: [ONNXRuntimeError] : 3 : NO_SUCHFILE : Load model from model.onnx failed:Load model model.onnx failed. File doesn't exist

该错误提示 ONNXRuntimeError:3:NO_SUCHFILE,是由于onnxruntime无法在指定路径中找到模型文件model.onnx,因此无法加载模型。

要解决此错误,您需要检查以下几点:

  1. 检查您提供的文件路径是否正确。

    请确保您提供的文件路径是正确的,并且包含文件名和后缀名,例如'model.onnx'。

  2. 检查文件名是否正确。

    请确保文件名拼写正确,并且大小写正确。

  3. 检查文件是否存在。

    请确保指定路径中包含该文件。您可以通过在Python中运行以下代码进行检查:

    1. import os.path
    2. model_path = 'model.onnx'
    3. exists = os.path.isfile(model_path)
    4. if not exists:
    5. print('Model file not found:', model_path)

  4. 检查文件路径是否有权限访问。

    如果您使用的是Windows,则可能需要以管理员身份运行命令提示符或PyCharm。如果您使用的是Linux或macOS,则需要检查文件路径是否有正确的权限。

通过以上步骤排查未能加载模型的原因,并进行相应的修正即可解决此错误。

错误:'CUDAExecutionProvider' is not in available provider

UserWarning: Specified provider 'CUDAExecutionProvider' is not in available provider names.Available providers: 'AzureExecutionProvider, CPUExecutionProvider' warnings.warn( Traceback (most recent call last): File "D:\code\AutoTest\common\onnx\testOnnx.py", line 13, in input_data = np.random.rand(batch_size, input_size).astype(np.float32) ^^^^^^^^^^ NameError: name 'batch_size' is not defined 解决方法

此错误具有两个独立的部分:

  1. UserWarning:Specified provider 'CUDAExecutionProvider' is not in available provider names。

    这意味着您正在尝试使用CUDAExecutionProvider,但是您的环境中可能没有安装或可用CUDAExecutionProvider。您可以尝试更改提供程序使用CPUExecutionProvider或AzureExecutionProvider。

    在您的代码中,您可以这样设置提供程序:

    1. import onnxruntime as rt
    2. providers = ['CPUExecutionProvider'] # or ['AzureExecutionProvider']
    3. session = rt.InferenceSession('model.onnx', providers)

  2. NameError:name 'batch_size' is not defined。

    这意味着您在代码中使用了“batch_size”变量,但是在代码的上下文中未定义该变量。请确保您已经定义了batch_size变量并赋予其正确的值。

    例如,您可以在代码中设置batch_size变量,如下所示:

    1. import numpy as np
    2. batch_size = 1
    3. input_size = 784 # assuming you have a model that takes 784 inputs
    4. input_data = np.random.rand(batch_size, input_size).astype(np.float32)

通过以上步骤排查未定义变量和可用提供程序的问题,并进行相应的修正即可解决此错误。

错误:ONNXRuntimeError

in run return self._sess.run(output_names, input_feed, run_options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: input for the following indices index: 1 Got: 784 Expected: 10 Please fix either the inputs or the model. 解决方法

此错误涉及到两个问题:

  1. UserWarning: Specified provider 'CUDAExecutionProvider' is not in available provider names。 Available providers: 'AzureExecutionProvider, CPUExecutionProvider'。

这个问题在前一个错误中已经解释过了。请参考之前的解决方法。

  1. InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: input for the following indices index: 1 Got: 784 Expected: 10 Please fix either the inputs or the model。

这个错误意味着您提供的输入张量形状不正确,或者模型中期望的输入形状与提供的输入形状不匹配。

在您给出的代码中,您正在尝试将一个形状为(batch_size, 784)的输入张量提供给模型,但是模型期望输入张量的形状为(batch_size, 10)。 您需要更改输入张量的形状,以便它符合模型的输入形状。

例如,如果您的模型期望的输入形状是(batch_size, 10),您可以将示例代码中的input_size变量设置为10。 然后您可以在生成随机输入数据时,将生成的随机数重塑为(batch_size, 10)形状的张量。

具体而言,您可以在代码中添加以下行,将input_size变量设置为10,并将input_data变量重塑为(batch_size, 10)张量:

  1. import numpy as np
  2. batch_size = 1
  3. input_size = 10 # set input size to 10
  4. input_data = np.random.rand(batch_size, input_size).astype(np.float32)
  5. input_data = input_data.reshape(batch_size, input_size) # reshape input_data to (batch_size, 10)

这样,您就可以使用正确形状的输入张量来运行模型,避免了此错误。

错误:'CUDAExecutionProvider' is not in available provider

UserWarning: Specified provider 'CUDAExecutionProvider' is not in available provider names.Available providers: 'AzureExecutionProvider, CPUExecutionProvider' warnings.warn( 解决方法

这个警告通常意味着您指定了一个不存在的执行提供程序。在使用onnxruntime.InferenceSession()创建会话对象时,您可以指定要使用的执行提供程序列表。如果指定的执行提供程序不在可用提供程序列表中,则会出现上述警告。

如何解决这个问题取决于您的目标。如果您确信指定的执行提供程序可用,则可以无视警告。否则,可以从可用的提供程序列表中选择一个或多个提供程序,并在创建会话时将其作为提供程序参数传递。例如:

  1. import onnxruntime as ort
  2. providers = ['CPUExecutionProvider']
  3. ort_session = ort.InferenceSession(model_path, providers=providers)

在这个示例中,我们将CPUExecutionProvider作为提供程序传递给onnxruntime.InferenceSession()。如果这个提供程序在可用的提供程序列表中,则不会出现警告。

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜