2

我正在尝试将我的自定义训练 SSD mobilenet TF2 对象检测模型转换为 .tflite 格式(flatbuffer),它将与 Raspberry pi 一起使用,我遵循了将我的模型转换为 tflite 模型的官方 tensorflow 教程:

注意:我使用 Colab 和 Tensorflow 2.5-gpu 进行训练,使用 Tensorflow 2.7-nightly 进行转换(提到一些与 SSD 到 tflite 模型转换相关的 Github 问题,使用 nightly 版本)

1-我首先尝试使用export_tflite_ssd_graph.py这些参数导出 tflite 图:

!python object_detection/export_tflite_ssd_graph.py \
--pipeline_config_path models/myssd_mobile/pipeline.config \
--trained_checkpoint_prefix models/myssd_mobile/ckpt-9.index \
--output_directory exported_models/tflite_model

但它显示以下错误:

RuntimeError: tf.placeholder() is not compatible with eager execution.

即使在我通过添加tf.disable_eager_execution()它禁用它之后显示以下错误:

NameError: name 'graph_matcher' is not defined

所以我意识到它可能不是为 tf2 创建的,所以我export_tflite_graph_tf2.py使用下面的代码转换了模型,我得到了保存的模型:

!python object_detection/export_tflite_graph_tf2.py \
--pipeline_config_path models/myssd_mobile/pipeline.config \
--trained_checkpoint_dir models/myssd_mobile \
--output_directory exported_models/tflite_model

2-我使用以下代码将 tflite savedmodel 转换为 .tflite 模型,该代码取自 tensorflow 文档:

import tensorflow as tf

converter = tf.lite.TFLiteConverter.from_saved_model('exported_models/tflite_model/saved_model')
converter.target_spec.supported_ops = [
  tf.lite.OpsSet.TFLITE_BUILTINS, # enable TensorFlow Lite ops.
  tf.lite.OpsSet.SELECT_TF_OPS # enable TensorFlow ops.
]
tflite_model = converter.convert()
open("converted_model.tflite", "wb").write(tflite_model)

之后,我手动创建了 tflite labels.txt,它是:

t1
t2
t3
t4
t5
t6
t7
t8
t9
t10
t11

然后我运行了以下脚本:

TFLite_detection_image.py

但它显示了这个错误:

Traceback (most recent call last):
  File "TFLite_detection_image.py", line 157, in <module>
    for i in range(len(scores)):
TypeError: object of type 'numpy.float32' has no len()

哪里错了?

提前致谢

4

2 回答 2

0

我在 SSD MobileNet v2 320x320 和 SSD MobileNet V2 FPNLite 640x640 上都遇到了同样的问题。所以我发现它不应该与模型本身有关。今天早上我刚刚通过再次生成所有需要的文件来修复这个错误:您将数据拆分为训练/测试(和验证);Tensorflow 的那些,比如 train.record、test.record ...我还检查了我用来确保它有我所有的类的标签图。

在此预处理之后,我使用 export_tflite_graph_tf2.py 导出了我的模型,然后使用了以下 TF Lite 转换器:

import tensorflow as tf
import argparse
# Define model and output directory arguments
parser = argparse.ArgumentParser()
parser.add_argument('--model', help='Folder that the saved model is located in',
                    default='exported-models/my_tflite_model/saved_model')
parser.add_argument('--output', help='Folder that the tflite model will be written to',
                    default='exported-models/my_tflite_model')
args = parser.parse_args()

converter = tf.lite.TFLiteConverter.from_saved_model(args.model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.experimental_new_converter = True
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS]

tflite_model = converter.convert()

output = args.output + '/model.tflite'
with tf.io.gfile.GFile(output, 'wb') as f:
  f.write(tflite_model)

注意:当我使用 TF Lite Nighty 时,我也遇到了错误,所以我只是将此脚本与 TF2 一起使用。

之后,我可以确认这两个模型都在 Raspberry Pi 4B+ 上运行,其精度/召回分数与我在 GPU 上获得的分数相同。

于 2021-09-09T09:34:29.203 回答
0

我遇到了同样的错误,TypeError: object of type 'numpy.float32' has no len()解决方案是在 python 代码中更改分数、框和类的索引,因为这意味着分数是一个标量值而不是数组。请参考这个答案

顺便说一句,当我在 Jetson Nano 上使用 tflite-runtime 时发生了这个错误,但是当我在 Raspberry PI 上的 TF2.5 上运行代码时,它运行时没有改变任何东西。

于 2022-03-04T14:44:43.597 回答