TensorRT是NVIDIA官方的深度学习网络加速推断库,有c++和python的Api,其中python的Api只支持linux系统,可以对ONNX、Caffe、TensorFlow网络进行加速。现在官方对目标检测框架支持的不多,其中就有onnx版的yolov3,也是现在主流的目标检测网络。
ONNX是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。它使得不同的人工智能框架(如Pytorch, MXNet)可以采用相同格式存储模型数据并交互。 ONNX的规范及代码主要由微软,亚马逊 ,Facebook 和 IBM 等公司共同开发,以开放源代码的方式托管在Github上。目前官方支持加载ONNX模型并进行推理的深度学习框架有: Caffe2, PyTorch, MXNet,ML.NET,TensorRT 和 Microsoft CNTK,并且 TensorFlow 也非官方的支持ONNX。---维基百科
环境信息:
下载TensorRT:
官网下载(需要预先登陆Nvidia):https://developer.nvidia.com/nvidia-tensorrt-download
选择推荐稳定版本GA TensorRT 5.1 GA
下载tar包,其中有python Api的wheel包需要安装,选择对应的python版本安装
pip install tensorrt-5.1.5.0-cp36-none-linux_x86_64.whl
项目所在目录/TensorRT-5.1.5.0/samples/python/yolov3_onnx,这是官方提供的yolov3的darknet权重转onnx再转trt的demo
安装onnx1.4.1版本
pip install onnx==1.4.1
安装依赖包:
pip install -r requirements.txt
官网下载keras版的yolov3:
https://github.com/qqwweee/keras-yolo3
这边先用coco的标准数据集的权重作为演示:
下载连接:
https://pjreddie.com/media/files/yolov3.weights
修改convert.py中88行input_layer的输入大小为608*608,这是TensorRT官方sample中支持的输入大小
input_layer = Input(shape=(608, 608, 3))
运行项目下的convert.py文件将yolov3.cfg和yolov3.weights转换成yolov3.h5:
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
这里保存的h5文件是包含模型和权重的,在自己训练数据保存模型时也必须是保存成包含模型和权重的,用save方法而不是
save_weights方法
h5模型转darknet的weights文件:
使用模型转换[yolov3模型在keras与darknet之间转换] 教程中的转换方法,亲测可用
需要安装tensorflow和keras
pip install tensorflow-gpu==1.13.1 keras==2.2.4
weights文件转onnx文件:
使用官方demo下的yolov3_to_onnx.py来转换成onnx文件
注意这里只支持python2运行,还需要单独创建一个python2的环境并且安装好onnx1.4.1版本以及相关其他依赖包
修改输入输出路径为自己的weights文件路径和生成名
weights_file_path = 'yolov3c_d2k_k2d.weights'
output_file_path = 'yolov3.onnx'
指定相关mask、anchor、threshold、输入尺寸参数
postprocessor_args = {"yolo_masks": [(6, 7, 8), (3, 4, 5), (0, 1, 2)], # A list of 3 three-dimensional tuples for the YOLO masks
"yolo_anchors": [(10, 13), (16, 30), (33, 23), (30, 61), (62, 45), # A list of 9 two-dimensional tuples for the YOLO anchors
(59, 119), (116, 90), (156, 198), (373, 326)],
"obj_threshold": 0.6, # Threshold for object coverage, float value between 0 and 1
"nms_threshold": 0.5, # Threshold for non-max suppression algorithm, float value between 0 and 1
"yolo_input_resolution": input_resolution_yolov3_HW}
onnx文件转trt文件并进行推断:
使用官方demo下的onnx_to_tensorrt.py来转换成trt文件
这里又要使用原来的python3环境来运行了
修改main函数下的路径为自己文件路径
onnx_file_path = 'yolov3.onnx'
engine_file_path = "yolov3.trt"
运行完成后会输出一张带标记的图像,说明trt文件保存成功并且推断成功
内容理解:
这里官方demo的yolov3使用的608*608大小的图像输入,然后有3个尺度的输出19*19, 38*38, 76*76,这是在weights文件转onnx文件时做的处理,之前使用onnx官方的keras转onnx只能有一个输出,而且在解析的时候中间层都没有检测到,所以就只能用tensorrt的demo通过weights转onnx,再将onnx转trt,这样才能正常使用。而且要指定输入大小为608*608。
如果是用416*416大小作为输入的话需要将3个尺度的输出改为13*13,26*26,52*52。由于keras的yolo默认保持的是权重,而且也的确是权重的h5是我们所需要的,因为在训练时一般我们会将前面层都冻结等操作,在保存时会影响模型结构,所以需要将h5的权重文件先转换成weights文件,然后再用yolov3官方的convert.py来转换成h5再转成weights文件,然后操作都和上面一样就行。还有需要修改coco_labels.txt里面的class为自己的类别,同时修改data_processing.py中CATEGORY_NUM为自己class的数目即可。
参考文章:
使用TensorRT加速yolo3 https://www.cnblogs.com/justcoder/p/10428100.html
TensorRT&Sample&Python[yolov3_onnx] https://www.cnblogs.com/shouhuxianjian/p/10550262.html
模型转换[yolov3模型在keras与darknet之间转换] https://www.cnblogs.com/shouhuxianjian/p/10567201.html