openvino多输入多输出动态尺寸样例记录

前言

openvino的文档实在太少了,写的也是相当含糊,包括它的例子,谷歌搜索了半天找不到和我类似的问题,于是我在此记录一下,用来帮助后来人,如何用openvino推断多输入多输出的模型。
本文将使用openvino runtimepython binding,先把模型转换为正确的格式,再进行推断。

模型示例

首先先科普一些基本知识,openvino目前是支持onnx模型直接加载的,也可以将onnx模型通过openvino的模型优化器转化成xml再加载,如果你是pytorch的模型的话,请先转为onnx。另外,在推断时,openvino的gpu推断目前是不支持动态加载的,只有cpu支持,也就是说你的向量尺寸必须固定下来,不能变化。不巧的是,本例中的模型还真就是动态加载的。
用netron软件打开我们的onnx模型看下输入输出:
在这里插入图片描述
输入有6个向量,src,r1i,r2i,r3i,r4i,r5i,downsample_ration。
在这里插入图片描述
输出也有六个向量,fgr,pha,r1o,r2o,r3o,r4o。本例中模型特殊的地方在于r1-r4是循环记忆向量,这个是在变化的,也就是说不能固定尺寸。

模型转换

本文假定你已经安装好了openvino的工具包。然后在命令行里输入:

mo --input_model 你的模型.onnx 
--input src,r1i,r2i,r3i,r4i,downsample_ratio 
--input_shape (1,3,720,1280),(1,?,?,?),(1,?,?,?),(1,?,?,?),(1,?,?,?),(1) 
--output fgr,pha,r1o,r2o,r3o,r4o
--data_type FP32

这里注意input和output里面的写法。多个输入输出要用逗号隔开并正确指定名称,同时input_shape里的向量形状需要你固定好,本例中由于r1-r4没法固定,所以就只固定了第一个和最后一个向量,其他都以问号填充。data_type指定模型的精度,本例中指定了FP32,一般对于cpu而言FP32会跑的更快。
在这里插入图片描述
没有报错后顺利转换完毕。多出了几个文件。只需要xml就行。

推断代码核心

本例假定你已经安装了openvino runtime。

from openvino.runtime import Core
ie = Core()
model_openvino = "xxxxx.xml"
model = ie.read_model(model=model_openvino)
compiled_model = ie.compile_model(model=model, device_name="CPU")
x = iter(compiled_model.inputs)
for i in x:
    print(i)
y = iter(compiled_model.outputs)
for i in y:
    print(i)

前三行代码读取模型,第四行代码加载模型,其中device_name指定cpu或者gpu跑,本例中因为动态尺寸,所以必须用cpu,不然加载报错。
后面几行代码会打印出所有的输入层和输出层,是用来检查的。
输出如下:
在这里插入图片描述
接下来正式推断:

infer_request = compiled_model({
        'src': src, 
        'r1i': rec[0], 
        'r2i': rec[1], 
        'r3i': rec[2], 
        'r4i': rec[3], 
        'downsample_ratio': downsample_ratio
    })
fgr,pha,*rec= infer_request.values()

输入的时候注意把向量尺寸都对应好,其中的infer_request是一个字典,因为有多个输出,取值的时候只需要按照字典的顺序用values()方法直接取值即可。
另外这里的*rec是指把剩下的四个循环记忆向量都存进了rec数组里,当成输入再进行推断,所以说是动态尺寸,因为在初始化时,这四个向量是空的,推断一次后就有固定形状了,这玩意目前在openvino的gpu推断里不支持。反正本例最重要的是多输入多输出如何推断的方法,我自行摸索了好久才明白过来。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenVINO C++支持多请求异步处理。多请求可以并行处理,从而提高推理速度。 以下是一个简单的示例,展示如何使用OpenVINO C++进行异步处理: ```c++ #include <inference_engine.hpp> #include <iostream> #include <string> #include <vector> #include <chrono> using namespace InferenceEngine; int main() { // Load the model Core ie; CNNNetwork network = ie.ReadNetwork("model.xml", "model.bin"); ExecutableNetwork executable_network = ie.LoadNetwork(network, "CPU"); // Create multiple infer requests std::vector<InferRequest> requests; for (int i = 0; i < 3; i++) { requests.push_back(executable_network.CreateInferRequest()); } // Prepare the input data std::vector<float> input_data = {1.0, 2.0, 3.0, 4.0}; Blob::Ptr input_blob = requests[0].GetBlob("input"); MemoryBlob::Ptr input_mem_blob = as<MemoryBlob>(input_blob); if (!input_mem_blob) { std::cerr << "Failed to cast input blob to memory blob." << std::endl; return 1; } auto input_mem_ptr = input_mem_blob->rwmap(); std::memcpy(input_mem_ptr.as<float*>(), input_data.data(), input_data.size() * sizeof(float)); // Start async inference for (int i = 0; i < requests.size(); i++) { requests[i].StartAsync(); } // Wait for async inference to complete for (int i = 0; i < requests.size(); i++) { requests[i].Wait(InferRequest::WaitMode::RESULT_READY); Blob::Ptr output_blob = requests[i].GetBlob("output"); MemoryBlob::Ptr output_mem_blob = as<MemoryBlob>(output_blob); if (!output_mem_blob) { std::cerr << "Failed to cast output blob to memory blob." << std::endl; return 1; } auto output_mem_ptr = output_mem_blob->rmap(); std::cout << "Request " << i << " output: "; for (int j = 0; j < output_blob->size(); j++) { std::cout << output_mem_ptr.as<float*>()[j] << " "; } std::cout << std::endl; } return 0; } ``` 该示例加载一个模型,并创建三个InferRequest对象。在准备输入数据后,它会启动异步推理,然后等待所有请求完成。最后,它会打印每个请求的输出。注意,每个请求的输出顺序可能不同,因为它们是并行处理的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值