1.0.简介
本文档介绍了一种将带*.pt 扩展名的YOLOv5 PyTorch* 权重文件转换为ONNX* 权重文件,以及使用模型优化器将ONNX 权重文件转换为IR 文件的方法。该方法可帮助OpenVINO™用户优化YOLOv5,以便将其部署在实际应用中。此外,本文档提供了一个关于如何运行YOLOv5 推理的Python 推理演示,以帮助加快YOLOv5 的开发和部署速度。在最后一部分,针对使用NCS2 运行推理引擎引发的YOLOv5 模型准确度下降问题,本文亦提供了解决方案-修改与重建libmyriadplugin.so,以使其适应YOLOv5 模型。
1.1.术语
1.2.参考文档
2.0.将权重转换为ONNX 文件
需要以下组件。OpenVINO™-在本文档中,我们使用OpenVINO™Linux* 版本2021.1 版进行验证系统–CPU 处理器。在Linux Ubuntu* 18.04.1 上使用Sky Lake 对本指南进行验证Python* –在本文档中,我们使用Python 3.6.9 进行验证ONNX –在本文档中,我们使用ONNX 1.6.0 进行验证PyTorch –在本文档中,我们使用PyTorch 1.6.0 进行验证Netron* –在本文档中,我们使用Netron 4.4.3 进行验证。
2.1.从GitHub 复制YOLOv5 存储库
在Linux 终端运行以下命令(在本文档中,提交4d3680c 用于验证)。
2.2.设置YOLOv5 的环境
若要设置YOLOv5 的环境,需要运行以下命令来安装一些必要组件:
2.3.下载PyTorch 权重
到目前为止,YOLOv5 存储库中有3 个标签。由于骨干网的不同,YOLOv5 分为YOLOv5s、YOLOv5m、YOLOv5l 和YOLOv5x。此处,我们使用来自标签v3.0 的YOLOv5s 进行说明。运行以下命令,以下载yolov5s.pt:
2.4.将PyTorch 权重转换为ONNX 权重
YOLOv5 存储库提供了models/export.py 脚本,您可以使用该脚本将带*.pt 扩展名的PyTorch 权重导出为带*.onnx 扩展名的ONNX 权重由于OpenVINO™2021.1 还未全面支持ONNX opset 版本11,因此我们需要将models/export.py 脚本的第69 行修改为opset 版本10:
然后保存脚本并运行以下命令:
随后,我们将在yolov5-v3 文件夹中得到yolov5s.onnx。
3.0将ONNX 文件转换为IR 文件
从上一节中得到ONNX 权重文件后,我们可以使用模型优化器将其转换为IR 文件。
运行以下脚本,以临时设置OpenVINO™环境和变量:
在使用模型优化器转换YOLOv5 模型时,我们需要指定IR 的输出节点。图1.经过8 倍下采样的YOLOv5 骨干网P3 的输出
YOLOv5 中有3 个输出节点。我们使用Netron 查看YOLOv5 ONNX 权重。然后通过在Netron 中搜索关键词“Transpose”找到输出节点。随后,我们可以查找卷积节点,该节点在图1. 中被标记为椭圆形。双击节点后,我们可以在属性面板中读取其名称“Conv_455”,名称在图1中被标记为矩形。图1 显示大小为1x3x80x80x85 的输出节点和分辨率为1x3x640x640 的输入图像,用于检测小型对象。我们使用卷积节点的名称“Conv_455”来指定模型优化器参数。
我们可以采用类似的方式获取另外两个卷积节点的名称。图2 显示大小为1x3x40x40x85 的输出节点和分辨率为1x3x640x640 的输入图像,用于检测中型对象。读取被标记为矩形的卷积名称“Conv_471”。图3 显示大小为1x3x20x20x85 的输出节点和分辨率为1x3x640x640 的输入图像,用于检测大型对象。读取被标记为矩形的卷积名称“Conv_487”。然后运行以下命令,以生成YOLOv5 模型的IR:
其中,--input_model 定义预训练模型,参数--model_name 是生成的IR 和output .xml/.bin 文件中的网络名称,-s 表示来自原始网络输入的所有输入值都将除以该值,--reverse_input_channels 可将输入通道顺序从RGB 转变为BGR(或者从BGR 转变为RGB),--output 表示模型输出运算的名称。随后,我们将在yolov5-v3 文件夹中得到YOLOv5s 的FP32 格式IR。
4.0推理Python 演示
生成YOLOv5 模型的IR 后,我们根据YOLOv5 模型的推理流程编写推理Python 演示。根据OpenVINO™默认Python 演示中提供的YOLOv3演示,YOLOv5 演示中主要有3 点需要修改:
1)使用letterbox 预处理输入图像
2)使用Sigmoid 函数的YOLO region 层
3)边界框后处理点击此处下载YOLOv5 Python 演示
4.1.使用letterbox 预处理输入图像
YOLOv5 使用letterbox 处理网络的输入图像。在YOLOv5 推理Python 演示中,我们提供了一个用于处理图像的函数:
4.2.使用Sigmoid 函数的YOLO Region 层
在对YOLOv5 的每个检测头执行最后的卷积后,YOLOv5 使用Sigmoid 函数处理推理中的输出。YOLOv5 Python 演示中的YOLO region 层的解析函数与YOLOv3 Python 演示中的解析函数不同。我们在此处提供了解析YOLO region 层的代码:
4.3.边界框后处理
由于YOLOv5 使用letterbox 处理输入图像,因此我们需要重写边界框后处理,以得到正确的检测结果。缩放边框(scale box) 函数如下所示:
5.0NCS2 的准确度下降问题
相比在CPU 上运行FP16 推理得到的检测结果,我们注意到将NCS2 设置为运行推理引擎的设备时,某些对象可能无法被YOLOv5 模型检测到。这是因为图形转换工具使用的缩放比例适合大多数网络,但是有时可能不适合某些网络。为了解决该问题,需要修改weights_analysis.cpp 中的缩放比例并重建libmyriadPlugin.so。首先需运行以下命令,从GitHub 中复制OpenVINO™存储库:
然后运行以下命令,从而切换到OpenVINO™2021.1:
将inference-engine/src/vpu/graph_transformer/src/middleend/passes/ 中的weights_analysis.cpp 的第243-248 行修改为:
然后运行以下命令,以构建OpenVINO™:
之后,您可以在bin/intel64/Release/lib/ 中找到libmyriadPlugin.so。我们可以对原始的libmyriadPlugin.so 进行备份,将新创建的libmyriadPlugin.so 复制到文件夹/opt/intel/openvino/inference_engine/lib/intel64/。然后,我们可以使用NCS2 运行YOLOv5 推理演示,得到的检测结果与使用CPU 得到的检测结果几乎相同。
6.0结论
本白皮书旨在帮助客户将YOLOv5 模型应用到其应用中。
本文档详细介绍了如何将PyTorch 权重文件转换为ONNX 权重文件,以及如何使用OpenVINO™模型优化器,从ONNX 权重文件中生成YOLOv5 模型的IR。此外,本文档提供了针对YOLOv5 模型的推理演示,适用于YOLOv5s、YOLOv5m、YOLOv5l 和YOLOv5x 模型推理。针对使用NCS2 部署YOLOv5 模型引发的准确度下降问题,本文档还提供了解决方案。
通过阅读本白皮书,客户可以更轻松地开发与部署其应用。