| 
 | 
	
 
 本帖最后由 Nicole_Terasic 于 2020-6-19 17:25 编辑  
 
概述 
 
图1 
 
OpenVINO中模型优化器(Model Optimizer)支持tensorflow/Caffe模型转换为OpenVINO的中间层表示IR(intermediate representation),从而实现对模型的压缩与优化,方便推断引擎更快的加载与执行这些模型。以tensorflow对象检测框架支持的SSD MobileNet v2版本的模型为例,实现从tensorflow的pb文件到IR格式的bin与xml文件生成。全部的过程可以分为三个部分,下面一一解析! 
 
Tensorflow层支持 
模型优化器对各种深度学习框架模型的支持并非是100%的,以tensorflow为例,只有下面这些层构建的模型才可以被模型优化器转换为中间层IR(.xml与.bin文件),R5版本支持的层列表如下: 
图2(见原文图示) 
 
注意:上述支持层构建的tensorflow模型才可以被转换成IR模型! 
 
特别值得赞扬的是模型优化器在R4版本中开始支持原生的tensorflow与基于tensorflow对象检测框架预训练与迁移学习两种方式生成的tensorflow模型。 
 
转换脚本运行 
 
在使用转换脚本之前,首先需要安装tensorflow支持,如果之前电脑上已经安装了tensorflow可以跳过此步!完整的从tensorflow模型到中间层IR转换步骤可以分为如下几步: 
 
1. 配置模型优化器依赖 
 
主要是要安装tensorflow框架支持- pip install tensorflow // 如果已经安装可以跳过此步
 
  复制代码 2. 导出PB文件或者冻结预测图 
 
3. 使用模型优化器生成脚本生成IR文件 
 
- xml文件-描述网络拓扑结构
 - bin文件-包含权重参数的二进制文件
 
 
  
 
打开cmd命令行,首先到openvino安装好的模型优化器目录下- <INSTALL_DIR>/deployment_tools/model_optimizer
 
  复制代码 里面有很多转换模型的脚本,其中mo_tf.py是支持把tensorflow模型转换为IR,脚本运行命令行如下:- python mo_tf.py --input_model .pb --log_level DEBUG
 
 
  复制代码 默认生成的模型会在<INSTALL_DIR>/deployment_tools/model_optimizer该目录下面。其中- --input_model表示tensorflow模型的pb文件路径
 
 - --log_level表示输出调试信息
 
 - --output_dir声明IR输出保持路径
 
 - --reverse_input_channels表示交换R与B通道顺序
 
  复制代码 上述的运行脚本与参数只能支持tensorflow本身的导出PB文件,对tensorflow对象检测框架中的预训练模型与自定义训练生成的模型无法正确生成IR。Tensorflow object detection API训练出来的模型必须通过下面的命令行参数才可以正确生成IR 
 
--input_model  
预训练的模型(二进制的bp文件路径) 
--tensorflow_use_custom_operations_config 
用来替换来自对象检测框架模型网络结构的子图配置与匹配文件,必须跟模型一一对应.- 当前支持的模型配置json文件包括如下:
 
 - ssd_v2_support.json
 
 - faster_rcnn_support.json
 
 - faster_rcnn_support_api_v1.7.json
 
 - mask_rcnn_support.json
 
 - mask_rcnn_support_api_v1.7.json
 
 - mask_rcnn_support_api_v1.11.json
 
 - rfcn_support.json
 
  复制代码 --tensorflow_object_detection_api_pipeline_config 
来自对象检测框架导出模型时候config文件,描述模型的结构与训练相关信息。 
--input_shape 
模型的输入数据,相当于对象检测网络中image_tensor的四维数据 
 
以对象检测网络中SSD MobileNet V2版本为例,执行如下脚本即可转换为IR模型:- python mo_tf.py /
 
 - --input_model D:\tensorflow\ssd_mobilenet_v2_coco_2018_03_29\frozen_inference_graph.pb /
 
 - --tensorflow_use_custom_operations_config extensions/front/tf/ssd_v2_support.json /
 
 - --output="detection_boxes,detection_scores,num_detections" /
 
 - --tensorflow_object_detection_api_pipeline_config D:\tensorflow\ssd_mobilenet_v2_coco_2018_03_29\pipeline.config /
 
 - --data_type FP32
 
 
  复制代码 其中 
--data_type 表示数据类型, 支持FP16 FP32 half float四种格式 
 
选择FP16或者half模型压缩后大小大概是原来的二分之左右,这样模型可以在受限的嵌入式设备上运行。运行命令行,会生成SSD MobileNet V2版本的xml与bin文件 
图3 
 
运行输出与结果: 
图4 
 
使用IR模型 
 
 
转换为IR的模型同样可以在OpenCV DNN中使用,完成对象检测,演示代码如下:- string binModel = "D:/projects/models/ssdv2_ir/frozen_inference_graph.bin";
 
 - string xmlInfo = "D:/projects/models/ssdv2_ir/frozen_inference_graph.xml";
 
 - Mat image = imread("D:/images/dog.jpg");
 
  
- // 启用OpenVINO
 
 - Net net = readNetFromModelOptimizer(xmlInfo, binModel);
 
 - net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
 
 - net.setPreferableTarget(DNN_TARGET_CPU);
 
  
- // 执行推断
 
 - Mat blob = blobFromImage(image, 1.0, Size(300, 300), Scalar(), true, false, 5);
 
 - net.setInput(blob);
 
 - Mat detection = net.forward();
 
  
- vector<double> layersTimings;
 
 - double freq = getTickFrequency() / 1000;
 
 - double time = net.getPerfProfile(layersTimings) / freq;
 
 - ostringstream ss;
 
 - ss << "inference: " << time << " ms";
 
 - putText(image, ss.str(), Point(20, 20), 0, 0.5, Scalar(255, 0, 0));
 
  
- // 解析输出
 
 - Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
 
 - float confidence_threshold = 0.5;
 
 - for (int i = 0; i < detectionMat.rows; i++) {
 
 -     float confidence = detectionMat.at<float>(i, 2);
 
 -     if (confidence > confidence_threshold) {
 
 -         size_t objIndex = (size_t)(detectionMat.at<float>(i, 1));
 
 -         float tl_x = detectionMat.at<float>(i, 3) * image.cols;
 
 -         float tl_y = detectionMat.at<float>(i, 4) * image.rows;
 
 -         float br_x = detectionMat.at<float>(i, 5) * image.cols;
 
 -         float br_y = detectionMat.at<float>(i, 6) * image.rows;
 
  
-         Rect object_box((int)tl_x, (int)tl_y, (int)(br_x - tl_x), (int)(br_y - tl_y));
 
 -         rectangle(image, object_box, Scalar(0, 0, 255), 2, 8, 0);
 
 -     }
 
 - }
 
  
- // 显示结果
 
 - imshow("tensorflow-openvino-ir-model", image);
 
 - imwrite("D:/ir_result.png", image);
 
  复制代码 运行结果如下: 
 
图5 
 
转自:https://mp.weixin.qq.com/s/nfi-E4IY61ivWL6jiATDHg 
作者: gloomyfish  OpenCV学堂 
 |   
 
 
 
 |