OpenVINO开发小组
直播中

刘秀英

8年用户 1416经验值
私信 关注
[问答]

使用OpenVINO™推理引擎进行推理时,如何更改模型布局?


  • 无法为一系列网络准备输入。
  • 第一个模型的输出在 CHW 布局中,但第二个模型的输入在 NCHW 布局中。

回帖(1)

张华

2025-3-6 17:46:03

在使用 OpenVINO™ 推理引擎进行推理时,如果你需要更改模型的布局(例如,将 CHW 布局转换为 NCHW 布局),可以通过以下步骤来实现。


1. 使用 ngraph 进行布局转换


OpenVINO™ 提供了 ngraph 库,可以在模型推理之前对模型进行布局转换。以下是一个示例,展示如何将 CHW 布局转换为 NCHW 布局。


#include 
#include
#include

using namespace InferenceEngine;

int main() {
    // 加载第一个模型并推理
    Core ie;
    auto network = ie.ReadNetwork("model1.xml", "model1.bin");
    auto executable_network = ie.LoadNetwork(network, "CPU");
    auto infer_request = executable_network.CreateInferRequest();

    // 获取第一个模型的输出
    auto output = infer_request.GetBlob("output_name");

    // 将 CHW 布局转换为 NCHW 布局
    auto output_dims = output->getTensorDesc().getDims();
    ngraph::Shape new_shape = {1, output_dims[0], output_dims[1], output_dims[2]}; // 添加 batch 维度
    auto reshape = std::make_shared(
        std::make_shared(ngraph::element::f32, output_dims),
        ngraph::opset3::Constant::create(ngraph::element::i64, ngraph::Shape{4}, new_shape),
        true);

    // 创建一个新的 ngraph 函数
    auto function = std::make_shared(ngraph::OutputVector{reshape}, ngraph::ParameterVector{});

    // 将 ngraph 函数转换为 OpenVINO 模型
    auto reshaped_network = InferenceEngine::CNNNetwork(function);

    // 加载第二个模型并推理
    auto network2 = ie.ReadNetwork("model2.xml", "model2.bin");
    auto executable_network2 = ie.LoadNetwork(network2, "CPU");
    auto infer_request2 = executable_network2.CreateInferRequest();

    // 将第一个模型的输出作为第二个模型的输入
    infer_request2.SetBlob("input_name", reshaped_network.GetOutputsInfo().begin()->second);

    // 进行推理
    infer_request2.Infer();

    // 获取第二个模型的输出
    auto output2 = infer_request2.GetBlob("output_name");

    // 处理输出结果
    // ...

    return 0;
}

2. 使用 PreProcess 进行布局转换


如果你不想修改模型本身,可以使用 OpenVINO™ 的 PreProcess 功能来在推理过程中动态调整输入布局。


#include 

using namespace InferenceEngine;

int main() {
    // 加载第一个模型并推理
    Core ie;
    auto network = ie.ReadNetwork("model1.xml", "model1.bin");
    auto executable_network = ie.LoadNetwork(network, "CPU");
    auto infer_request = executable_network.CreateInferRequest();

    // 获取第一个模型的输出
    auto output = infer_request.GetBlob("output_name");

    // 加载第二个模型
    auto network2 = ie.ReadNetwork("model2.xml", "model2.bin");
    auto executable_network2 = ie.LoadNetwork(network2, "CPU");
    auto infer_request2 = executable_network2.CreateInferRequest();

    // 设置第二个模型的输入布局为 NCHW
    auto input_info = network2.getInputsInfo().begin()->second;
    input_info->setLayout(Layout::NCHW);

    // 将第一个模型的输出作为第二个模型的输入
    infer_request2.SetBlob("input_name", output);

    // 进行推理
    infer_request2.Infer();

    // 获取第二个模型的输出
    auto output2 = infer_request2.GetBlob("output_name");

    // 处理输出结果
    // ...

    return 0;
}

3. 使用 reshape 方法


如果你在模型推理之前已经知道需要更改布局,可以在加载模型时使用 reshape 方法来调整输入输出的形状。


#include 

using namespace InferenceEngine;

int main() {
    // 加载第一个模型并推理
    Core ie;
    auto network = ie.ReadNetwork("model1.xml", "model1.bin");
    auto executable_network = ie.LoadNetwork(network, "CPU");
    auto infer_request = executable_network.CreateInferRequest();

    // 获取第一个模型的输出
    auto output = infer_request.GetBlob("output_name");

    // 加载第二个模型并调整输入形状
    auto network2 = ie.ReadNetwork("model2.xml", "model2.bin");
    auto input_info = network2.getInputsInfo().begin()->second;
    input_info->getInputData()->reshape({1, 3, 224, 224}); // 假设输入形状为 NCHW

    auto executable_network2 = ie.LoadNetwork(network2, "CPU");
    auto infer_request2 = executable_network2.CreateInferRequest();

    // 将第一个模型的输出作为第二个模型的输入
    infer_request2.SetBlob("input_name", output);

    // 进行推理
    infer_request2.Infer();

    // 获取第二个模型的输出
    auto output2 = infer_request2.GetBlob("output_name");

    // 处理输出结果
    // ...

    return 0;
}

总结


以上三种方法都可以帮助你在 OpenVINO™ 推理引擎中更改模型布局。选择哪种方法取决于你的具体需求和场景。如果你需要在推理过程中动态调整布局,PreProcess 是一个不错的选择;如果你希望在模型加载时调整布局,可以使用 reshape 方法;如果你需要更复杂的布局转换,可以使用 ngraph 进行模型转换。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分