Note:这个答案是为 Tensorflow 1.x 编写的,虽然概念和核心思想在 TensorFlow 2.x 中保持不变,但这个答案中的命令可能已被弃用。
TF-Lite 的机制使得检查图并获取内部节点的中间值的整个过程有点棘手。这get_tensor(...)
其他答案建议的方法不起作用。
如何可视化 TF-Lite 推理图?
TensorFlow Lite 模型可以使用以下方式可视化可视化.py https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/tools/visualize.py脚本中的TensorFlow Lite 存储库 https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite。您只需要:
-
克隆 TensorFlow 存储库 https://www.tensorflow.org/install/source
-
Run the visualize.py
带有 bazel 的脚本:
bazel run //tensorflow/lite/tools:visualize \
model.tflite \
visualized_model.html
我的 TF 模型中的节点在 TF-Lite 中是否具有等效节点?
NO!事实上,TF-Lite 可以修改您的图表,使其变得更加优化。以下是来自TF-Lite 文档 https://www.tensorflow.org/lite/guide/ops_compatibility:
许多 TensorFlow 操作都可以由 TensorFlow Lite 处理,尽管它们没有直接的等效项。这种情况可以简单地从图中删除(tf.identity)、用张量(tf.placeholder)替换或融合到更复杂的操作(tf.nn.bias_add)中。有时,甚至某些受支持的操作也可能会通过这些过程之一被删除。
此外,TF-Lite API目前不允许获取节点对应关系; TF-Lite 的内部格式很难解释。因此,即使没有下面的另一个问题,您也无法获得所需的任何节点的中间输出......
我可以获得某些 TF-Lite 节点的中间值吗?
NO!这里我就解释一下为什么get_tensor(...) https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter#get_tensor在 TF-Lite 中不起作用。假设在内部表示中,图包含 3 个张量,以及中间的一些密集操作(节点)(您可以认为tensor1
作为输入和tensor3
作为模型的输出)。在这个特定图的推理过程中,TF-Liteonly需要 2 个缓冲区,让我们展示一下如何操作。
First, use tensor1
计算tensor2
通过应用dense
手术。这只需要 2 个缓冲区来存储值:
dense dense
[tensor1] -------> [tensor2] -------> [tensor3]
^^^^^^^ ^^^^^^^
bufferA bufferB
Second,使用的值tensor2
存储在bufferB
计算tensor3
... 可是等等!我们不需要bufferA
不再了,所以让我们用它来存储值tensor3
:
dense dense
[tensor1] -------> [tensor2] -------> [tensor3]
^^^^^^^ ^^^^^^^
bufferB bufferA
现在是棘手的部分。 “产值”为tensor1
仍会指向bufferA
,现在的值是tensor3
。所以如果你打电话get_tensor(...) https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter#get_tensor对于第一个张量,您将得到不正确的值。这该方法的文档 https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter#get_tensor甚至指出:
该函数不能用于读取中间结果。
如何解决这个问题?
-
简单但有限的方法。您可以指定节点的名称,以及要在转换期间获取其值的输出张量:
tflite_convert \
-- # other options of your model
--output_arrays="output_node,intermediate/node/n1,intermediate/node/n2"
-
困难但灵活的方式。您可以使用 Bazel 编译 TF-Lite(使用这条指令 https://www.tensorflow.org/install/source)。然后你实际上可以注入一些日志代码Interpreter::Invoke()
在文件中tensorflow/lite/interpreter.cc
。一个丑陋的黑客,但它有效。