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个评论