python - Visualize TFLite graph and get intermediate values of a particular node?
问题描述
I was wondering if there is a way to know the list of inputs and outputs for a particular node in tflite? I know that I can get input/outputs details, but this does not allow me to reconstruct the computation process that happens inside an Interpreter
. So what I do is:
interpreter = tf.lite.Interpreter(model_path=model_path)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
interpreter.get_tensor_details()
The last 3 commands basically give me dictionaries which don't seem to have the necessary information.
So I was wondering if there is way to know where each nodes outputs goes? Surely Interpreter
knows this somehow. Can we? Thanks.
解决方案
注意:此答案是为 TensorFlow 1.x 编写的,虽然概念和核心思想在 TensorFlow 2.x 中保持不变,但此答案中的命令可能已被弃用。
TF-Lite 的机制使得检查图和获取内部节点中间值的整个过程有点棘手。另一个答案建议的get_tensor(...)
方法不起作用。
如何可视化 TF-Lite 推理图?
TensorFlow Lite 模型可以使用TensorFlow Lite 存储库中的Visualize.py脚本进行可视化。你只需要:
visualize.py
使用 bazel运行脚本:bazel run //tensorflow/lite/tools:visualize \ model.tflite \ visualized_model.html
我的 TF 模型中的节点在 TF-Lite 中是否具有等效节点?
不!事实上,TF-Lite 可以修改您的图表,使其变得更加优化。以下是TF-Lite 文档中关于它的一些话:
TensorFlow Lite 可以处理许多 TensorFlow 操作,即使它们没有直接的等价物。对于可以从图中简单地删除 (tf.identity)、被张量 (tf.placeholder) 替换或融合到更复杂的操作 (tf.nn.bias_add) 中的操作就是这种情况。甚至某些受支持的操作有时也可能通过这些过程之一被删除。
此外,TF-Lite API 目前不允许获取节点对应关系;很难解释 TF-Lite 的内部格式。因此,即使没有下面的另一个问题,您也无法获得所需任何节点的中间输出...
我可以获得一些 TF-Lite 节点的中间值吗?
不!在这里,我将解释为什么get_tensor(...)
不能在 TF-Lite 中工作。假设在内部表示中,该图包含 3 个张量,以及中间的一些密集操作(节点)(您可以将tensor1
其视为模型的输入和tensor3
输出)。在这个特定图的推理过程中,TF-Lite只需要 2 个缓冲区,让我们展示一下。
首先,通过应用运算来tensor1
计算。这只需要 2 个缓冲区来存储值:tensor2
dense
dense dense
[tensor1] -------> [tensor2] -------> [tensor3]
^^^^^^^ ^^^^^^^
bufferA bufferB
其次,使用tensor2
stored in的值bufferB
来计算tensor3
……但是等等!我们不再需要bufferA
了,所以让我们用它来存储 的值tensor3
:
dense dense
[tensor1] -------> [tensor2] -------> [tensor3]
^^^^^^^ ^^^^^^^
bufferB bufferA
现在是棘手的部分。的“输出值”tensor1
仍将指向bufferA
,它现在包含 的值tensor3
。所以如果你调用get_tensor(...)
第一个张量,你会得到不正确的值。该方法的文档甚至指出:
此函数不能用于读取中间结果。
如何解决这个问题?
简单但有限的方式。您可以指定节点的名称,输出张量要在转换期间获取其值:
tflite_convert \ -- # other options of your model --output_arrays="output_node,intermediate/node/n1,intermediate/node/n2"
艰难但灵活的方式。您可以使用 Bazel 编译 TF-Lite(使用此指令)。然后,您实际上可以
Interpreter::Invoke()
在文件中注入一些日志记录代码tensorflow/lite/interpreter.cc
。一个丑陋的黑客,但它的工作原理。
推荐阅读
- vert.x - Vert.x mqtt 服务器 3.6.0 是否符合 MQTT 版本 5?
- javascript - 使用 Webmethod 从 asp.net 后面的代码向 Javascript 传递值
- c# - moq 模拟对象与实际类有多少相似之处?
- r - R中组之间的平均差异
- android - Firebase onchildadded() 在列表视图中返回相同的数据 3 次
- javascript - Setter/Getter 对此
- mysql - 我需要加密 MySQL 表。
- java - Swagger 2.0 无法解析引用,因为:无法解析指针
- docker - Docker 409 客户端错误。如何获得真正的错误并查看容器中的真实日志?
- angular - Angular:表单验证 - 匹配的密码不起作用