OpenVINO部署模型时如何自定义任意尺寸的支持
小o
更新于 3年前
基本原理
OpenVINO在高版本中支持动态修改模型的输入尺度大小(一般是图像宽与高),这个功能是非常有用的,可以帮助我们在程序执行阶段动态修改CNNNetWork的大小,而无需再次转换IR模型文件。它的基本原理支持来自推理引擎的底层ngraph功能支持。最新的IR文件版本v10,它的加载流程与依赖结构如下:
其中读取到的模型可以方便在运行时动态获取与修改替换节点。这里我们通过CNNNetwork支持的函数首先获取输入层的名称与张量维度,然后再修改,修改之后重新编译转换网络就得到修改输入层张量更新之后的CNNNetwork了,整个过程都是在程序执行时候动态完成,无需再次转换IR模型。下面就看看怎么做的!
函数与代码演示
然后我们重新获取输入层的名称与大小,就会发现已经被改变。涉及到两个函数分别为:
//获取输入大小
std::map<std::string, InferenceEngine::SizeVector> InferenceEngine::CNNNetwork::getInputShapes()
// 设置新的大小输入
void InferenceEngine::CNNNetwork::reshape(const std::map<std::string, InferenceEngine::SizeVector> shapes)
无论是来自ngraph的修改还是IR的修改之后都需要调用低延时转换(动态转换)之后会更新网络对象CNNNetwork,调用代码特别简单一句话搞定:
InferenceEngine::LowLatency(cnnNetwork);
然后就会得到改变之后的CNNNetwork了,下面的调用跟正常SDK调用流程相似,以tensorflow对象检测模型的SSD 300x300为例相关的实验代码如下:
#include <opencv2\opencv.hpp>
#include<inference_engine.hpp>
#include "ie_transformations.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
std::string xml = "D:/project***odels/tf_ssdv2_ir/frozen_inference_graph.xml";
std::string bin = "D:/project***odels/tf_ssdv2_ir/frozen_inference_graph.bin";
InferenceEngine::Core ie;
InferenceEngine::CNNNetwork net = ie.ReadNetwork(xml, bin);
std::map<std::string, InferenceEngine::SizeVector> inputs = net.getInputShapes();
std::map<std::string, InferenceEngine::SizeVector>::iterator iter;
// 输入格式
for(iter=input***egin(); iter != inputs.end(); iter++) {
std::cout <<"input name: " << iter->first << std::endl;
InferenceEngine::SizeVector dims = static_cast<InferenceEngine::SizeVector>(iter->second);
printf("input shapes: [");
for (size_t t = 0; t < dims.size(); t++) {
printf(" %d", dims[t]);
}
printf(" ] \n");
}
InferenceEngine::SizeVector n_dims;
n_dims.push_back(1);
n_dims.push_back(3);
n_dims.push_back(224);
n_dims.push_back(224);
std::map<std::string, InferenceEngine::SizeVector> n_input;
n_input.insert(std::make_pair("image_tensor", n_dims));
net.reshape(n_input);
InferenceEngine::LowLatency(net);
inputs = net.getInputShapes();
// 输入格式
for (iter = input***egin(); iter != inputs.end(); iter++) {
std::cout << "new input name: " << iter->first << std::endl;
InferenceEngine::SizeVector dims = static_cast<InferenceEngine::SizeVector>(iter->second);
printf("new input shapes: [");
for (size_t t = 0; t < dims.size(); t++) {
printf(" %d", dims[t]);
}
printf(" ] \n");
}
return 0;
}
运行截图如下:
可以看到输入层:image_tensor的输入大小已经从
1x3x300x300
变为:
1x3x224x224
以后想怎么改就改吧,OpenVINOIE SDK动态修改输入大小技能get!
0个评论