【问题标题】:Cannot load TensorFlow Lite model on microcontroller无法在微控制器上加载 TensorFlow Lite 模型
【发布时间】:2020-02-24 16:31:26
【问题描述】:

我正在尝试在微控制器上运行 TensorFlow lite 模型,即在 Sparkfun Edge 板上,但是我在将模型加载到设备时遇到了一些问题。以下是我经历的步骤:

  1. 使用tf.keras API 在 TensorFlow 2.1 中训练我自己的模型
  2. 使用TensorFlow website 上提供的说明对权重和激活执行全整数量化。我不知道为什么,但似乎我无法获得具有 INT8 输入和输出的模型,即使我按照提供的说明进行操作。事实上,这是我的模型在量化后的样子: 可以看到,我模型的输入类型还是float32,流过Quantize节点后变成int8。同样,我有一个指向图形输出的Dequantize 节点,它的作用正好相反,即它采用int8 值并将它们转换回float32,如下所示: 虽然这不是它应该的样子(即int8 输入和输出没有 QuantizeDequantize 节点),但只要我能让它工作就可以了
  3. 编辑了this file(实际上还有一些其他文件,但这是最重要的文件),它是在 Sparkfun Edge 板上运行并托管在 TensorFlow 的 GitHub 上的图像分类模型的example application 的一部分存储库(此应用程序使用 TensorFlow Lite 的 C++ API 与微控制器一起使用)。更具体地说,我替换了以下代码:
static tflite::MicroOpResolver<3> micro_op_resolver;
micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
    tflite::ops::micro::Register_DEPTHWISE_CONV_2D());
micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_CONV_2D,
                             tflite::ops::micro::Register_CONV_2D());
micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_AVERAGE_POOL_2D,
                             tflite::ops::micro::Register_AVERAGE_POOL_2D());

用这个:

static tflite::MicroOpResolver<10> micro_op_resolver;

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
    tflite::ops::micro::Register_DEPTHWISE_CONV_2D(),
    1,
    3
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_CONV_2D, 
    tflite::ops::micro::Register_CONV_2D(),
    1,
    3
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_AVERAGE_POOL_2D, 
    tflite::ops::micro::Register_AVERAGE_POOL_2D()
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_ADD, 
    tflite::ops::micro::Register_ADD()
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_SOFTMAX, 
    tflite::ops::micro::Register_SOFTMAX()
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_FULLY_CONNECTED, 
    tflite::ops::micro::Register_FULLY_CONNECTED()
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_QUANTIZE, 
    tflite::ops::micro::Register_QUANTIZE()
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_DEQUANTIZE, 
    tflite::ops::micro::Register_DEQUANTIZE(),
    1,
    2
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_RELU, 
    tflite::ops::micro::Register_RELU()
);

micro_op_resolver.AddBuiltin(
    tflite::BuiltinOperator_RELU6, 
    tflite::ops::micro::Register_RELU6()
);

它基本上注册了我的自定义模型中包含的所有不同层。 按照为 Sparkfun Edge 板提供的instructions,我设法将应用程序闪存到板上,但是当我运行它时,它会输出以下错误:

Didn't find op for builtin opcode 'QUANTIZE' version '1'

Failed to get registration from op code  d

AllocateTensors() failed

我不明白我做错了什么,因为 QUANTIZE 操作已注册到 micro_op_resolver.AddBuiltin(...)(请参阅最后的代码 sn-p)

【问题讨论】:

    标签: c++ microcontroller tensorflow-lite


    【解决方案1】:

    我在使用最新版本的 Tensorflow(和 tf-nightly)时遇到了同样的错误。我已经在 Tensorflow 的 Github herehere 上打开了一个问题以及另一个用户。

    在使用“MicroOpResolver”时,我也遇到了与“QUANTIZE”相同的错误。您可以尝试使用“AllOpsResolver”,但您可能会遇到问题中提到的相同问题。

    static tflite::ops::micro::AllOpsResolver resolver;
    

    【讨论】:

    • 令人惊讶的是,它奏效了!不过,我不明白为什么。顺便说一句,我现在面临一个不同的问题:解释器在执行层时卡在某个点,即“添加”层。奇怪的是,它并没有卡在第一个“添加”,而是卡在第五个。如果我试图让它跳过第五个加法,它会卡在第六个,依此类推。我想知道这是否与将MicroOpResolver 替换为AllOpsResolver 意味着更少的内存可用于张量分配之类的事情有关
    • 所以它通过将 'MicroOpResolver' 替换为 'AllOpsResolver' 来工作?有趣的。我想这取决于网络架构和您使用的层。你更新 TensorFlow 了吗?对于您的新问题,您是否尝试在您的计算机上使用 Tensorflow lite 运行您的模型,看看它是否也会发生?
    • 我使用通过 pip 安装的 TensorFlow 2.1 训练我的模型,而我部署到开发板上的 C++ 程序中的各种包含文件(以及 TensorFlow Lite 解释器本身)来自TensorFlow 的 GitHub 存储库,版本 2.1。我尝试在我的电脑上使用 TensorFlow Lite 运行模型,它可以工作(它不会卡住)
    猜你喜欢
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    相关资源
    最近更新 更多