TensorRT 4 基本介绍及TensorFlow模型转化Uff格式导入(二)

原创作品,转载时请务必以超链接形式标明文章原始出处: http://www.dapalm.com/?p=143,作者:大数据,怕了么?

目录

  • 原创作品,转载时请务必以超链接形式标明文章原始出处: http://www.dapalm.com/?p=143,作者:大数据,怕了么?
      • 目录
    • 多种模型导入
    • 支持层
    • 自定义层

从TensorRT1到TensorRT4一路跟过来,现在支持也越来越完善,NVIDIA的尿性就是不开源,坑不少,作为一个Inference库,确实为部署网络带来方便。下面从下面几个方面梳理总结一下:

  • 多种模型导入
  • 支持层
  • 自定义层
  • UFF格式及转换

多种模型导入

  • Caffe caffemodel目前支持最完整
  • Onnx Onnx目前不支持自定义层
  • TensorFlow TensorFlow的模型需要先导出frozen graph,在转换成uff格式

支持层

TRT实现了22中层接口,Caffe和TensorFlow支持的层都是通过集成这些接口实现,具体每种模型支持哪些具体的层和参数,并没有很明确的支持,只能通过代码去试验。
- Convolution:3D,with or without bias
- Full_Connected
- Activation : ReLu, Sigmoid,Tanh
- Pooling :Max, Average, Max_Average_blend
- LRN
- Scale
- Softmax
- Deconvolution
- Concat : across channel
- ElementWise : sum, product, maximum, subtraction,division, power
- RNN : Input,Output,Forget,Update,Reset,Cell,Hidden
- Unary : exp,log,sqrt,recip,abs,neg
- Padding
- Shuffle
- Reduce : sum,prod,max,min,avg
- Topk max,min
- Gather
- Matrix_Multiply
- Ragged_Softmax
- Constant : Uff模型的权值就是保存为常量类型
- RNN_v2
- Plugin : FasterRCNN fused plugin (RPN + ROI pooling). Normalize plugin. Permute plugin. PriorBox plugin. SSD DetectionOutput plugin. Concat plugin. YOLO PReLU Plugin. YOLO Reorg Plugin. YOLO Region Plugin.

  • Caffe已知支持的层(没有明确指出CaffeParser能解析哪些层和参数,下面列一下用过不支持的层)
    不支持除ReLu外其他变形 除across channel参数的Softmax、Concat等
  • TensorFlow已知支持的算子
    Placeholder Const Add Sub Mul Div RealDiv Relu Tanh Sigmoid Negative Abs Sqrt Rsqrt Square Pow Exp Log Softmax Minimum Maximum Shape Reshape Transpose Pack ConcatV2 MaxPool AvgPool Conv2D DepthwiseConv2dNative Conv2DBackpropInput BiasAdd FuseBatchNorm StrideSlice Sum Prod Min Max Mean Squeeze Pad

自定义层

目前支持Caffe和TensorFlow的模型,不支持Onnx

1.创建一个符合IPlugin接口的插件
具体步骤:
{
0.构造函数
- 第一个构造函数,构造函数作用是拷贝权重到对应内存中,或者输入各种参数,用于配置及序列化,参数类型由自己定义,如果有权值需要带const Weight* weight,int nbWeight这两个参数,将权值读入内存,最终序列化到硬盘;
- 第二个构造函数,传入参数const void* data, size_t length,从硬盘中序列化的优化权重文件拷到gpu内存,如果该层没有权值,不需要实现,只需要在执行阶段操作上一层传过来的feature map。
1.确定自定义层输出大小,在调用ITensor::getDimensions()或者builder阶段时调用
- getNbOutputs(); //return该层输出的个数
- getOutputDimensions(); //return该层输出的维度
2.配置层(只在builder阶段调用,用来确定序列化或反序列化)
- configure(const Dims*inputs, int nbInputs, const Dims* outputs, int nbOutputs, int); 调用第一构造函数,最后序列化时,可以从输入参数获取需要保存的数据,存入硬盘。提供了输入维度,输入个数,输出维度和输出个数信息,可以在插件中直接使用
3.工作空间
- getWorkspaceSize();//层所需要的额外内存空间大小
4.资源管理(初始化和释放)
- initialize(); //调用第二个构造函数反序列化后,构建engine时,用于做一些初始化操作,主要是开辟显存空间。
- terminate();//释放资源
5.执行
- enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream);//该层具体的操作,一般用cuda实现:核函数 + 接口函数。
6.序列化/以及反序列化
- getSerializationSize();//该层序列化的字节数,
- serilization(void* buffer); //序列化,直接以字节形式把需要存储的参数写入buffer中
}
2.class CustomPlugin: public IPlugin自定义层在插件工厂中进行初始化
Caffe和Uff模型都是用同一个工厂class PluginFactory : public nvinfer1::IPluginFactory, public nvcaffeparser1::IPluginFactory,public nvuffparser::IPluginFactory,public nvuffparser::FieldCollection
- Caffe使用nvinfer1::IPlugin* createPlugin(const char* layerName, const nvinfer1::Weights* weights, int nbWeights)来实例化插件层中的第一个构造函数
- Uff使用nvinfer1::IPlugin* createPlugin(const char* layerName, const nvinfer1::Weights* weights, int nbWeights,const FieldCollection fc)来实例化插件层中的第一个构造函数(序列化过程)
- Caffe和Uff都是用统一的函数nvinfer1::IPlugin* createPlugin(const char* layerName, const void* serialData, size_t serialLength)来实例化插件层中的第二个构造函数(反序列化过程)
3.添加插件到网络ICaffeParser* parser = createCaffeParser(); parser->setPluginFactory(pluginFactory);
Caffe添加插件具体方法请samplePlugin参考 —— [ TensorRT Developer Guide ]
注意: TensorRT中的UFF格式需要从TensorFlow Frozen Graph转换而来,其中自定义op可以自己根据情况在后面添加对应_ID号,防止多个同样的插件层在插件工厂中出现莫名其妙的问题,插件没有Demo,自己试的

你可能感兴趣的:(TensorRT编程指南)