Tensorflow: [问题&错误] tensorflow-lite中是否有类似SSD-Mobile-net的检测模型?

创建于 2017-12-26  ·  141评论  ·  资料来源: tensorflow/tensorflow

你好。

使用 tensorflow-lite 开发一个安卓应用程序。

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/g3doc/models.md
未找到检测模型。

另外,我尝试使用 tensorflow-lite-API 转换 SSD-Inceptionv2。 但是好像有问题。

命令


bazel run --config=opt --copt=-msse4.1 --copt=-msse4.2 \
  //tensorflow/contrib/lite/toco:toco -- \
  --input_file=/home/danshin/tensorflow_lite/lite_model/fire_incpetion_v2.pb \
  --output_file=/home/danshin/tensorflow_lite/lite_model/fire_inception_v2.lite \
  --input_format=TENSORFLOW_GRAPHDEF \
  --output_format=TFLITE \
  --inference_type=FLOAT \
  --input_shape=1,300,300,3 \
  --input_array=image_tensor \
  --output_array={detection_boxes,detection_scores,detection_classes,num_detections}

错误代码


2017-12-26 14:59:25.159220: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] Before general graph transformations: 2029 operators, 3459 arrays (0 quantized)
2017-12-26 14:59:25.251633: F tensorflow/contrib/lite/toco/graph_transformations/resolve_tensorflow_switch.cc:95] Check failed: other_op->type == OperatorType::kTensorFlowMerge 

fire_inception_v2 文件已创建,但其大小为零字节。
什么是问题?

还,
请让我知道部署自定义模型以进行对象检测的最佳方法是什么?

有人帮我请!

谢谢。

lite feature

最有用的评论

它现在在tensorflow/contrib/lite/examples/android上线! 这是原始 TF Android 演示的一个更完整的移植版(仅缺少 Stylize 示例),并将替换 tensorflow/contrib/lite/java/demo 中的其他演示。

转换后的 TF Lite flatbuffer 可以在mobilenet_ssd_tflite_v1.zip中找到,您可以在TFLiteObjectDetectionAPIModel.java中找到 Java 推理实现。 请注意,这与原始 TF 实现的不同之处在于,这些盒子必须在 Java 中手动解码,并且需要在应用程序资产中打包一个盒子之前的 txt 文件(我认为上面模型 zip 中包含的那个应该对大多数人都有效图表)。

在 TOCO 转换期间,使用不同的输入节点(预处理器/子)以及不同的输出节点(concat、concat_1)。 这会跳过一些对 tflite 有问题的部分,直到图形被重构或 TF Lite 达到 TF parity。

以下是将 SSD MobileNet 模型转换为 tflite 格式并构建演示以使用它的快速步骤:

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

所有141条评论

@aselle你能看看这个问题吗? 谢谢。

我们目前正在努力转换 mobilenet SSD(然后是 inception ssd),但它包含不完全支持的操作。 完成后,我将更新此问题。

太好了,我在这里问过类似的问题: https ://github.com/tensorflow/tensorflow/issues/14731

你们估计要多久才能添加来自 ssd-mobilenet 的支持?

谢谢,
马丁·佩尼亚克

应用了stat: awaiting tensorflower 标签后,TensorFlow 组织的一名成员已经回复。

?

唠叨的受让人:已经 14 天没有活动了,这个问题有一个受让人。 请相应地更新标签和/或状态。

任何更新?
我也面临着类似的问题。 提前致谢。

@yucheeling

您能否建议任何数据集,如“ ssd_mobilenet_v1_coco_2017_11_17.tar ”,可用于零售店中的不同服装识别,如 T 恤、牛仔裤等。

@rana3579 ,请在stackoverflow上提出这样的问题。 mobilenet ssd 的快速更新。 这正在取得进展,我们希望我们很快就会有一个例子。

@rana3579查看我的视频,在 movidius、nvidia gpus 以及 arm 处理器上运行。 我无法分享数据集,但如果您是公司的一员,我们可以讨论潜在的合作: https ://www.youtube.com/watch?v=3MinI9cCJrc

@aselle感谢您的更新! 在哪里查找有关此的通知? 如果可能的话,我想尽快通知。 谢谢你,我感谢你在这方面的辛勤工作!

@andrewharp ,正在为此工作,并将更新 Java TF Mobile 应用程序以使用 tflite。 因此,请注意存储库中的这些更改。 我暂时不讨论这个问题。

这是内部功能; 在接下来的一两周内应该有一些东西出来。

@andrewharp太棒了!! 这也适用于 iOS 相机示例吗?
还有重量和性能的大小是多少?
TFLite 分类移动网络很小,iOS 上的性能非常流畅,所以我对 TFLite 感到非常兴奋。

其他一些人已经将现有的 SSD Mobilenet pb 转换为 coreml 模型,并在 Swift 中编写了缺少的输出层:
https://github.com/vonholst/SSDMobileNet_CoreML

但这只是 iPhone 7 上的 8-12 fps。

你好,
这事有进一步更新吗?

我也很好奇:)

我有一个将 Android TF 演示移植到目前正在审查的 tflite 的提交,希望这周应该出现在 github 上。

@madhavajay它仅适用于 Android,但您应该能够将其调整为适用于 iOS。 唯一的问题是,一些预处理(图像调整大小/归一化)和后处理(非最大抑制和框先验调整)是在 Java 中完成的,因为 tflite 并不完全支持 MobileNet SSD 使用的所有运算符.

@andrewharp太棒了。 您能否简要解释一下为什么这些操作目前在 TF lite 中不可用。 常规 SSD 上的 tfcoreml 转换工具的情况似乎相同。 不只是出于技术兴趣而抱怨,他们是否做了一些在移动堆栈中特别难以实现的事情,或者只是低优先级?

期待看到你在 Android 代码上的史诗般的努力!!! 非常感谢。 我知道我不是唯一一个期待这个的人!

@andrewharp@aselle关于使用基于 SSD 的 TFLite 对象本地化示例的演示的任何更新?

它现在在tensorflow/contrib/lite/examples/android上线! 这是原始 TF Android 演示的一个更完整的移植版(仅缺少 Stylize 示例),并将替换 tensorflow/contrib/lite/java/demo 中的其他演示。

转换后的 TF Lite flatbuffer 可以在mobilenet_ssd_tflite_v1.zip中找到,您可以在TFLiteObjectDetectionAPIModel.java中找到 Java 推理实现。 请注意,这与原始 TF 实现的不同之处在于,这些盒子必须在 Java 中手动解码,并且需要在应用程序资产中打包一个盒子之前的 txt 文件(我认为上面模型 zip 中包含的那个应该对大多数人都有效图表)。

在 TOCO 转换期间,使用不同的输入节点(预处理器/子)以及不同的输出节点(concat、concat_1)。 这会跳过一些对 tflite 有问题的部分,直到图形被重构或 TF Lite 达到 TF parity。

以下是将 SSD MobileNet 模型转换为 tflite 格式并构建演示以使用它的快速步骤:

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

@andrewharp复活节快乐🥚🍫 你的传奇! :) 看看我能不能让它运行起来。

你好,有量化版本吗?

我按照上面的说明进行操作,但需要:

  • Android SDK 15 因为我的 bazel 版本
  • 我也无法在 Android Studio 中打开项目

@andrewharp这是你们正在开发的一个新的 Android Studio 东西,它使用 bazel 来构建项目而不是 Gradle,还是因为时间短而暂时缺少一些项目设置来让它工作?

如果我了解问题所在,很乐意提供 PR。

同样关于性能,我的 LG G6 在 Android 7 上似乎很慢。
那是因为 NN API 只在 Android 8 上吗?

有人可以在 Android 8 上测试吗?

我明白了,我认为这些说明仅用于转换。 在句子的第一部分说这就是你如何转换模型大声笑后,我停止了阅读。

是的,我有像素 xl,我想你的手机没有可以加速推理的硬件,或者软件不支持硬件。

我会尽力让你知道。 我假设我可以用 android studio doh 构建它......

从我的iPhone发送

2018 年 3 月 31 日 20:05,Madhava Jay [email protected]写道:

我按照上面的说明进行操作,但需要:

Android SDK 15 因为我的 bazel 版本
我也无法在 Android Studio 中打开项目
@andrewharp这是你们正在开发的一个新的 Android Studio 东西,它使用 bazel 来构建项目而不是 Gradle,还是因为时间短而暂时缺少一些项目设置来让它工作?

如果我了解问题所在,很乐意提供 PR。

同样关于性能,我的 LG G6 在 Android 7 上似乎很慢。
那是因为 NN API 只在 Android 8 上吗?

有人可以在 Android 8 上测试吗?


您收到此消息是因为您发表了评论。
直接回复此电子邮件,在 GitHub 上查看它,或将线程静音。

是的,我做了同样的事情,直接去了代码和 Android 工作室。 然后,在您今天早上 ping 之后,我正要回复说我遇到了同样的问题,然后再次 RTFM。 🤣

据我所知,LG G6 应该能够支持 N​​N API,因为它具有与 Pixel 1 相同的 Qualcomm 821 SoC。但不幸的是,LG 尚未发布 Android 8 或 8.1,并且最新的 LineageOS 构建看起来有点粗略所以我会推迟,除非我知道它在 Android 8.1 上效果更好。 如果你能在 Pixel 上启动它,那就太棒了! 👍

我已经设法对此进行了测试,但演示运行速度非常慢……甚至比原始版本还要慢。
我正在使用 Pixel XL(第一个版本),并且我之前已经为 64 位拱门编译了旧的演示,即使没有 tfLite,它的运行速度几乎是两倍……在这种情况下,推理时间约为 450 毫秒。 当我尝试这个演示时,它以大约 850 毫秒的速度运行,有时甚至超过一秒。 我是不是做错了什么,或者我只是过于乐观地期望得到一个不错的加速? 谢谢。

@mpeniak我在 LG G6 上获得了相同的速度,开启或关闭调试(起初以为是调试)。 我怀疑 NNAPI 没有被使用。 也许我们需要对 nnapi_lib 构建做一些特别的事情?
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/BUILD

列出了依赖项,但可能需要为特定架构构建?
也许在 ./configure
(顺便说一句,我在我的 ./configure 中启用了 XLA,以防万一,但它没有改变速度)

@andrewharp
我想使用NNAPI,但我不知道如何使用它。
根据文档,神经网络 API 在 Android 8.1 中可用 >
如果是8.1以上,基本都应用了吗? 或者我需要额外的 NDK 工作吗? 文档链接
祝你有美好的一天XD

@andrewharp ,我尝试为 tflite_demo 启用 NNAPI 并运行 apk,但是我发现 apk 崩溃了
调用 AddOpsAndParams 时,不支持 tflite::BuiltinOperator_SQUEEZE 操作,并且
nn_op_type 设置为 -1,这将导致 FATAL 调用和 exit(-1) 。 我认为那是
根本原因。 请问以后的版本会支持吗? 有没有其他的工作方式
周围测试NNAPI路径? 谢谢。

@andrehentz
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB --output=$STRIPPED_PB --frozen_graph=True \
--input_names=预处理器/子 --output_names=concat,concat_1 \
--alsologtostderr

为什么不是 input_names image_tensor?
我尝试过这种方式,但遇到了错误。

@nanamare
您应该使用frozen_inference_graph_stripped.pb 而不是frozen_inference_graph.pb。
尝试“bazel-bin/tensorflow/tools/graph_transforms/summarize_graph --in_graph=frozen_inference_graph_stripped.pb”
您可以看到以下输出:
找到 1 个可能的输入:(name=Preprocessor/sub, type=float(1), shape=None)
没有发现变量。
找到 2 个可能的输出: (name=concat, op=ConcatV2) (name=concat_1, op=ConcatV2)

输入名称是 Preprocessor/sub abd 输出名称是 concat。

@nanamare
最新的 tensorflow lite 代码包括一个启用 NNAPI 的 java 接口。

类解释器具有调用函数:setUseNNAPI(true);
你可以直接调用这样的接口。

@张博0325
我已经尝试调用 setUserNNAPI(true);,但是没有效果。
不使用 NNAPI 几乎是类似的推理。
安卓规范:8.1版本。

@nanamare ,您正在运行 ssd-mobilenet 吗? 对于这样的网络,有一个 android NNAPI 不支持的 SQUEEZE 操作。 我问了上面的问题。 对于mobilenet-v1,没问题。

<strong i="5">@andrewharp</strong>  Hi, andrewharp. i just followed your quick steps for converting an SSD MobileNet model to tflite format, and then i tried to  build the demo to use it. But something accurred in apk.
for the tflite from mobilenet_ssd_tflite_v1.zip, everything is ok! i can use mobile to detecter things.
And then i tried to use pet data to fine tune the model from the checkpoint in mobilenet_ssd_tflite_v1.zip. this process is also ok. i check the generated frozen_inference_graph.pb with the object_detection_tutorial.ipynb(https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb). the result shown this pb can used to object detection. And then i followed the script to convert frozen pb to tflite. Then build demo with tflite, unfortunately something wrong ocurred. Then log is written below. 
It seems the Shape of output target [1, 1917, 4] does not match with the shape of the Tensor [1, 1917, 1, 4]. Because i am new to use object detection api, i donot know how to deal with the problem. 
Hope you can point out some solutions, Thx!

移动日志在这里:
04-04 19:46:36.099 28864-28882/org.tensorflow.lite.demo E/AndroidRuntime:致命异常:推理过程:org.tensorflow.lite.demo,PID:28864 java.lang.IllegalArgumentException:输出目标的形状[1, 1917, 4] 与张量 [1, 1917, 1, 4] 的形状不匹配。 在 org.tensorflow.lite.Tensor.copyTo(Tensor.java:44) 在 org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:139) 在 org.tensorflow.demo.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java:226 ) 在 org.tensorflow.demo.DetectorActivity$3.run(DetectorActivity.java:248) 在 android.os.Handler.handleCallback(Handler.java:761) 在 android.os.Handler.dispatchMessage(Handler.java:98) 在android.os.Looper.loop(Looper.java:156) 在 android.os.HandlerThread.run(HandlerThread.java:61)

惊人的! 试图让它在 iOS 上运行。 如何解析张量输出?

interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);

DetectorActivity界面卡在我的项目中,你存在吗,怎么解决?

@zhangbo0325感谢您的详细信息。 由于 NNAPI 不支持挤压,这是否意味着根本不使用 NNAPI 并且推理将保持与原来一样慢? 正如我在前面的评论中提到的,我在 Pixel XL 上的表现真的很差。 我预计推理时间在 80-120 毫秒左右。 谢谢!

@mpeniak ,我向 andrewharp 提出了同样的问题。 我只是在 tensorflow-lite cpu 实现的帮助下运行了 ssd-mobilenet,但性能也很差。

2018 年开发者峰会上的 TensorFlow Lite 演讲展示了 MobileNet 上 3 倍的性能:
https://youtu.be/FAMfy7izB6A?t=530

也许那不是SSD?
可能首先需要权重量化?

我已经尝试过 mobilnet,它的速度要快得多,但这不适用于 mobilnet-ssd...

悲伤的熊猫☹️🐼
@andrewharp知道何时可以使用高性能 SSD 实施吗? 是权重量化的问题吗?

我在 TensorFlowLite 上的 ssd-mobilenet 性能也很差 :(
但是,我还有一个问题。 为什么结果的分数超过1? 不是概率吗?

@a1103304122据我了解,分数是节点“concat”的输出,在 softmax 之前,所以,这不是概率。

在 TOCO 转换期间,使用不同的输入节点(预处理器/子)以及不同的输出节点(concat、concat_1)。 这会跳过一些对 tflite 有问题的部分,直到图形被重构或 TF Lite 达到 TF parity。

有人知道为什么在这个模型中 TFlite 比 TFmobile 慢吗?

@andrewharp可以评论 TF Lite SSD 的性能吗? 量化是否可能/即将到来? 我知道你们正在努力使这一切发生,但如果这只是一个短期的小问题,还是有我们可以应用的解决方案,那就太好了。 😄

@andrewharp感谢您的精彩发帖。 但是,我对您的步骤有一个问题。

在让 TOCO 看到 graphdef 之前去掉有问题的节点

bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB --output=$STRIPPED_PB --frozen_graph=True \
--input_names=预处理器/子 --output_names=concat,concat_1 \
--alsologtostderr

如果我没误会的话,这里你要生产 STRIPPED_PB 对吧? 如果是这样,目前,我们的输入文件的输入应该是 image_tensor。 所以,我不太明白我们为什么要使用 Preprocessor/sub。 你能解释得更详细些吗?

其次,这里我们使用optimize_for_inference,可以使用transform_graph这个工具吗? 因为新的 tensorflow 文档推荐使用 transform_graph 而不是 optimize_for_inference。

@mpeniak你是怎么做的? 请说一些细节。

org.tensorflow.lite.demo E/AndroidRuntime: FATAL EXCEPTION: inference Process: org.tensorflow.lite.demo, PID: 28864 java.lang.IllegalArgumentException: Shape of output target [1, 1917, 4] 与张量的形状 [1, 1917, 1, 4]。

@Haijunlv问题解决了吗? 你能分享解决方案吗?

导入 TF Lite 新的 Android 演示后,我在 OS X 上获得了Error:Plugin with id 'com.android.application' not found.

@csmith105相同的问题! 我设法用 bazel 构建和安装了演示,但我无法在 Android Studio 上编译或运行该项目......这个问题有什么解决方案吗?

@Eddy-zheng 如果你看到冻结图中的节点“concat”,你会发现在 concat op 之后执行了squeeze op。 我认为这就是形状不兼容的原因。 我没有测试挤压操作的速度。 但我认为有两种方法可以解决这个问题。

  1. 改变squeeze和concat op的顺序。 在 ssd_meta_arch.py​​ 中,稍微更改“box_encodings = tf.squeeze(tf.concat(prediction_dict['box_encodings'],axis=1),axis=2)”
  2. 直接杀死轴2处的形状1。在box_predictor.py中,稍微改变“box_encodings =tf.reshape(
    box_encodings, tf.stack([combined_feature_map_shape[0],
    组合特征地图形状[1] *
    组合特征地图形状[2] *
    num_predictions_per_location,
    1、self._box_code_size]))"

实际上我不明白为什么用额外的“1”形状重塑张量。 可能是多余的
同上。
我已经尝试过方法 1 并成功在移动设备中运行模型。 但还是有点慢。 稍后我将尝试方法2,看看它是否可以获得更好的速度

@Haijunlv检测效果如何? @andrewharp演示中的 lite 模型只是从图中删除了所有预处理和后处理节点(数千个),并用几行代码替换它们。 我不确定它会如何工作..

我认为 android studio 和 gradle 问题有一个解决方案。 (如果我错了或者有更好的解决方案,请纠正我):

  • 这不是最好的方法,但是我们可以在 Android Studio 中安装一个 Bazel 插件来“替换”Gradle,我们可以通过 AS 使用 Bazel 构建和运行我们的项目。

  • 我阅读了几篇关于 Bazel 的文章,我在 Quora 中遇到了这个问题。根据答案,tensorflow 将继续使用 Bazel,因为它更好地利用了框架并提供了更好的结果。所以我认为作为这种特殊情况下的开发人员,我们应该适应把 Gradle 留在后面,直到 tensorflow 完全支持它。

@davidfant
您是否设法在 TensorFlow Lite C++ 中获得多个输出?

interpreter->Invoke();
???? output = interpreter->typed_output_tensor<?????>(0);

我正在进步,但我仍然不知道如何在 C++ 中获得输出。 有这方面的文件吗? 这就是我目前所拥有的。 我如何必须访问数据数组才能获得分数?

(fill inputs)
.......
intepreter->Invoke();
const std::vector<int>& results = interpreter->outputs();
TfLiteTensor* outputLocations = interpreter->tensor(results[0]);
TfLiteTensor* outputClasses   = interpreter->tensor(results[1]);
float *data = tflite::GetTensorData<float>(outputClasses);
for(int i=0;i<NUM_RESULTS;i++)
{
   for(int j=1;j<NUM_CLASSES;j++)
   {
      float score = expit(data[i*NUM_CLASSES+j]); // ¿?
    }
}

@JaviBonilla我做了类似的事情,发现它不起作用。 使用 android 演示应用程序的截断,它只会输出太多噪音。 如果您使用 tensorboard 阅读图表,您会发现 lite 模型修剪了数千个后处理节点。 我认为目前的方式行不通。 我希望 tensorflow lite 将来会支持那些后处理节点,而不是要求人们做这种不工作的黑客。

谢谢@YijinLiu。 我看到了您的存储库 tf-cpu,我将查看您的代码以检查我的实现是否正确,并查看结果即使它们不好。

@JaviBonilla当您弄清楚如何使用 C++ 运行时,请告诉我们! 🙌

@davidfant

我仍然需要测试它,但@YijinLiu已经想通了!

看看他的存储库(https://github.com/YijinLiu/tf-cpu)。 特别是,您可以在tf-cpu/benchmark/obj_detect_lite.cc文件中找到如何获取输出, AnnotateMat()函数在Interpreter->Invoke()之后执行。

@JaviBonilla我没有完成 obj_detect_lite.cc,特别是使用先验来解码检测框。
我发现分数在所有情况下都没有意义。 在某些情况下,它会产生过多的噪音。 对于其他情况,它可能会丢失一些好的检测。 我查看了这些节点以将这些中间分数转换为最终的可能性分数。 有数千个节点...

@YijinLiu感谢您澄清这一点。 然后,我认为最好等到 TensorFlow Lite 中包含更多用于对象检测的改进。 无论如何,如果我有时间,我会尝试用 C++ 解码检测框。

@andrewharp

感谢您为制作新的 android 演示项目所做的努力,但是您能否在tensorflow/contrib/lite/examples/android中写一个 readme.md 或一些描述文档,以便我们都可以轻松理解制作 tensorflow lite 的过程? 谢谢~!

您好,我已经成功运行了 ssd_mobilenet_v1_coco_2017_11_17 演示,然后我得到了一个微调的模型。当我在上面运行@andrehentz的进程时,出现了问题:
bazel run tensorflow/contrib/lite/toco:toco -- --input_file=$STRIPPED_PB --output_file=$DETECT_FB --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub --output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

移除未使用的操作之前:586 个操作符,871 个数组(0 个量化)
2018-06-12 15:29:54.273221: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] 在一般图形转换之前:586 个运算符,871 个数组(0 量化)
2018-06-12 15:29:54.300213: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] 一般图形转换后通过 1: 409 个运算符,688 个数组(0 量化)
2018-06-12 15:29:54.309735: I tensorflow/contrib/lite/toco/graph_transformations/graph_transformations.cc:39] 在去量化图转换之前:409 个运算符,688 个数组(0 个量化)
2018-06-12 15:29:54.317395: I tensorflow/contrib/lite/toco/allocate_transient_arrays.cc:329] 总瞬态数组分配大小:2880256 字节,理论最优值:2880128 字节。
2018-06-12 15:29:54.319173: F tensorflow/contrib/lite/toco/tflite/export.cc:330] 标准 TensorFlow Lite 运行时不支持模型中的某些运算符。 如果您有他们的自定义实现,您可以使用 --allow_custom_ops 禁用此错误,或者在调用 tf.contrib.lite.toco_convert() 时设置 allow_custom_ops=True。 以下是您需要自定义实现的运算符列表:RSQRT、SquaredDifference、Stack、TensorFlowShape。

这是我的模型https://drive.google.com/open?id=1IxRSU4VSmVmhUtUpSQew_5anEfxTg3Ca

谁能帮我?
@andrehentz

@JaviBonilla@YijinLiu我有一个Python 实现,我使用 Google 的预置 SSD MobileNet V{1,2} 和 SSDLIte MobileNet V2 模型进行了测试。 请参阅此处的简单文档。

@freedomtan您使用哪个版本的 tf ? tf 1.8 ?

tflite解释器 Python 绑定 (29c129c6) 后的 @hengshanji 主分支。 我认为 1.8 没有绑定。

@freedomtan tf1.8 具有解释器 Python 绑定,但我遇到了这样的问题“nnapi 错误:无法打开库 libneuralnetworks.so”。 从哪里得到这个 .so 或如何生成它? 谢谢。

忽略它:) 它适用于 Android NNAPI。

@freedomtan你是在设备上还是在电脑上测试了这个例子? 当我在电脑上测试它时,使用 android-28/x86 libneuralnetworks.so,它显示错误“Aborting since tflite returned failure”。

正如我所说,请忽略 NNAPI 问题。 你不应该有一个工作libneuralnetwork.so 。 我在运行 Ubuntu 的 x86 和运行 Debian 的 ARMv8 板上测试了我的脚本。

@freedomtan ,感谢分享代码和文档。

基于存储库(https://github.com/YijinLiu/tf-cpu)。 我已经更新了 tf-cpu/benchmark/obj_detect_lite.cc 以获取输出。 在函数 AnnotateMat() 中添加 decodeCenterSizeBoxes 代码来处理 output_locations,然后对这些结果执行 nms。
同时,使用https://github.com/tensorflow/tensorflow/issues/14688生成libtensorflow-lite.a,可以在运行Ubuntu的x86和ssdlite_mobilenet_v2_coco_2018_05_09中的tflite模型的android设备上运行。 tar.gz.
谢谢大家。

@WeiboXu可以在这里分享代码和模型吗?

@freedomtan在你的python 实现代码中,有一个文件“/tmp/box_priors.txt”,你知道如何生成这个文件吗? 或者这个文件中的数据是如何计算的? 对300X300的图片进行推理没有问题,但是对224X224的图片进行推理,推理精度会下降

@freedomtan , @andrewharp , 按照这个指令的 prev 模型在最新的 TFLite Demo中无法工作,无论是量化还是浮动,因为最新的 TFLite demo 中的 tflite 模型需要 4 个输出,但 prev 模型只有 2 个输出(连接,连接1)。

请帮忙,谢谢!

这些说明目前正在更新。 将在下周提供更新说明的链接。

@frontword /tmp/box_priors.txt中的内容是用于后期处理的框。 如果您使用@WenguoLi提到的较新的,则不需要它。 但是,据我所知,这些后处理操作是作为 TF Lite 自定义操作实现的。 这意味着如果没有进一步的努力,您将无法使用 NNAPI 加速器来加速它们。

对于图像大小问题,是的,我认为将 224x224 图像输入 SSD300(Google 发布的模型是用 300x300 图像训练的)并且精度变差并不意外。

@WenguoLi在我看来,您提到的更新模型很容易处理。 请参阅我的更新脚本。 下图由

python  tensorflow/contrib/lite/examples/python/object_detection.py --image /tmp/image2.jpg  --show_image True

image

要修复超过 1 的推理结果分数,可以使用 Java 方法 TrackedObject.getCurrentCorrelation() 因为它似乎总是返回小于 1 的值(虽然不确定它是否正确)。 TFLite Android 示例使用 Recognition.getConfidence() 似乎总是返回大于 1 的值

@mpeniak您在 Movidius 上运行了 ssd mobilenet tflite 模型。 我也打算做类似的事情。 你能指导一下你是怎么做到的吗?

@achowdhery嗨,我在此处(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/examples/android/app)看到了最新 android 演示的构建说明的一些更新,但它没有说明我们如何将冻结的 pb 模型实际转换为 tflite 模型(最新演示中使用的量化检测.tflite)。 关于量化模型转换流程的任何进一步说明? 另外,我认为我们应该首先按照此处(https://www.tensorflow.org/performance/quantization)的说明使用假量化操作进行量化训练,然后执行模型转换,对吗? 另外,是否可以在最新的 android demo 中启用 NNAPI? 我尝试在 TFLiteObjectDetectionAPIModel.java 中使用 tfLite.setUseNNAPI(true),但它在运行 Android 8.1 的 Pixel 2 上崩溃(它可以在没有 NNAPI 的情况下正常工作)。 有什么建议? 谢谢!

@tenoyart “是否可以在最新的 android 演示中启用 NNAPI?”的简短回答? 应该是NO。 不是那么简短的答案是,如果您修改 TF Lite 解释器执行诸如拆分模型或将相应的自定义操作添加到 NNAPI 之类的操作,那么它是有可能的。

@achowdhery我看到了你的一篇 TensorFlow 博客文章。 这是您提到的指令还是更多指令?

是的。 这是在 Android 上训练和服务对象检测模型的说明。

@freedomtan感谢分享脚本。
在您最新的带有后处理的脚本中,您使用的是哪个模型文件?
您是否指定了 optimize_for_inference.py 的参数,例如
--input_names="预处理器/子"
--output_names="detection_boxes,detection_scores,num_detections,detection_classes"

你看到有/没有后处理有什么不同吗?

谢谢!

有没有办法将具有 4 个输出的 SqueezeNet 模型转换为 tflite?

@chanchanzhang请按照https://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus中教程末尾的新说明进行操作
请注意,这使用与使用 optimize_for_inference.py 不同的工作流程

@ashwaniag如果您想用 SqueezeNet 分类器替换 Mobilenet,同时保留 SSD 用于检测,这对于当前工作流程来说很好。

@achowdhery很高兴在 ssd mobilenet v1 上看到 TF Lite 模型。 TF Lite 是否完全支持 ssdlite mobilenet v2?

@tenoyart是的。 任何 Mobilenet SSD 都将通过此管道工作。 我们还没有在开源中发布相应的 tflite 文件。 如果您遇到问题,请提交错误。

@chanchanzhang正如@achowdhery所说,请使用object_detection/export_tflite_ssd_graph.py而不是optimized_for_inference.py 。 我使用的 tflite 模型文件来自 Android 示例使用的模型文件。 你可以在这里得到它。

@achowdhery我认为ssd_mobilenet_v1_quantized_cocossd_mobilenet_v1_0.75_depth_quantized_coco的检查点中没有 FakeQuant 节点和张量。 你能检查一下吗?

@freedomtan在使用 object_detection/export_tflite_ssd_graph.py 后,我确实在导出的图中看到了 weight_quant 和 act_quant 节点。
请提供您如何验证它没有 Fakequant 节点的屏幕截图或确切说明。
我也能够成功转换检查点

@achowdhery感谢您的检查。 当我在这两个上运行export_tflite_ssd_graph.py时,我无法获得 tflite 模型,所以我检查了检查点。 我所做的是类似的

curl http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_03.tar.gz | tar xzvf -
cd ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_03
strings model.ckpt.index  |grep quant

什么都没有出现。

@andrewharp 非常感谢您的 cutosm 推理类TFLiteObjectDetectionAPIModel.java ,我已经用您的 ssd mobilenet v1 tflite mobilenet_ssd_tflite_v1.zip进行了尝试,但是当应用程序启动时,当我调用时,函数识别图像(最终位图位图)似乎存在问题tfLite.runForMultipleInputsOutputs(inputArray, outputMap); 它抛出这个异常

07-18 10:37:02.416 19957-19996/com.app.cerist.realtimeobjectdetectionapi E/AndroidRuntime: FATAL EXCEPTION: Camera
    Process: com.app.cerist.realtimeobjectdetectionapi, PID: 19957
    java.lang.IllegalArgumentException: Output error: Outputs do not match with model outputs.
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:170)
        at com.app.cerist.realtimeobjectdetectionapi.ImageClassifierTFLiteAPI.recognizeImage(ImageClassifierTFLiteAPI.java:207)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.classifyFrame(MainActivity.java:421)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.access$1000(MainActivity.java:48)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity$4.run(MainActivity.java:455)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.os.HandlerThread.run(HandlerThread.java:61)
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi V/Process: killProcess [19957] Callers=com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:99 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 <bottom of call stack> 
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi I/Process: Sending signal. PID: 19957 SIG: 9

错误表示输出数组的长度大于输入数组的长度
这是 Interpreter.java 中的条件

public void runForMultipleInputsOutputs(Object[] inputs, <strong i="7">@NonNull</strong> Map<Integer, Object> outputs) {
        if (this.wrapper == null) {
            throw new IllegalStateException("Internal error: The Interpreter has already been closed.");
        } else {
            Tensor[] tensors = this.wrapper.run(inputs);
            if (outputs != null && tensors != null && outputs.size() <= tensors.length) {
                int size = tensors.length;
                Iterator var5 = outputs.keySet().iterator();
            }
       }
}

这是我的输入和输出数组:

d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
d.imgData.order(ByteOrder.nativeOrder());
d.intValues = new int[d.inputSize * d.inputSize];
 imgData.rewind();
        for (int i = 0; i < inputSize; ++i) {
            for (int j = 0; j < inputSize; ++j) {
                int pixelValue = intValues[i * inputSize + j];
                if (isModelQuantized) {
                    // Quantized model
                    imgData.put((byte) ((pixelValue >> 16) & 0xFF));
                    imgData.put((byte) ((pixelValue >> 8) & 0xFF));
                    imgData.put((byte) (pixelValue & 0xFF));
                } else { // Float model
                    imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
                    imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

输出数组:

// Copy the input data into TensorFlow.
        Trace.beginSection("feed");
        outputLocations = new float[1][NUM_DETECTIONS][4];
        outputClasses = new float[1][NUM_DETECTIONS];
        outputScores = new float[1][NUM_DETECTIONS];
        numDetections = new float[1];

        Object[] inputArray = {imgData};
        Map<Integer, Object> outputMap = new HashMap<>();
        outputMap.put(0, outputLocations);
        outputMap.put(1, outputScores);
        outputMap.put(2, numDetections);
        outputMap.put(3, outputClasses);
        Trace.endSection();

和推理:

// Run the inference call.
        Trace.beginSection("run");
        Log.d("TAG_INPUT",""+String.valueOf(inputArray.length));
        Log.d("TAG_OUTPUT",""+String.valueOf(outputMap.size()));

        tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
        Trace.endSection();

我不明白这个错误的含义,因为我所做的与您的 TFLiteObjectDetectionAPIModel.java 类完全相同。
谢谢你的帮助

@achowdhery嗨,在您的博客之后,我从 ssd_mobilenet_v1_coco_2017_11_17 转换了模型。 但是,当我在 tflite_demo.apk 中使用转换后的 mobilenet_ssd.tflite 时,出现以下错误:

    java.lang.IllegalArgumentException: Cannot copy between a TensorFlowLite tensor with shape [1, 1917, 4] and a Java object with shape [1, 10, 4].

任何想法为什么我得到它? 谢谢。

这是形状不匹配,因为预期的输出张量大小为 1,10,4 而不是 1,1917,4。 对于旧模型文件,您需要退回到 May 的演示应用程序版本。 否则请使用最新发布的机型进行转换。

@achowdhery我将自己的模型转换为 tflite 并在我运行它时。 解释器->invoke() 调用会引发 seg 错误。 知道可能出了什么问题吗?

@ashwaniaghttps://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus-b78971cf1193上下载模型
为你编译?
如果是,那么当您遇到段错误时,请提供您现在正在使用的新说明?
输入类型/大小等可能不匹配。

@achowdhery它奏效了。 我给出了错误的 input_arrays。 不管怎么说,多谢拉!

更新ssd_mobilenet_v1_quantized_cocossd_mobilenet_v1_0.75_depth_quantized_coco工作,如果你按照教程。 谢谢@achowdhery。

我在示例演示应用程序中查看TFLiteObjectDetectionAPIModel.javaoutputLocationsoutputClassesoutputScoresnumDetections是否有理由每个recognizeImage调用上分配? 似乎它们是预先分配的。
我已经尝试使用预分配运行代码,它似乎工作正常,但我只是想确保没有什么会在以后引入问题。

预分配可能更有效。 你在哪里预分配你可能预见到的问题?

感谢@achowdhery 的回复。 我将按原样保留静态create方法中的预分配。 我唯一担心的是代码似乎被编写为使用预分配(静态方法预分配数组),但由于某种原因,数组在每次调用时都会重新分配。

@achowdhery ,我测试了新的 Android tflite 应用演示。 它适用于ssd_mobilenet_v1_coco、ssd_mobilenet_v1_0.75_depth_coco、ssd_mobilenet_v1_quantized_coco
但是对于其他 ssd-mobilenet 模型,我得到了这个例外:

07-25 07:41:25.292 31515-31532/org.tensorflow.lite.demo E/AndroidRuntime: FATAL EXCEPTION: inference
    Process: org.tensorflow.lite.demo, PID: 31515
    java.lang.ArrayIndexOutOfBoundsException: length=160; index=-2147483648
        at java.util.Vector.elementData(Vector.java:734)
        at java.util.Vector.get(Vector.java:750)
        at org.tensorflow.demo.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java:218)
        at org.tensorflow.demo.DetectorActivity$3.run(DetectorActivity.java:249)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)

tflite 模型产生了错误的类索引。 该异常会在检测良好几秒钟后导致应用程序崩溃。
ssd_mobilenet_v1_ppn_coco会产生错误的混乱边界框和标签。

PPN 是浮点模型:您是否使用浮点转换命令转换 TFLITE 模型。
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md
然后你还需要在DetectorActivity.java中更改以下内容:
私有静态最终布尔 TF_OD_API_IS_QUANTIZED = true;

我知道那个配置。 实际上,当该配置错误时,该应用程序根本无法运行。
你能看到 ArrayIndexOutOfBoundsException 吗? 我也试过你的教程的docker,但它是一样的。

好的。 请用准确的复制说明提交一个新的 GitHub 问题。 PPN 模型是 Java 应用程序的新功能请求 - 我们会在可以优先处理时回复

谢谢。 ArrayIndexOutOfBoundsException 也发生在 ssd_mobilenet_v1_0.75_depth_quantized_coco、ssdlite_mobilenet_v2_coco。 与 PPN 的不同之处在于,它会在应用程序因该异常而崩溃之前生成正确的结果。

@achowdhery无论如何使用 legacy/train.py 为 tflite 训练具有 4 个输出的量化模型,因为新的 model_main.py 有错误?
https://github.com/tensorflow/models/issues/4798

@ashwaniag您可以区分这两个代码并添加添加量化的部分:请注意,graph_rewriter 函数是添加量化操作的地方。

@achowdheryhttps ://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md
是否有示例或示例代码说明如何在 iOS 中执行相同操作。 到目前为止,我发现的最接近的东西是这个https://github.com/YijinLiu/tf-cpu/blob/master/benchmark/obj_detect_lite.cc ,它并不总是有效。

当前的 iOS 演示应用程序不适用于 ssd 和浮动模型。

@achowdhery我使用 tensorflow v1.9 训练了我的模型。 使用博客中的步骤转换为 tflite。 我没有得到任何检测。 你对此有什么想法吗?

@ashwaniag可可还是宠物? 请使用准确的复制说明打开一个新错误。 其他 GitHub 用户已确认使用 Tensorflow 1.10

@achowdhery这是我自己的数据集。 我为 mobilenetv2 架构进行了培训。 当我运行 .pb 模型(张量流模型)时,我得到
未找到:在 VAL5-04 上运行的二进制文件中未注册操作类型“NonMaxSuppressionV3”。 确保在此进程中运行的二进制文件中注册了 Op 和 Kernel。

你觉得有关系吗?

@ashwaniag请打开一个新错误并提供准确的可重现说明

@ashwaniag检查这两个问题,我遇到了类似的问题: # 10254 和#19854

@achraf-boussaada 谢谢! 我修好了它。 这是一个版本不匹配的问题。
@achowdhery现在,问题是完整的 tensorflow 模型给了我很好的结果,但 tflite 模型给出了非常糟糕的结果。

@ashwaniag请定义非常糟糕的结果。 你有小物件吗? 请附上模型检查点、管道配置和标签文件以及示例图像,以帮助我们重现问题。 谢谢

@oopsodd你好,我也得到了错误的类索引。 它抱怨“java.lang.ArrayIndexOutOfBoundsException:长度=10;索引=-739161663”,你能帮帮我吗?

注意我已经为 iOS 和 Android 创建了 TensorFlow Lite SSD(对象检测)最小工作示例; https://github.com/baxterai/tfliteSSDminimalWorkingExample。 iOS 版基于 YijinLiu 的 obj_detect_lite.cc(带有 WeiboXu 的 nms 功能),Android 版基于https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/examples/安卓tflDetect。 它消除了内部摄像头等所有开销,并隔离了检测对象和显示检测框所需的核心代码。

@baxterai 干得好! 谢谢,我会测试它。

感谢大家的出色工作! 关于最近添加的后处理操作,我还有另一个问题。

预训练的ssd_mobilenet_v1_quantized_coco的输出
目前仅限于框架中的前10 个检测,即使 models/research/object_detection/samples/configs/ 中的默认配置像
ssd_mobilenet_v1_quantized_300x300_coco14_sync.config 都指定了总检测的上限。

post_processing { batch_non_max_suppression { score_threshold: 1e-8 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 100 } score_converter: SIGMOID }

这是通过使用这种管道配置重新训练网络来解决的,还是
'TFLite_Detection_PostProcess' 被其他配置固定为 10?

@Georg-W 您还需要更改 export_tflite_ssd_graph.py 中的最大检测。 有一个命令行选项。

@achowdhery啊谢谢! 这就是我错过的。

@andrewharp 非常感谢您的 cutosm 推理类TFLiteObjectDetectionAPIModel.java ,我已经用您的 ssd mobilenet v1 tflite mobilenet_ssd_tflite_v1.zip进行了尝试,但是当应用程序启动时,当我调用时,函数识别图像(最终位图位图)似乎存在问题tfLite.runForMultipleInputsOutputs(inputArray, outputMap); 它抛出这个异常

07-18 10:37:02.416 19957-19996/com.app.cerist.realtimeobjectdetectionapi E/AndroidRuntime: FATAL EXCEPTION: Camera
    Process: com.app.cerist.realtimeobjectdetectionapi, PID: 19957
    java.lang.IllegalArgumentException: Output error: Outputs do not match with model outputs.
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:170)
        at com.app.cerist.realtimeobjectdetectionapi.ImageClassifierTFLiteAPI.recognizeImage(ImageClassifierTFLiteAPI.java:207)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.classifyFrame(MainActivity.java:421)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity.access$1000(MainActivity.java:48)
        at com.app.cerist.realtimeobjectdetectionapi.MainActivity$4.run(MainActivity.java:455)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:159)
        at android.os.HandlerThread.run(HandlerThread.java:61)
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi V/Process: killProcess [19957] Callers=com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:99 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 <bottom of call stack> 
07-18 10:37:02.436 19957-19996/com.app.cerist.realtimeobjectdetectionapi I/Process: Sending signal. PID: 19957 SIG: 9

错误表示输出数组的长度大于输入数组的长度
这是 Interpreter.java 中的条件

public void runForMultipleInputsOutputs(Object[] inputs, <strong i="14">@NonNull</strong> Map<Integer, Object> outputs) {
        if (this.wrapper == null) {
            throw new IllegalStateException("Internal error: The Interpreter has already been closed.");
        } else {
            Tensor[] tensors = this.wrapper.run(inputs);
            if (outputs != null && tensors != null && outputs.size() <= tensors.length) {
                int size = tensors.length;
                Iterator var5 = outputs.keySet().iterator();
            }
       }
}

这是我的输入和输出数组:

d.imgData = ByteBuffer.allocateDirect(1 * d.inputSize * d.inputSize * 3 * numBytesPerChannel);
d.imgData.order(ByteOrder.nativeOrder());
d.intValues = new int[d.inputSize * d.inputSize];

```
imgData.rewind();
for (int i = 0; i < inputSize; ++i) {
for (int j = 0; j < inputSize; ++j) {
int pixelValue = intValues[i * inputSize + j];
如果(isModelQuantized){
// 量化模型
imgData.put((byte) ((pixelValue >> 16) & 0xFF));
imgData.put((byte) ((pixelValue >> 8) & 0xFF));
imgData.put((byte) (pixelValue & 0xFF));
} else { // 浮点模型
imgData.putFloat((((pixelValue >> 16) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
imgData.putFloat((((pixelValue >> 8) & 0xFF) - IMAGE_MEAN) / IMAGE_STD);
imgData.putFloat(((pixelValue & 0xFF) - IMAGE_MEAN) / IMAGE_STD);

The outputs array :

// 将输入数据复制到 TensorFlow。
Trace.beginSection("feed");
outputLocations = new float[1][NUM_DETECTIONS][4];
outputClasses = new float[1][NUM_DETECTIONS];
outputScores = new float[1][NUM_DETECTIONS];
numDetections = 新浮点数[1];

    Object[] inputArray = {imgData};
    Map<Integer, Object> outputMap = new HashMap<>();
    outputMap.put(0, outputLocations);
    outputMap.put(1, outputScores);
    outputMap.put(2, numDetections);
    outputMap.put(3, outputClasses);
    Trace.endSection();
And the Inference :

// 运行推理调用。
Trace.beginSection("运行");
Log.d("TAG_INPUT",""+String.valueOf(inputArray.length));
Log.d("TAG_OUTPUT",""+String.valueOf(outputMap.size()));

    tfLite.runForMultipleInputsOutputs(inputArray, outputMap);
    Trace.endSection();

```
我不明白这个错误的含义,因为我所做的与您的 TFLiteObjectDetectionAPIModel.java 类完全相同。
谢谢你的帮助

我有同样的问题..有解决方案吗?
谢谢..

@Georg-W 您还需要更改 export_tflite_ssd_graph.py 中的最大检测。 有一个命令行选项。

你好

我正在尝试检测图像中的 10 多个对象(这是默认设置)
我正在使用以下命令:
bazel run -c opt tensorflow/contrib/lite/ toco:toco -- --input_file=$OUTPUT_DIR/tflite_graph.pb --output_file=$OUTPUT_DIR/mobile_net_500.tflite --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor -- output_arrays='TFLite_Detection_PostProcess',' TFLite_Detection_PostProcess:1 ',' TFLite_Detection_PostProcess:2 ',' TFLite_Detection_PostProcess:3 ' --inference_type=FLOAT --max_detections=500 --max_classes_per_detection=1 --allow_custom_ops

我也修改了
export_tflite_ssd_graph.py
flags.DEFINE_integer('max_detections', 500 <--- 而不是 10,
'要显示的最大检测数(框)。')
flags.DEFINE_integer('max_classes_per_detection', 1,
'每个检测框显示的类数。')

但仍然在 android [1,10,4] 中提供 10 个对象作为输出。

任何想法?

我也会对@KaviSanth问题的解决方案感兴趣。

@Stevelb的这个解决方案应该可以工作。 您可能希望可视化冻结图以确保正确设置 max_detections。

@achowdhery感谢您的回复。 我尝试执行@andrewharp编写的命令,但出现以下错误。 确实,toco 不在这个地方。 我正在使用 github 存储库中的主版本和 r1.95 版本。

bazel 运行 tensorflow/contrib/lite/ toco:toco -- --input_file=$STRIPPED_PB --output_file=$DETECT_FB --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=预处理器/sub - -output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr
信息:调用 ID:0e58a5ef-9fee-4619-b760-aeb1c83c9661
错误:跳过“tensorflow/contrib/lite/ toco:toco ”:没有这样的包“tensorflow/contrib/lite/toco”:在包路径上找不到构建文件
警告:目标模式解析失败。
错误:没有这样的包'tensorflow/contrib/lite/toco':在包路径上找不到BUILD文件
信息:经过时间:0.179s
信息:0 个进程。
失败:构建未成功完成(已加载 0 个包)
失败:构建未成功完成(已加载 0 个包)
我必须修改我正在从 git 提取的本地 tensorflow 文件夹中执行这些命令。

我可以在 tensorflow/lite/toco 下找到一个 toco,我只是在测试它是否有效。
好的,使用这个 toco 似乎可以工作,除此之外,您必须将 $DETECT_FB 路径更改为 $PWD/ssd_mobilenet.tflite,因为在 contrib/lite 文件夹中只有一些 python 位于其他位置。

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android (https://github.com/tensorflow/tensorflow/blob) 在 DetectorActivity 中添加 .tflite 文件时出现运行时错误/master/tensorflow/examples/android/src/org/tensorflow/demo/DetectorActivity.java) 与该行

private static final String TF_OD_API_MODEL_FILE =
            "file:///android_asset/ssd_mobilenet_v1.tflite";

E/AndroidRuntime: 致命异常: main
进程:myProcess,PID:32611
java.lang.RuntimeException:找不到输入节点“image_tensor”
在 myPackage.myClass.TensorFlowObjectDetectionAPIModel.create(TensorFlowObjectDetectionAPIModel.java:106)

不能在该应用程序中使用 .tflite 模型吗?

@defaultUser3214您正在检测应用程序中使用分类器模型。 MobileNet v1 是分类模型。 请使用 MobileNet SSD 型号

@achowdhery谢谢! 使用 wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz中的模型会导致该错误。 但我以为这是ssd版本?

但是使用 ssd_mobilenet_v1_android_export.pb 转换为之前作为 .pb 工作的 .tflite 会产生相同的错误。

@defaultUser3214这是旧版本的模型,无法在 2018 年 7 月发布的最新演示应用程序中使用。请在检测模型动物园下载 2018 年 7 月的最新模型:它们确实在应用程序中工作。 如果这仍然被阻止,请打开一个新问题。

@SteveIb您还需要在 TFLiteObjectDetectionAPIModel.java 中更改 NUM_DETECTIONS = 500

无法将 ssdmobilenet v1 .pb 转换为 .tflite
通过Tensorflow对象检测api生成的pb @aselle @achowdhery

这方面有什么进展吗? 尝试将 frozen_inference_graph.pb 转换为 .TFLITE 文件但出现错误

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 49152 bytes and a ByteBuffer with 270000 bytes

用于 Android 中的自定义对象检测。 关于不同转换方法的任何想法? 按照此处的教程在 Windows 10 上传输学习的 ssd_mobilenet_v1_pets: https ://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10

这方面有什么进展吗? 尝试将 frozen_inference_graph.pb 转换为 .TFLITE 文件但出现错误

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 49152 bytes and a ByteBuffer with 270000 bytes

用于 Android 中的自定义对象检测。 关于不同转换方法的任何想法? 按照此处的教程在 Windows 10 上传输学习的 ssd_mobilenet_v1_pets: https ://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10

只是为了跟进这一点并帮助遇到同样错误的其他人——这是由于使用了不正确的模型检查点进行训练造成的。 要使用 .tflite 在 Android 上工作,初始模型必须是 MobileNet 并且还必须是量化的,并且在 .config 文件中将包含这部分代码或类似内容:

graph_rewriter { quantization { delay: 48000 weight_bits: 8 activation_bits: 8 } }

它现在在tensorflow/contrib/lite/examples/android上线! 这是原始 TF Android 演示的一个更完整的移植版(仅缺少 Stylize 示例),并将替换 tensorflow/contrib/lite/java/demo 中的其他演示。

转换后的 TF Lite flatbuffer 可以在mobilenet_ssd_tflite_v1.zip中找到,您可以在TFLiteObjectDetectionAPIModel.java中找到 Java 推理实现。 请注意,这与原始 TF 实现的不同之处在于,这些盒子必须在 Java 中手动解码,并且需要在应用程序资产中打包一个盒子之前的 txt 文件(我认为上面模型 zip 中包含的那个应该对大多数人都有效图表)。

在 TOCO 转换期间,使用不同的输入节点(预处理器/子)以及不同的输出节点(concat、concat_1)。 这会跳过一些对 tflite 有问题的部分,直到图形被重构或 TF Lite 达到 TF parity。

以下是将 SSD MobileNet 模型转换为 tflite 格式并构建演示以使用它的快速步骤:

# Download and extract SSD MobileNet model
wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2017_11_17.tar.gz
tar -xvf ssd_mobilenet_v1_coco_2017_11_17.tar.gz 
DETECT_PB=$PWD/ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb
STRIPPED_PB=$PWD/frozen_inference_graph_stripped.pb
DETECT_FB=$PWD/tensorflow/contrib/lite/examples/android/assets/mobilenet_ssd.tflite

# Strip out problematic nodes before even letting TOCO see the graphdef
bazel run -c opt tensorflow/python/tools/optimize_for_inference -- \
--input=$DETECT_PB  --output=$STRIPPED_PB --frozen_graph=True \
--input_names=Preprocessor/sub --output_names=concat,concat_1 \
--alsologtostderr

# Run TOCO conversion.
bazel run tensorflow/contrib/lite/toco:toco -- \
--input_file=$STRIPPED_PB --output_file=$DETECT_FB \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--input_shapes=1,300,300,3 --input_arrays=Preprocessor/sub \
--output_arrays=concat,concat_1 --inference_type=FLOAT --logtostderr

# Build and install the demo
bazel build -c opt --cxxopt='--std=c++11' //tensorflow/contrib/lite/examples/android:tflite_demo
adb install -r -f bazel-bin/tensorflow/contrib/lite/examples/android/tflite_demo.apk

这就像一个魅力!

此页面是否有帮助?
0 / 5 - 0 等级