Dmi*_*rii 4 python keras tensorflow tensorflow-lite
我正在尝试调试我的tflite模型,该模型使用自定义操作。我找到了操作名称(in *.pb)和操作ID(in *.tflite)之间的对应关系,并且我正在进行逐层比较(以确保输出差异始终在范围内1e-4(因为它在最后爆炸) ,我想找到我的自定义层失败的确切位置)如下:
方法1:我使用get_tensor如下方式获取输出:
from tensorflow.contrib.lite.python import interpreter
# load the model
model = interpreter.Interpreter(model_path='model.tflite')
model.allocate_tensors()
# get tensors
for i in tensor_ids:
tensor_output[i] = model.get_tensor(i)
Run Code Online (Sandbox Code Playgroud)
它显示的随机值完全不足(与 TensorFlow 模型的输出相比)。
方法2:只转换*.pb到某一层,然后重复,基本上:
创建一个*.pb,使其仅包含从input到 的网络layer_1。
转换为tflite(因此输出现在为layer_1)并使用 TensorFlow 检查 TF-Lite 的输出。
layer_2对, layer_3, ...重复步骤 1-2 outputs。
此方法需要更多的工作和执行,但它正确地表明,对于内置操作,模型的输出tflite是pb相同的,并且仅在我的自定义操作中开始有所不同(而在方法 1中,输出立即与第一层不同) 。
问:为什么行为
get_tensor如此奇怪?也许是因为我正在使用tensorflow 1.9(当时 TF-Lite 尚未发布并且仅在开发者预览版中可用)?
PS:我知道 TF-Lite 的发布,但我已经为我的项目手动编译了 TensorFlow 1.9,现在很难更改版本控制。
几个月前我也遇到了同样的问题。事实是,TF-Lite 与 TensorFlow 完全不同——它使用静态内存和执行计划、内存映射文件以实现更快的加载,并且它应该优化网络前向传播管道中的一切可能。
我不是 TF-Lite 的开发人员,但我认为它通过重新使用用于先前计算操作的内存区域来保持极低的内存占用。让我们看看下图的想法:
第 1 步:首先,我们将输入提供给符号张量I(在括号中)。假设它的值存储在名为 的缓冲区中buffer_1。
op1 op2 op3
(I) ----> A ----> B ----> O
_________________________________
^^^ ^^^^^^^^^^^^ ^^^
input intermediate output
tensor tensors tensor
Run Code Online (Sandbox Code Playgroud)
步骤 2:现在,我们需要计算op1符号张量I以获得符号张量A。我们计算buffer_1符号张量的值并将其存储A在名为 的缓冲区中buffer_2。
[op1] op2 op3
(I) ----> (A) ----> B ----> O
Run Code Online (Sandbox Code Playgroud)
步骤 3:现在,我们计算op2符号张量A以获得符号张量B。我们计算buffer_2符号张量的值并将其存储在名为...B的缓冲区中buffer_3
op1 [op2] op3
I ----> (A) ----> (B) ----> O
Run Code Online (Sandbox Code Playgroud)
可是等等!buffer_3如果我们现在有buffer_1未使用的内存,并且其值现在对于获取输出无用,为什么要浪费我们的内存来存储呢O?因此,buffer_3我们实际上不会将该操作的结果存储在buffer_1!
这就是高效内存重用的基本思想,我认为它是在 TF-Lite 中实现的,因为它内置了静态图形分析器toco和其他东西。这就是为什么你不能简单地应用于get_tensor非输出张量。
更简单的调试方法?
您提到您正在编写一个自定义操作,所以我想您已经使用 构建tflite了bazel,对吗?然后您实际上可以将一些日志记录代码注入到Interpreter::Invoke()该文件中tensorflow/lite/interpreter.cc。一个丑陋的黑客,但它有效。
PS:如果有任何 TensorFlow Lite 开发人员遇到并对此发表评论,我将很高兴:)
| 归档时间: |
|
| 查看次数: |
2392 次 |
| 最近记录: |