0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述OpenVINO™ + ResNet实现图像分类

英特尔物联网 来源:英特尔物联网 作者:英特尔物联网 2021-05-18 09:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

推理引擎(IE)应用开发流程

与相关函数介绍

通过OpenVINO的推理引擎跟相关应用集成相关深度学习模型的应用基本流程如下:

3f4a03ea-b4ff-11eb-bf61-12bb97331649.png

图-1

从图-1可以看到只需要七步就可以完成应用集成,实现深度学习模型的推理预测,各步骤中相关的API函数支持与作用解释如下:

Step 1:

InferenceEngine::Core // IE对象

Step 2:

Core.ReadNetwork(xml/onnx)输入的IR或者onnx格式文件,返回CNNNetwork对象

Step 3:

InferenceEngine::InputsDataMap, InferenceEngine::InputInfo, // 模型输入信息
InferenceEngine::OutputsDataMap // 模型输出信息

使用上述两个相关输入与输出对象就可以设置输入的数据类型与精度,获取输入与输出层的名称。

Step 4:

ExecutableNetwork LoadNetwork (
const CNNNetwork &network,
const std::string &deviceName,
const std::map< std::string, std::string > &config={}
)

通过Core的LoadNetwork方法生成可执行的网络,如果你有多个设备,就可以创建多个可执行的网络。其参数解释如下:

network 参数表示step2加载得到CNNNetwork对象实例

deviceName表示模型计算所依赖的硬件资源,可以为CPUGPUFPGA、 FPGA、MYRIAD

config默认为空

InferRequest InferenceEngine::CreateInferRequest()

表示从可执行网络创建推理请求。

Step 5:

根据输入层的名称获取输入buffer数据缓冲区,然后把输入图像数据填到缓冲区,实现输入设置。其中根据输入层名称获取输入缓冲区的函数为如下:

Blob::Ptr GetBlob (
const std::string &name // 输入层名称
)

注意:返回包含输入层维度信息,支持多个输入层数据设置!

Step 6:

推理预测,直接调用推理请求的InferRequest.infer()方法即可,该方法无参数。

Step 7:

调用InferRequest的GetBlob()方法,使用参数为输出层名称,就会得到网络的输出预测结果,根据输出层维度信息进行解析即可获取输出预测信息与显示。

图像分类与ResNet网络

图像分类是计算机视觉的关键任务之一,关于图像分类最知名的数据集是ImageNet,包含了自然场景下大量各种的图像数据,支持1000个类别的图像分类。OpenVINO在模型库的public中有ResNet模型1000个分类的预训练模型支持,它们主要是:

- resnest-18-pytorch

- resnest-34-pytorch

- resnest-50-pytorch

- resnet-50-tf

其中18、34、50表示权重层,pytorch表示模型来自pytorch框架训练生成、tf表示tensorflow训练生成。ResNet系列网络的详细说明如下:

406b3d52-b4ff-11eb-bf61-12bb97331649.png

图-2(来自《Deep Residual Learning for Image Recognition》论文)

我们以ResNet18-pytorch的模型为例,基于Pytorch框架我们可以很轻松的把它转换为ONNX格式文件。然后使用Netron工具打开,可以看到网络的输入图示如下:

40f2157a-b4ff-11eb-bf61-12bb97331649.png

图-3

查看网络的输出:

40fe8af8-b4ff-11eb-bf61-12bb97331649.png

图-4

这样我们很清楚的知道网络的输入与输出层名称,输入数据格式与输出数据格式,其中输入数据格式NCHW中的N表示图像数目,这里是1、C表示图像通道数,这里输入的是彩色图像,通道数为3、H与W分别表示图像的高与宽,均为224。在输出格式中1x1000中1表示图像数目、1000表示预测的1000个分类的置信度数据。

程序实现的基本流程与步骤

前面已经介绍了IE SDK相关函数,图像分类模型ResNet18的输入与输出格式信息。现在我们就可以借助IE SDK来完成一个完整的图像分类模型的应用部署了,根据前面提到的步骤各步的代码实现与解释如下:

1. 初始化IE

InferenceEngine::Core ie;

2. 加载ResNet18网络

InferenceEngine::CNNNetwork network = ie.ReadNetwork(onnx);
InferenceEngine::InputsDataMap inputs = network.getInputsInfo();
InferenceEngine::OutputsDataMap outputs = network.getOutputsInfo();

3. 获取输入与输出名称、设置输入与输出数据格式

std::string input_name = "";
for (auto item : inputs) {
input_name = item.first;
auto input_data = item.second;
input_data->setPrecision(Precision::FP32);
input_data->setLayout(Layout::NCHW);
input_data->getPreProcess().setColorFormat(ColorFormat::RGB);
std::cout << "input name: " << input_name << std::endl;
}

std::string output_name = "";
for (auto item : outputs) {
output_name = item.first;
auto output_data = item.second;
output_data->setPrecision(Precision::FP32);
std::cout << "output name: " << output_name << std::endl;
}

4. 获取推理请求对象实例

auto executable_network = ie.LoadNetwork(network, "CPU");
auto infer_request = executable_network.CreateInferRequest();

5. 输入图像数据设置

auto input = infer_request.GetBlob(input_name);
size_t num_channels = input->getTensorDesc().getDims()[1];
size_t h = input->getTensorDesc().getDims()[2];
size_t w = input->getTensorDesc().getDims()[3];
size_t image_size = h*w;
cv::Mat blob_image;
cv::resize(src, blob_image, cv::Size(w, h));
cv::cvtColor(blob_image, blob_image, cv::COLOR_BGR2RGB);
blob_image.convertTo(blob_image, CV_32F);
blob_image = blob_image / 255.0;
cv::subtract(blob_image, cv::Scalar(0.485, 0.456, 0.406), blob_image);
cv::divide(blob_image, cv::Scalar(0.229, 0.224, 0.225), blob_image);

// HWC =》NCHW
float* data = static_cast(input->buffer());for (size_t row = 0; row < h; row++) {    for (size_t col = 0; col < w; col++) {        for (size_t ch = 0; ch < num_channels; ch++) {            data[image_sizech + row*w + col] = blob_image.at<:vec3f>(row, col)[ch];
}
}
}

在输入数据部分OpenCV导入的图像三通道顺序是BGR,所以要转换为RGB,resize到224x224大小、像素值归一化为0~1之间、然后要减去均值(0.485, 0.456, 0.406),除以方差(0.229, 0.224, 0.225)完成预处理之后再填充到Blob缓冲区中区。

6. 推理

infer_request.Infer();

7. 解析输出与显示结果

auto output = infer_request.GetBlob(output_name);
const float* probs = static_cast ::value_type*>(output->buffer());
const SizeVector outputDims = output->getTensorDesc().getDims();
std::cout << outputDims[0] << "x" << outputDims[1] << std::endl;
float max = probs[0];
int max_index = 0;
for (int i = 1; i < outputDims[1]; i++) {
if (max < probs[i]) {
max = probs[i];
max_index = i;
}
}<:fp32>

cv::putText(src, labels[max_index], cv::Point(50, 50), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 255), 2, 8);
cv::imshow("输入图像", src);
cv::waitKey(0);

解析部分代码首先通过输出层名称获取输出数据对象BLOB,然后根据输出格式1x1000,寻找最大值对应的index,根据索引index得到对应的分类标签,然后通过OpenCV图像输出分类结果。

运行结果

图-5(来自ImageNet测试集)

这样我们就使用OpenVINO 的推理引擎相关的SDK函数支持成功部署ResNet18模型,并预测了一张输入图像。你可以能还想知道除了图像分类模型,OpenVINO 推理引擎在对象检测方面都有哪些应用,我们下次继续…….

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4421

    浏览量

    67826
  • 代码
    +关注

    关注

    30

    文章

    4976

    浏览量

    74373
  • OpenCV
    +关注

    关注

    33

    文章

    652

    浏览量

    45076
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1111

    浏览量

    52005

原文标题:OpenVINO™ + ResNet实现图像分类

文章出处:【微信号:英特尔物联网,微信公众号:英特尔物联网】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    图像采集卡分类、接口与性能指标详解

    图像采集卡是机器视觉、工业检测、安防监控、医疗影像等领域的核心硬件,核心作用是将相机等图像源输出的模拟/数字信号转化为计算机可识别、处理的数字图像数据,同时完成信号同步、缓存、传输等关键操作,其
    的头像 发表于 01-29 16:55 696次阅读
    <b class='flag-5'>图像</b>采集卡<b class='flag-5'>分类</b>、接口与性能指标详解

    基于级联分类器的人脸检测基本原理

    检测到人脸这一结果。 注:该算法在github上有开源实现:https://github.com/nenadmarkus/pico 3) 算法流程 我们在图像上设置一定的搜索范围,初始化一系列的滑动窗口
    发表于 10-30 06:14

    基于瑞芯微RK3576的resnet50训练部署教程

    Resnet50简介ResNet50网络是2015年由微软实验室的何恺明提出,获得ILSVRC2015图像分类竞赛第一名。在ResNet网络
    的头像 发表于 09-10 11:19 1467次阅读
    基于瑞芯微RK3576的<b class='flag-5'>resnet</b>50训练部署教程

    无法在NPU上推理OpenVINO™优化的 TinyLlama 模型怎么解决?

    在 NPU 上推断 OpenVINO™优化的 TinyLlama 模型。 遇到的错误: get_shape was called on a descriptor::Tensor with dynamic shape
    发表于 07-11 06:58

    无法将Tensorflow Lite模型转换为OpenVINO™格式怎么处理?

    将 Tensorflow Lite 模型转换为 OpenVINO™ 格式。 遇到的错误: FrontEnd API failed with OpConversionFailure:No translator found for TFLite_Detection_PostProcess node.
    发表于 06-25 08:27

    请问OpenVINO™ 是否支持 Rust 绑定?

    无法确定OpenVINO™是否支持 Rust 绑定。
    发表于 06-25 07:45

    无法运行Whisper Asr GenAI OpenVINO™ Notebook怎么解决?

    冉小 声说-asr-genai OpenVINO™笔记本。 遇到的错误: Port for tensor name cache_position was not found.
    发表于 06-25 07:41

    请问如何优化OpenVINO™工具套件中的内存使用?

    运行OpenVINO™推断时找不到优化内存使用情况的方法。
    发表于 06-25 06:56

    无法使用OpenVINO™在 GPU 设备上运行稳定扩散文本到图像的原因?

    OpenVINO™ GPU 设备上使用图像大小 (1024X576) 运行稳定扩散文本到图像,并收到错误消息: RuntimeError: Exception from
    发表于 06-25 06:36

    请问Openvino是否支持 Risc-V (riscv64) 架构?

    在spacemit k1型板(bpi-f3)上编译OpenVINO™,但失败。 使用 riscv64 构建OpenVINO™并崩溃。
    发表于 06-24 07:26

    请问如何通过OpenVINO™加速启用稳定的扩散 Web UI?

    无法运行具有OpenVINO™加速的稳定扩散 Web UI。
    发表于 06-24 06:48

    无法将Openvino™ 2025.0与onnx运行时Openvino™ 执行提供程序 1.16.2 结合使用,怎么处理?

    使用OpenVINO™与英特尔 i5-8500 CPU 和超核处理器 630 iGPU 一起部署模型。 使用了 Microsoft.ML.OnnxRuntime.OpenVino
    发表于 06-24 06:31

    为什么无法通过“pip install openvino-dev==2025.0.0”安装 2025.0 OpenVINO™?

    通过“pip install openvino-dev==2025.0.0OpenVINO™ 2025.0 安装。 收到的错误: ERROR: No matching distribution found for openvino
    发表于 06-23 08:13

    Intel OpenVINO™ Day0 实现阿里通义 Qwen3 快速部署

    本文将以 Qwen3-8B 为例,介绍如何利用 OpenVINO 的 Python API 在英特尔平台(GPU, NPU)Qwen3 系列模型。
    的头像 发表于 05-11 11:36 1879次阅读
    Intel <b class='flag-5'>OpenVINO</b>™ Day0 <b class='flag-5'>实现</b>阿里通义 Qwen3 快速部署

    OpenVINO C#如何运行YOLO11实例分割模型

    代码是我在OpenVINO-CSharp-API作者开源的YOLOv8对象检测的代码基础上修改而成。
    的头像 发表于 04-29 09:30 2227次阅读
    <b class='flag-5'>OpenVINO</b> C#如何运行YOLO11实例分割模型