在本教程中,我将演示如何将用 TF 2.0 编写的预训练网络转换为适合推理的优化网络,该网络采用一些高级体系结构。目的是使用OpenCV 的Dnn 模块在C++运行模型,但优化的模型可以在 Python 中使用,初始模型可以使用 TensorRT 运行。

在 TF 2.0 中训练模型后,我寻找一种优化模型进行推理的简单方法。但是,我没有找到一个地方,指导我如何做到这一点在TF 2.0,因为TF删除了他们的支持在冻结优化的图形,从所有投诉堆积在StackOverflow(例如,1,2)。

有很多解决方案写在不同的互联网论坛。我正在写一个指南,关于我发现最简单的方法。

系统规格

阿纳康达3 4.4€,

张力2.0,

OpenCV 4.1.2°,

您可能还喜欢:
张力流简介

开始

在网络实现中,我使用了:

  1. 数据集和迭代器 ( tf.data.dataset
  2. 占位符 ( tf.placeholder
  3. 卷积 ( tf.layers.conv2d ).
  4. 深度卷积 ( 和 tf.nn.depthwise_conv2d td.nn.bias_add
  5. 雷卢6 tf.nn.relu6 ()
  6. 批处理规范化 tf.layers.batch_normalization ()。
  7. 平展 tf.layers.flatten ()
  8. 软最大值 tf.nn.softmax ()。
  9. 全球平均数 ( tf.layers.average_pooling2d

培训后,我们希望将模型导出到 .pb 文件,以在推理时运行。Tensorflow 具有用于发布模型的简单代码 API:

tf.saved_model.simple_save(sess,path,inputs,outputs) 

但是,这将导出许多文件中的完整模型,包括图形 def、变量,并且不会删除摘要,这在推理时是不必要的。这限制了使用 GPU 的性能,因为不必要的网络组件通常在 CPU 上运行。

在 TF 2.0 之前,最佳做法是:

  • 冻结模型(将图形 def 与检查点组合在一起,并将所有变量转换为仅一个 pb 文件中的 const)
  • 优化冻结图形进行推理,包括:
    • 删除未使用的节点。
    • 将算术和表达式折叠到常量。
    • 删除标识,不进行操作操作。
    • 将批处理规范化折叠成简单的乘法。
    • 按执行顺序排序,这是在 OpenCV 中运行它所必需的

com/张力流/张力流/斑点/主/拉伸流/工具/graph_transforms/README.md”rel=”无跟踪”目标=”_blank”=图形变换工具,并集成在 TensorFlow 工具库中。直到 TF2.0,TF 删除了他们的支持和图形使用代码,因为 tf.compact1.graph_util 基本上是空的。相反,他们希望开发人员使用保存模型API。但是,其他库和推理模块不支持它,TF 用户需要打破他们的头,以找到优化其模型的方法。

我将详细说明我所做的,以冻结我的模型:

提前编写代码以适合推理

使用名为 的标志 Inference

对于迭代器使用:

Python

xxxxxxx
1
1
    Xy=迭代器.get_next()

3
    is_training=tf占位符(tf.布尔名称="is_training")
4
其他
5
X =tf    占位符(tf.浮点32形状=...
6
    y=tf占位符(tf.浮点32形状=...
7
is_training =tf    常数(tf布尔名称="is_training")
8

使用以下功能保存模型的图形定义:

Tf.train.write_graph(sess.graph,path) 

使用张量流 1.15 创建新环境,并运行以下代码:

Python

xxxxxxx
1
18
1
蛇,工具导入freeze_graphoptimize_for_inference_lib

2

3
freeze_graph.freeze_graph(input_graph_path,input_saver_def_path =" 
4
输入二进制=false,checkpoint_path=checkpoint_path
5
output_nodes="预测"*,restore_op_name""
6
文件名tensor_=""clear_devices=false,")
7

8
图形定义()

9
tfgfile.打开冻结图形路径"rb"f
10
    数据2readf.读取()
11
    输入图解析从String数据 2read
12

13
输出图optimize_for_inference_lib
14
                    optimize_for_inference(输入图, [输入节点名称],
15
tf.浮点32.作为数据类型枚举

17
tfgfile.FastGFile优化的图形路径'w'作为f
18
    f. .写入输出图)。序列化到串())

此代码应工作得完美无缺,但无法处理我的特定模型。我有例外:

“Didn’t find expected Conv2D input to bn” 

这很奇怪,我开始研究我的代码,以及问题是否在我的网络中,或者环境的变化。

最后,我发现这不是我的假设。我发现 TF1.15 代码没有更新与最新的图形转换工具代码在其 inference_lib 。代码的问题是假定批处理规范化接受 Conv2D 操作作为输入。但是,在我的网络中,我使用偏置, BiasAdd 在应用批处理规范化之前使用生成的操作

在尝试修复 Bug 之前,我联机搜索,并看到它已在 GitHub 中得到处理,但它未在 TF 中更新,也不会更新,因为它已在 TF2.0 中删除。

我修改了 TF 代码,并在 以下文件中修补了文件:

%installation python folder%/tensorflow/python/tools/optimjzed_for_inference_
libcom/rangit3/片段/blob/master/optimize_for_inference_lib.py”rel=”不跟随”目标=”_blank”=代码。修复后,我的代码不会返回任何错误。

我希望本指南将帮助有人在那里转换用TF2.0编写的模型在推理时运行。

祝你好运:)

在我的下一篇文章中,我将演示如何在C++ OpenCV 和 Python 中的 TF 上的 OpenCV 上进行推理时运行优化的图形。我会标杆他们(提示:在CPU上,他们是相当相等的)。

进一步阅读

Comments are closed.