• 深度学习-Python调用ONNX模型


    目录

    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()。如果这个提供程序在可用的提供程序列表中,则不会出现警告。

  • 相关阅读:
    使用GIt小组分工完成积分商城系统-SSM
    从InterruptedException深入理解AtomicReference的方方面面
    树莓派(十二)树莓派驱动开发入门:从读懂框架到自己写驱动(下)
    docker swarm 更改绑定ip
    JAVA实训第三天
    正则表达式--记录01
    mysql 递归获取内容
    护网行动,最全攻略来啦!!!
    橱柜的装修干货|板材、五金、高度、配色4个方面。福州中宅装饰,福州装修
    nginx 编译使用 nginx_upstream_check_module
  • 原文地址:https://blog.csdn.net/songpeiying/article/details/133084413