深度学习系列六:将网络迁移到TensorRT7.0平台

概述

关于使用TensorRT对网络进行加速的基本工作在深度学习系列五:使用TensorRT对网络进行加速中描述很详细了,这里主要记录下在迁移到7.0时,顺便解决了之前ResizeNearestNeighbor这个层在uff模型中无法直接支持必须外挂plugin的问题。

Keras模型转ONNX模型

之前使用6.0时,采用的方案是Keras模型转uff模型,再创建engine,其实从官方文档可以看出来,目前TensorRT对onnx支持更好,它对onnx支持的层是最多的,这样容易理解,毕竟onnx可以由各种模型转化得到,因此本次使用onnx模型建立engine,转化可以使用keras-onnx库,安装也很简单:

pip3 install keras2onnx

安装完成后使用api进行转换,非常简单,当然还必须安装tensorflow或者keras:

import keras2onnx
import onnx
# load keras model
model = tf.compat.v1.keras.models.load_model(model_path)

# convert to onnx model
onnx_model = keras2onnx.convert_keras(model, model.name, target_opset=10)
# keras model has dynamic batch size, which will add extra work in generating engine.
# Therefore, convert it to static batch size=1
onnx_model.graph.input[0].type.tensor_type.shape.dim[0].dim_value = 1
# # runtime prediction
output_path = os.path.join(output_path, 'converted.onnx')
onnx.save_model(onnx_model, output_path)

需要注意得是tensorrt和onnx版本必须兼容,这里试了好多版本,最终onnx==1.6和opset==10生成的模型基本没有问题。
使用onnx生成模型输入跟keras模型是一致的,为NHWC,而在uff模型中输入会变成NCHW格式,在之前的工作中input总需要进行额外的transpose操作。

ONNX模型生成engine

有了ONNX模型后,生成engine非常简单:

EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
with trt.Builder(TRT_LOGGER) as builder, builder.create_network(EXPLICIT_BATCH) as network, trt.OnnxParser(
        network, TRT_LOGGER) as parser:
    builder.max_batch_size = 1
    builder.max_workspace_size = 1 << 28
    if self.infer_mode == 'int8':
        calibration_cache = "model_data/tensorrt_model/yolo_calibration.cache"
        calib = YOLOEntropyCalibrator(self.calib_img_path, calibration_cache, self.model_image_size,
                                      batch_size=8)
        builder.int8_mode = True
        builder.int8_calibrator = calib

    # profile = builder.create_optimization_profile()
    # profile.set_shape('input_1', (1, 416, 416, 3), (1, 416, 416, 3), (1, 416, 416, 3))
    # config.add_optimization_profile(profile)

    onnx_path = common.model_path_to_onnx_path(model_path)
    with open(onnx_path, 'rb') as model:
        if not parser.parse(model.read()):
            raise TypeError("Parser parse failed.")

    engine = builder.build_cuda_engine(network)

    if not engine:
        raise TypeError("Build engine failed.")
    with open(engine_path, 'wb') as f:
        f.write(engine.serialize())

得到engine文件后,加在它进行推理即可:

if os.path.isfile(engine_path):
    with open(engine_path, 'rb') as f, trt.Runtime(TRT_LOGGER) as runtime:
        return runtime.deserialize_cuda_engine(f.read())

最终得到的三种模型map为:

ModelmodedatasetMAPMAP (0.5)MAP(0.75)
Yolov3-416rawCOCOval20140.3150.5610.319
Yolov3-416fp32COCOval20140.3150.5610.319
Yolov3-416int8COCOval20140.3040.5510.295

所有代码都已经开源,具体推理使用方法见Yolov3-TensorRT-py

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值