二、TensorRT


TensorRT Sample Support Guide(v7.0)

(一)基于python:(9个)

 


  1、使用Python将Caffe,TensorFlow和ONNX模型导入TensorRT的简介

   运行样本:工程文件:/python/introductory_parser_samples

    它使用TensorRT及其随附的解析器套件 argparser(UFF,Caffe和ONNX解析器)来对经过各种框架训练的ResNet-50模型进行推理

    他是三个较小样本的集合,每个样本都专注于特定的解析器。以下各节介绍每个示例的工作方式:

    caffe_resnet50:该示例演示了如何使用Caffe解析器从训练有素的Caffe模型构建引擎,然后运行推理。Caffe解析器用于Caffe2模型。训练后,您可以直接在模型文件上调用Caffe解析器(通常.caffemodel)并部署文件(通常 .prototxt)。

    onnx_resnet50:该示例演示了如何使用开源ONNX解析器从ONNX模型文件构建引擎,然后运行推理。ONNX解析器可以与任何支持ONNX格式的框架一起使用(通常.onnx 文件)。

    uff_resnet50:该示例演示了如何从UFF模型文件(从TensorFlow protobuf转换)构建引擎,然后运行推理。UFF解析器用于TensorFlow模型。冻结TensorFlow图并将其写入protobuf文件后,您可以使用以下命令将其转换为UFF convert-to-uff   TensorRT附带的实用程序。此样本附带了预先生成的UFF文件。

 


  2、使用TensorFlow和Python的TensorRT的“ Hello World”

   运行样本:工程文件:/python/end_to_end_tensorflow_mnist

    MNIST数据集上训练了一个小型的全连接模型并使用TensorRT运行推理。

    示例是一个端到端的Python示例,该示例在TensorFlow和Keras中训练一个小的3层模型,冻结该模型并将其写入protobuf文件,将其转换为UFF,最后使用TensorRT运行推理。

    冻结TensorFlow图:为了使用命令行UFF实用程序,必须冻结TensorFlow图并将其另存为.pb 文件。

    冻结Keras模型:

def save(model, filename):
    # First freeze the graph and remove training nodes.
    output_names = model.output.op.name
    sess = tf.keras.backend.get_session()
    frozen_graph = tf.graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), [output_names])
    frozen_graph = tf.graph_util.remove_training_nodes(frozen_graph)
    # Save the model
    with open(filename, "wb") as ofile:
        ofile.write(frozen_graph.SerializeToString())
View Code

 

 

     运行样本以训练模型并写出冻结的图:

1 mkdir models
2 python model.py
View Code

    转换 .pb 归档到 .uff 使用convert-to-uff实用程序: 转换为uff的模型/lenet5.pb    创建一个TensorRT推理引擎并运行推理: python sample.py [-d DATA_DIR]


  3、使用PyTorch和Python的TensorRT的“ Hello World”

   运行样本:工程文件:/python/network_api_pytorch_mnist

    端到端样本,它在PyTorch中训练模型,在TensorRT中重新创建网络,从训练后的模型中导入权重(kenel = weight.cov1, weight.bias1组建网络,最后使用TensorRT引擎进行推理。

python sample.py [-d DATA_DIR]
View Code

 


    4、在Python的TensorRT中向您的Caffe网络添加自定义层

   运行样本:工程文件:/python/fc_plugin_caffe_mnist

    演示了如何使用cuBLAS和cuDNN实现自定义FullyConnected层,如何将实现包装在TensorRT插件中(带有相应的插件工厂),并使用它生成Python绑定 pybind11这些绑定然后用于向CaffeParser注册插件工厂

    plugin/该目录包含用于FullyConnected图层插件的文件。完全连接该插件实现CUDA,cuDNN和cuBLAS。pyFullyConnected.cpp该插件为生成Python绑定 FCPlugin 和 FCPluginFactory 类。sample.py该脚本使用提供的FullyConnected图层插件运行MNIST网络

    构建插件及其对应的Python绑定。
mkdir build && pushd build
cmake ..
View Code
    生成插件。
make -j4
popd
View Code
python3 sample.py [-d DATA_DIR]
View Code

  5、在Python的TensorRT中向您的TensorFlow网络添加自定义层

   运行样本:工程文件:/python/uff_custom_plugin

    示例uff_custom_plugin演示了如何将使用C ++编写的插件与TensorRT Python绑定和UFF解析器一起使用。该示例实现了一个裁剪层(作为CUDA内核),将实现包装在TensorRT插件中(带有相应的插件创建者),然后生成一个包含其代码的共享库模块。然后,用户使用Python动态加载该库,这将导致插件在TensorRT的PluginRegistry中注册,并使该插件可用于UFF解析器。

    Plugin/此目录包含Clip层插件的文件。clipKernel.cu裁剪输入的CUDA内核。clipKernel.h该头使CUDA内核暴露于C ++代码。customClipPlugin.cpp自定义TensorRT插件实现,在内部使用CUDA内核customClipPlugin.h ClipPlugin标头。

    lenet5.py该脚本训练了使用Clip插件使用ReLU6激活的MNIST网络。mnist_uff_relu6_plugin.py该脚本将训练后的模型转换为UFF(将ReLU6激活委托给ClipPlugin实例),并在TensorRT中运行推理。requirements.txt该文件指定了运行此Python示例所需的所有Python软件包。

    构建插件及其对应的Python绑定 
 1 mkdir build && pushd build
 2 cmake ..
 3 
 4 
 5 注意: 
 6 cmake .. \
 7         -DPYBIND11_DIR=/usr/local/pybind11/ \
 8         -DCUDA_ROOT=/usr/local/cuda-9.2/ \
 9         -DPYTHON3_INC_DIR=/usr/include/python3.6/ \
10         -DNVINFER_LIB=/path/to/libnvinfer.so \
11         -DTRT_INC_DIR=/path/to/tensorrt/include/
View Code

    生成插件

make -j
popd
View Code

    运行样本以训练模型 

python3 lenet5.py
View Code

    使用TensorRT和自定义剪辑插件实现运行推理

python3 sample.py
View Code

    验证 

=== Testing ===
    Loading Test Case: 3
    Prediction: 3
View Code

 


  6、在Python中使用ONNX TensorRT后端进行对象检测

   运行样本:工程文件:/python/yolov3_onnx/

    chkpoint 文件 创建YOLOv3的ONNX版本 yolov3_to_onnx.py

    从生成的ONNX文件构建TensorRT引擎,然后对示例图像进行推断

    验证样本是否成功运行

 


  7、在Python中使用SSD进行对象检测

   运行样本:工程文件:/python/uff_ssd

    该示例uff_ssd实现了一个完整的基于UFF的管道,用于通过SSD(InceptionV2特征提取器)网络执行推理。

    该示例基于SSD:单发MultiBox检测器 纸。建立在VGG-16网络上的SSD网络在网络的单向通过中执行对象检测和定位的任务。此方法将边界框的输出空间离散化为一组默认框,这些默认框具有不同的长宽比和每个要素图位置的比例。在预测时,网络会为每个默认框中的每个对象类别的存在生成分数,并对该框进行调整以更好地匹配对象形状。此外,该网络还结合了来自具有不同分辨率的多个特征的预测,以自然地处理各种大小的对象。

    该示例基于SSD的TensorFlow实现。有关更多信息,请下载ssd_inception_v2_coco。与本文不同的是,使用MSCOCO数据集对TensorFlow SSD网络进行了InceptionV2架构的培训,该数据集具有91个类(包括背景类)。可以在此处找到网络的配置详细信息。

 

    示例详解

   1、该示例下载了预训练的ssd_inception_v2_coco_2017_11_17模型,并使用其执行推理。另外,它在输入图像上叠加边界框,作为后期处理步骤。

    SSD网络在网络的单向通过中执行对象检测和定位的任务。使用MSCOCO数据集对TensorFlow SSD网络进行了InceptionV2架构的培训

    该示例利用TensorRT插件运行SSD网络。要使用这些插件,需要对TensorFlow图形进行预处理。

    在为我们的应用选择对象检测模型时,通常需要在模型准确性和推断时间之间进行权衡。在这个样本中,我们展示了如何使用TensorRT在不降低准确性的情况下大大改善预训练网络的推理时间。为此,我们采用预训练的Tensorflow模型,并使用TensorRT的UffParser构建TensorRT推理引擎。

 

    该网络的主要组件是预处理器,FeatureExtractor,BoxPredictor,GridAnchorGenerator和后处理器。

    预处理器图形的预处理器步骤负责调整图像的大小。图像调整为300x300x3尺寸张量。预处理器步骤还执行图像的归一化,因此所有像素值都在范围[-1,1]之间

    FeatureExtractor图的FeatureExtractor部分在预处理的图像上运行InceptionV2网络。锚点生成步骤将生成的要素图用于为每个要素图生成默认边界框。在此网络中,用于锚点生成的特征图的大小为[(19x19),(10x10),(5x5),(3x3),(2x2),(1x1)]。

    BoxPredictor BoxPredictor步骤将一个高级要素图作为输入,并为每个要素图生成一个框编码(xy坐标)列表以及这些编码中每种编码的类分数列表。该信息被传递到后处理器。

    GridAnchorGenerator此步骤的目标是为每个要素地图单元格生成一组默认边界框(根据配置中提到的比例和长宽比)。这在TensorRT中作为插件层实现,称为 gridAnchorGenerator插入。注册的插件名称是 GridAnchor_TRT

    后处理器后处理器步骤执行最终步骤以生成网络输出。所有要素图的边界框数据和置信度得分与预先计算的默认边界框(在 GridAnchorGenerator命名空间)。然后,它执行NMS(非最大抑制),该NMS基于置信度阈值和IoU(联合上方的交集)交叠来修剪掉大多数边界框,因此每个类仅存储前N个框。这在TensorRT中作为插件层实现,称为网管系统插入。注册的插件名称是 NMS_TRT

    注意:此示例还实现了另一个名为FlattenConcat 它用于展平每个输入,然后连接结果。由于NMS插件要求数据采用这种格式,因此在将其输入到后处理器步骤之前将其应用于位置和置信度数据。(有关插件实现方式的详细信息,请参见 FlattenConcat 插件和 FlattenConcatPluginCreator 在里面 sampleUffSSD.cpp 文件在 张量/样本/ sampleUffSSD 目录。)

 

   2、处理输入图

    TensorFlow SSD图具有一些TensorRT当前不支持的操作。使用GraphSurgeon,我们可以将图形中的多个操作组合为单个自定义操作,可以使用TensorRT中的插件层实现该操作。当前,GraphSurgeon提供了将命名空间中的所有节点缝合到一个自定义节点中的功能。

    要使用GraphSurgeon, 转换为uff 实用程序应使用 -p标志和一个配置文件。配置脚本还应包含所有自定义插件的属性,这些属性将嵌入到生成的插件中 .uff文件。SSD的当前示例脚本位于 /usr/src/tensorrt/samples/sampleUffSSD/config.py

    使用GraphSurgeon,我们能够从图形中删除预处理器名称空间,将 GridAnchorGenerator 创建的命名空间 GridAnchorGenerator 插件,将后处理器名称空间缝合到 网管系统 插件并将BoxPredictor中的concat操作标记为 FlattenConcat 插件。

    TensorFlow图具有一些操作,例如 断言 和 身分识别可以将其删除以进行推断。像 断言 删除剩余的节点(一旦删除断言,将不再有输出)将被递归删除。

    身分识别删除操作并将输入转发到所有连接的输出。可在TensorRT API中找到有关图形预处理器的其他文档。

 

   3、uff_ssd插件(自定义操作)

    创建TensorRT插件 :

    GridAnchorGeneration plugin:该插件层在TensorFlow SSD网络中生成网格锚点。

    NMS plugin:NMS插件基于BoxPredictor生成的位置和置信度预测来生成检测输出。该层具有三个输入张量,分别对应于位置数据(locData),置信度数据(confData)和先验盒数据(priorData)。

    编译 FlattenConcat 样本目录中的自定义插件;

sh
mkdir -p build
cd build
cmake ..
make
cd ..
View Code

 

  4、验证输出

    在创建构建器(请参阅在Python中构建引擎)并对该引擎进行序列化(请参阅在Python中序列化模型)之后,我们可以执行推理。

    SSD网络的输出是人类可以解释的。后处理工作(例如最终的NMS)在NMS插件中完成。结果以7个元组的形式组织。在每个元组中,这7个元素分别是图像ID,对象标签,置信度得分,()边界框左下角的坐标,以及()边界框右上角的坐标。可以使用以下命令在输出PPM图像中绘制此信息: writePPMFileWithBBox功能。 visualizeThreshold参数可用于控制图像中对象的可视化。当前设置为0.5,因此输出将显示置信度得分为50%或更高的所有对象。

 


  8、Python中的INT8校准

   运行样本:工程文件:/python/int8_caffe_mnist

    演示了如何创建INT8校准器,如何为INT8模式构建和校准引擎以及如何最终在INT8模式下运行推理

    在校准期间,校准器总共检索1003批,每批100张图像。我们简化了用Python读写校准缓存的过程,因此现在可以轻松地缓存校准数据以加快引擎构建速度(请参阅校准器 有关实施的详细信息)。在推论过程中,样本从校准器中加载一个随机批次,然后对全部100张图像执行推论。

 


  9、用Python改装引擎

   运行样本:工程文件:/python/engine_refit_mnist

    在PyTorch中训练MNIST模型,在TensorRT中使用虚拟权重重新创建网络,最后在TensorRT引擎中使用模型中的权重进行调整。改装使我们能够快速修改TensorRT引擎中的权重,而无需重建.。

    该示例首先使用TensorRT网络API重建模型。在第一遍中,其中一个转换层的权重(conv_1)中填充了伪值,从而导致错误的推断结果。在第二阶段中,我们使用训练有素的真值为发动机重新安装conv_1层并再次运行推理。现在正确设置权重,推断应该提供正确的结果。

 


从简入繁

posted on 2020-03-13 22:49  _小程序  阅读(213)  评论(0)    收藏  举报