整体加速过程

1.将tensorflow训练生成的.h5模型结构权重文件转换成.pb的模型文件。
2.将.pb模型文件转换成uff格式的文件并进行解析,同时生成TensorRT的engine。
3.调用生成的engine文件,实现推理加速。

准备工作

1.生成.pb的模型文件
首先我们需要从保存模型的chekpoint文件中,生成.pb的模型文件。

import tensorflow.compat.v1 as tf1tf1.reset_default_graph()
tf1.keras.backend.set_learning_phase(0)  # 调用模型前一定要执行该命令
tf1.disable_v2_behavior()  # 禁止tensorflow2.0的行为
# 加载hdf5模型,一定要是将模型结构和权重同时保存的文件。
hdf5_pb_model = tf1.keras.models.load_model('D:/Graduate student/Deep learning/project/crowd dense/MSCNN-master/models/bet_model_weights.h5')def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):# tf.graph是创建一张新图,这是指获取图graph = session.graph# 上下文管理器 能够覆盖掉默认的图with graph.as_default():output_names = output_names or []print("output_names", output_names)# 返回此图的序列化图形化表示,node结点,node节点的属性包括name,op,input# GraphDef保存了从输入层到输出层的计算过程input_graph_def = graph.as_graph_def()print(type(input_graph_def))print("len node1", len(input_graph_def.node))if clear_devices:for node in input_graph_def.node:node.device = ""# 计算图中的变量取值以常量的形式保存,output_name用来指定保存的节点frozen_graph = tf1.graph_util.convert_variables_to_constants(session, input_graph_def,                                                                output_names)# 删除不需要进行推理(inference)的节点,在训练过程中,有一些节点,比如Identity和checknerics,它们只在训练时有用,并且可以在仅用于推理的图形中删除outgraph = tf1.graph_util.remove_training_nodes(frozen_graph)  # 云掉与推理无关的内容for node in outgraph.node:print('node:', node.name)print("len node1", len(outgraph.node))return outgraph
output_folder2 = 'D:/Graduate student/Deep learning/project/crowd dense/MSCNN-master/models'
# 模型冻结,返回TensorFlow会话,如果在创建Session时没有指定Graph,则该Session会加载默认Graph
frozen_graph = freeze_session(tf1.compat.v1.keras.backend.get_session(),output_names=[out.op.name for out in hdf5_pb_model.outputs])
# 转换成pb模型
tf1.train.write_graph(frozen_graph, output_folder2, "classify.pb", as_text=False) #保存图结构
  1. 导入必要的库
import tensorflow as tf
import uff
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
from tensorrt.parsers import uffparser

uff:是将刚才的pb转化为TensorRT引擎支持的uff文件,该文件可以序列化,也可以直接当作流传过去。
pycyda:用于显卡cuda编程的,如果要使用TensorRT的python API,这是一个必须的库
uffparser :用于解析uff模型

3.参数设置

MODEL_DIR = './model_seg/model.pb'
CHANNEL = 3
HEIGHT = 299
WIDTH = 299
ENGINE_PATH = './model_seg/model_.pb.plan'
INPUT_NODE = 'input'
OUTPUT_NODE = ['InceptionV3/Logits/SpatialSqueeze']
INPUT_SIZE = [CHANNEL, HEIGHT ,WIDTH]
MAX_BATCH_SIZE = 1
MAX_WORKSPACE = 1<<30
MODEL_DIR:第一步中生成的pb模型地址
CHANNEL、HEIGHT、WIDTH:图片的通道、高和宽,根据模型的输入大小确定
ENGINE_PATH:等会保存TensorRT引擎的地址
INPUT_NODE:模型的输入节点
OUTPUT_NODE:模型的输出节点,是一个列表,如果有许多个输出节点,就将节点名都列入这个列表中
INPUT_SIZE:输入图片的大小,注意通道在前还是后,这里输入的是 CHANNEL, HEIGHT ,WIDTH
MAX_BATCH_SIZE:在推理的时候,每次输入几张图片
MAX_WORKSPACE:显存的大小1<<30也就是1GB的大小。有的时候,程序运行是会报内存溢出的错,这个时候就可以调小MAX_WORKSPACE,比如2 << 10

将tensorflow模型转换成TensorRT

1.pb转uff 并解析模型

# 建立日志模块
G_LOGGER = trt.infer.ConsoleLogger(trt.infer.LogSeverity.INFO)
uff_model = uff.from_tensorflow_frozen_model(FROZEN_GDEF_PATH, OUTPUT_NODE)
parser = uffparser.create_uff_parser()
parser.register_input(INPUT_NODE, INPUT_SIZE, 0)
parser.register_output(OUTPUT_NODE)
这里做的事情是将pb的文件格式转成了uff文件格式。你需要知道的一个概念是,UFF(Universal Framework Format)是一种描述DNN执行图的数据格式。绑定执行图的是输入与输出,所以parser.register_input和parser.register_output做的事情是将tensorflow模型的输入输出在UFF文件中记录。
注意,对于多个输出,因为OUTPUT_NODE是一个列表,所以将多个输出节点依次放入列表就可以了。
如果是多个输入的话,则需要将输入节点名一个个的记录在uff中。register_input()需要3个参数:
name – Input name.
shape – Input shape.
order – Input order on which the framework input was originally.假设你的模型在输入层同时输入了三张图片,那么你需要定义3个输入节点,并且指定order分别为0、1、2。这里的order指的是模型的输入在uff结构中的顺序,这种order在接下来的binding会得到体现。
parser.register_input(INPUT_NODE1, INPUT_SIZE, 0)
parser.register_input(INPUT_NODE2, INPUT_SIZE, 1)
parser.register_input(INPUT_NODE3, INPUT_SIZE, 2)

2.保存模型

engine = trt.utils.uff_to_trt_engine(G_LOGGER,uff_model,parser,MAX_BATCH_SIZE,MAX_WORKSPACE,datatype=trt.infer.DataType.FLOAT)
以上代码创建了TensorRT中的engine,即引擎,这个engine将负责模型的前向运算。TensorRT是一个用于推理的加速工具,所以前向计算就够了。

在engine创建成功之后,就可以使用了。不过,一个建议是将结果保存下来。毕竟到目前为止,虽然代码很少,但是将pb文件成功转换成uff文件是不容易的(谁用谁知道!)

使用以下语句,我们就保存了一个.plan文件。PLAN文件是运行引擎用于执行网络的序列化数据。包含权重,网络中执行步骤以及用来决定如何绑定输入与输出缓存的网络信息。

trt.utils.cwrite_engine_to_file('./model_.pb.plan',engine.serialize())

使用TensorRT实现推理

现在,让我们调用之前保存的plan文件,启用引擎,开始使用TensorRT实现推理。

engine = trt.utils.load_engine(G_LOGGER, './model_.pb.plan')

引擎叫做engine,而引擎运行的上下文叫做context。engine和context在推理过程中都是必须的,这两者的关系如下:

context = engine.create_execution_context()
engine = context.get_engine()

在运行前向运算前,我们还需要做一次确认。get_nb_bindings()是为了获取与这个engine相关的输入输出tensor的数量。对于本例中单输入输出的模型,tensor的数量是2。如果有多个输入输出,这个确认值就要相应的变化,比如3个输入,1个输出的模型,tensor的数量就是4。我们需要知道这个数量,是为了之后的显存分配做准备。

print(engine.get_nb_bindings())
assert(engine.get_nb_bindings() == 2)

现在准备好一张可以输入给模型的图像 img.jpg,并且转换成fp32

img = cv2.imread(img.jpg)
img = img.astype(np.float32)

同时,创建一个array来“接住”输出数据。为什么说“接住”呢,因为之后你就会看到,引擎做前向推理计算的时候,是生成了一个数据流,这个数据流会写入output array中

#create output array to receive data
OUTPUT_SIZE = 10
output = np.zeros(OUTPUT_SIZE , dtype = np.float32)

我们需要为输入输出分配显存,并且绑定。

#使用PyCUDA申请GPU显存并在引擎中注册
#申请的大小是整个batchsize大小的输入以及期望的输出指针大小。
d_input = cuda.mem_alloc(1 * img.size * img.dtype.itemsize)
d_output = cuda.mem_alloc(1 * output.size * output.dtype.itemsize)#引擎需要绑定GPU显存的指针。PyCUDA通过分配成ints实现内存申请。
bindings = [int(d_input), int(d_output)]

现在,我们可以开始TensorRT上的推理计算了!

#建立数据流
stream = cuda.Stream()
#将输入传给cuda
cuda.memcpy_htod_async(d_input, img, stream)
#执行前向推理计算
context.enqueue(1, bindings, stream.handle, None)
#将预测结果传回
cuda.memcpy_dtoh_async(output, d_output, stream)
#同步
stream.synchronize()

这个时候,如果你将output打印出来,就会发现output数组中已经有值了,这就是TensorRT计算的结果。

如过你使用tensorflow的方法,对同一组输入数据做预测,看看计算的结果是否一致 ,因为精度的差异会有一些差异,但是大体上来说,使用tensorflow和TensorRT,会得到一致的结果。

特别注意!

TensorRT和Tensorflow的数据格式不一样,Tensorflow是NHWC格式,即channel_last,而TensorRT中是NCHW格式,即channel_first,比如一张RGB图像,在Tensorflow中表示为(224, 224, 3),在TensorRT中就是(3,224, 224)。所以使用TensorRT时,请一定确认图像的格式。

TensorRT加速相关推荐

  1. 使用TensorRT加速yolo3

    一.TensorRT支持的模型: TensorRT 直接支持的model有ONNX.Caffe.TensorFlow,其他常见model建议先转化成ONNX.总结如下: 1 ONNX(.onnx) 2 ...

  2. TensorRT加速 ——NVIDIA终端AI芯片加速用,可以直接利用caffe或TensorFlow生成的模型来predict(inference)...

    官网:https://developer.nvidia.com/tensorrt 作用:NVIDIA TensorRT™ is a high-performance deep learning inf ...

  3. tensorflow打印模型图_[深度学习]TensorRT加速tensorflow实例

    使用TensorRT加速tensorflow模型的推理应该是很有市场的一种应用了,但是使用Python的.易懂的例子并不多,官方的文档在这方面也是很不友好. 所以,本文旨在提供一个能把原理讲明白,代码 ...

  4. 探讨TensorRT加速AI模型的简易方案 — 以图像超分为例

    AI模型近年来被广泛应用于图像.视频处理,并在超分.降噪.插帧等应用中展现了良好的效果.但由于图像AI模型的计算量大,即便部署在GPU上,有时仍达不到理想的运行速度.为此,NVIDIA推出了Tenso ...

  5. NVIDIA教你用TensorRT加速深度学习推理计算 | 量子位线下沙龙笔记

    主讲人:Ken(何琨)| NVIDIA开发者社区经理 张康 屈鑫 编辑整理 量子位 出品 | 公众号 QbitAI 12月22日,量子位联合NVIDIA英伟达举行了线下交流会,跟现场近百位开发者同学共 ...

  6. TensorRT加速ENet

    TensorRT加速ENet 文章目录 TensorRT加速ENet 1. 训练ENet 2. 生成部署ENet的模型 3. 生成用于TensorRT调用的engine文件 4. 调用engine文件 ...

  7. Yolov5训练自己的数据集+TensorRT加速+Qt部署

    本人由于项目要求,需要利用Yolov5网络训练自己的目标检测与分类模型,并利用TensorRT加速将其部署到Qt界面上.目前已经实现了整个流程,写下这篇博客供需要的各位参考.(本文描述的重点主要是在后 ...

  8. 踩坑到怀疑人生:win10下tensorRT加速YOLOV5

    目录 版本 下载安装包 1.Go to:CUDA10.2 2.Go to:CUDNN 3.Go to:opencv340 4.Go to:pytorch官网 5.Go to:yolov5 6.Go t ...

  9. yolov5 6.1官方模板TensorRT加速保姆级图文教程

    加速的基础流程今年春季已经写好了,可以完美复现加速. 需要补充的是运行export.py的报错,加一句: pip install onnx 这会写教程的时候,电脑是昨天新做的系统,没有python以及 ...

  10. 如何使用TensorRT加速深度学习推理

    文章目录 1.TensorRT 简介 2.一个简单的TensorRT示例 3.简要代码演练 3.1.批量输入 4.配置文件 5.优化您的应用 6.使用混合精度计算 7.设置最大工作区大小 8.重用Te ...

最新文章

  1. Vue:Elementui中的Tag与页面其它元素相互交互的两三事
  2. 【强化学习】AC注释版本
  3. linux网络编程之通信协议格式
  4. HDU - 6621 K-th Closest Distance——主席树+二分
  5. ElasticSearch Pipeline 为新增数据设置更新时间
  6. Callback Functions Tutorial
  7. 怎么打开/查看MySQL的SQL记录
  8. 基于知识图谱的问答系统,BERT做命名实体识别和句子相似度
  9. 单词计数 soj1076
  10. python爬取链家租房信息_使用python爬取链家广州12108条租房信息,并做一些基础分析...
  11. html引入微软雅黑,求让所有浏览器支持微软雅黑的方法_html/css_WEB-ITnose
  12. jadx-gui-1.4.4 反编译工具使用教程
  13. 【FAQ】应用集成HMS Core部分服务出现“ 6003报错”情况的解决方法来啦
  14. eclipse安装图形界面插件
  15. 《傻瓜计量经济学与stata应用》第二章do文件,记得把数据考到当前目录或带上路径,否则可能无法打开
  16. 京东集团副总裁李大学:像CEO一样思考 - Dancen的专栏 - 博客频道 - CSDN.NET
  17. Winsows Server 2019 安装 PostgreSQL
  18. 深度优先搜索-Python
  19. amazon_亚马逊甚至不再那么方便
  20. nubia,无IMEI码(串号丢失)解救【转】

热门文章

  1. JQuery-回到顶部
  2. 近期edge、谷歌浏览器崩溃的问题解决方案
  3. 【php】php开发的前期准备
  4. W3C发布HTML5正式推荐标准 开放Web平台迎来新的里程碑
  5. python字符串format方法参数解释,一文秒懂!Python字符串格式化之format方法详解
  6. mysql的增量备份与全量备份
  7. 精读《设计模式 - Observer 观察者模式》
  8. win10下安装openvino遇到的一些问题及解决方法
  9. 配置 SNAT 和NAT
  10. 腾讯云服务器有多垃圾,清理腾讯云服务器的各种垃圾日志