我对OpenVINO模型优化器感到好奇。我有一个自定义的ONNX网络,我想使用MO对其进行优化。我正在使用OpenVINO随附的OpenCV执行最终推断。

首先,我将onnx网络转换为其等效的IR表示形式。
python mo.py --input_model E:\cv_align.dll --framework onnx --output_dir E:\models\b1 --log_level DEBUG > log.txt
输出看起来很好。

Common parameters:
    - Path to the Input Model:  E:\cv_align.dll
    - Path for generated IR:    E:\models\b1
    - IR output name:   cv_align
    - Log level:    DEBUG
    - Batch:    Not specified, inherited from the model
    - Input layers:     Not specified, inherited from the model
    - Output layers:    Not specified, inherited from the model
    - Input shapes:     Not specified, inherited from the model
    - Mean values:  Not specified
    - Scale values:     Not specified
    - Scale factor:     Not specified
    - Precision of IR:  FP32
    - Enable fusing:    True
    - Enable grouped convolutions fusing:   True
    - Move mean values to preprocess section:   False
    - Reverse input channels:   False
ONNX specific parameters:
Model Optimizer version:    2019.2.0-436-gf5827d4

[ SUCCESS ] Generated IR model.
[ SUCCESS ] XML file: E:\models\b1\cv_align.xml
[ SUCCESS ] BIN file: E:\models\b1\cv_align.bin
[ SUCCESS ] Total execution time: 30.65 seconds.

我将生成的xml,bin加载到我的C++程序中。当我使用虚拟输入转发模型时,该崩溃。然后,我拿起onnx并直接从onnx生成网络,该网络可以按预期工作。

像这样
static cv::dnn::Net alignNet;

int main()
{
    //initialise
    //auto out = Align_init("E:\\cv_align.dll", 1);
    auto out = Align_init("E:\\models\\b1\\cv_align.xml",
        "E:\\models\\b1\\cv_align.bin", 1);

return 0;
}

///THIS ONE CRASHES AT POINT SHOWN
ALIGN_OUT Align_init(std::string xmlPath, std::string binPath, int batch_size)
{
    assert(std::experimental::filesystem::exists(xmlPath));
    assert(std::experimental::filesystem::exists(binPath));

    alignNet = cv::dnn::readNetFromModelOptimizer(xmlPath, binPath);
    alignNet.dumpToFile("E:\\models\\dump.dmp");

    alignNet.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
    alignNet.setPreferableTarget(cv::dnn::DNN_TARGET_OPENCL);

    //initialise using dummy vars
    std::cout << "  --  Dummy image -- " << std::endl;
    Image dummyImage1 = generateRandMat();
    Image dummyImage2 = generateRandMat();

    Image cImage = getCombinedImage(dummyImage1, dummyImage2);
    auto dummyInput = imgToBlob(cImage);
    alignNet.setInput(dummyInput);
    auto dummyProb = alignNet.forward();  <== This statement throws a Microsoft C++ exception: InferenceEngine::details::InferenceEngineException


    return ALIGN_OUT();
}

///THIS ONE'S FINE
ALIGN_OUT Align_init(std::string onnx_path, int batch_size)
{
    assert(batch_size == 1);
    //TODO: other batch sizes if required

    alignNet = cv::dnn::readNetFromONNX(onnx_path);
    alignNet.dumpToFile("E:\\models\\dump1.dmp");

    alignNet.setPreferableBackend(cv::dnn::DNN_BACKEND_INFERENCE_ENGINE);
    alignNet.setPreferableTarget(cv::dnn::DNN_TARGET_OPENCL);

    //initialise using dummy vars
    std::cout << "  --  Dummy image -- " << std::endl;
    Image dummyImage1 = generateRandMat();
    Image dummyImage2 = generateRandMat();

    Image cImage = getCombinedImage(dummyImage1, dummyImage2);
    auto dummyInput = imgToBlob(cImage);
    alignNet.setInput(dummyInput);
    auto dummyProb = alignNet.forward(); <== This one's fine

return ALIGN_OUT();
}

也以防万一
typedef cv::Mat Image;
typedef std::vector<Image> Images;

知道我做错了什么吗?

谢谢。

转储的更多信息

ONNX转储-
digraph G {
    "261" [label="261\nSlice\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "262" [label="262\nConvolution\nkernel_size (HxW): 7 x 7\lstride (HxW): 2 x 2\ldilation (HxW): 1 x 1\lpad (HxW): (3, 3) x (3, 3)\lgroup: 1\lOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "263" [label="263\nBatchNorm\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "264" [label="264\nRelu\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "265" [label="265\nPooling\nkernel_size (HxW): 3 x 3\lstride (HxW): 2 x 2\lpad (HxW): (1, 1) x (1, 1)\lpool: MAX\lOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "266" [label="266\nConvolution\nkernel_size (HxW): 3 x 3\lstride (HxW): 1 x 1\ldilation (HxW): 1 x 1\lpad (HxW): (1, 1) x (1, 1)\lgroup: 1\lOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "267" [label="267\nBatchNorm\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "268" [label="268\nRelu\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "269" [label="269\nConvolution\nkernel_size (HxW): 3 x 3\lstride (HxW): 1 x 1\ldilation (HxW): 1 x 1\lpad (HxW): (1, 1) x (1, 1)\lgroup: 1\lOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "270" [label="270\nBatchNorm\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "271" [label="271\nEltwise\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "272" [label="272\nRelu\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "273" [label="273\nConvolution\nkernel_size (HxW): 3 x 3\lstride (HxW): 1 x 1\ldilation (HxW): 1 x 1\lpad (HxW): (1, 1) x (1, 1)\lgroup: 1\lOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "274" [label="274\nBatchNorm\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "275" [label="275\nRelu\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "276" [label="276\nConvolution\nkernel_size (HxW): 3 x 3\lstride (HxW): 1 x 1\ldilation (HxW): 1 x 1\lpad (HxW): (1, 1) x (1, 1)\lgroup: 1\lOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "277" [label="277\nBatchNorm\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
    "278" [label="278\nEltwise\nOCV/CPU\n" fillcolor="#ffffb3" style=filled shape=box]
....
...
many more lines

红外线转储-
digraph G {
    "545" [label="545\n\nDLIE/CPU\n" fillcolor="#fdb462" style=filled shape=box]

    "_input" -> "545"
}

似乎它只是以某种方式跳过了中间的每一层。

最佳答案

OpenVINO随附的OpenCV出现了问题。使用Inference Engine Core API时,程序可以按预期工作。

08-27 18:31