Android上的Tensorflow推论找不到'Iterator'op。没有注册任何OpKernel支持Op

时间:2018-07-13 19:10:44

标签: android python tensorflow

java.lang.IllegalArgumentException:没有注册任何OpKernel支持这些属性的Op'Iterator'。

我正在尝试在Android设备上运行经过训练的张量流模型。我尝试在android移动设备上运行的模型在推理图中使用了Iterator操作。我正在尝试在新创建的Android Studio项目上运行此程序。

我正在使用

  • Android Studio 3.1.3
  • Android NDK 14b
  • Andorid SDK v28
  • Bazel 0.14.1
  • Tensorflow 1.8.0(用于培训以及创建.so和.jar文件)

我使用README https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/android中的该bazel指南从Tensorflow生成了Tensorflow .jar文件和.so文件。.so文件大小为14.1 MB。

我在Android Studio项目的l​​ibs目录下添加了.jar,并在jniLibs / armeabi-v7a目录下添加了.so文件。尝试在Android Studio应用程序中进行推断后,出现以下错误。

I/TensorFlowInferenceInterface: Checking to see if TensorFlow native methods are already loaded
E/art: No implementation found for long org.tensorflow.contrib.android.RunStats.allocate() (tried Java_org_tensorflow_contrib_android_RunStats_allocate and Java_org_tensorflow_contrib_android_RunStats_allocate__)
I/TensorFlowInferenceInterface: TensorFlow native methods not found, attempting to load via tensorflow_inference
I/TensorFlowInferenceInterface: Successfully loaded TensorFlow native methods (RunStats error may be ignored)
I/TensorFlowInferenceInterface: Model load took 764ms, TensorFlow version: 1.8.0
I/TensorFlowInferenceInterface: Successfully loaded model from 'file:///android_asset/laptop_frozen_graph_init_tables.pb'
E/TensorFlowInferenceInterface: Failed to run TensorFlow inference with inputs:[batch_size, src_data], outputs:[index_to_string_Lookup]
E/AndroidRuntime: FATAL EXCEPTION: Thread-5769
                  Process: com.example.student.projecttest, PID: 6805
                  java.lang.IllegalArgumentException: No OpKernel was registered to support Op 'Iterator' with these attrs.  Registered devices: [CPU], Registered kernels:
                    <no registered kernels>

                     [[Node: Iterator = Iterator[container="infer", output_shapes=[[?,?], [?]], output_types=[DT_INT32, DT_INT32], shared_name=""]()]]
                      at org.tensorflow.Session.run(Native Method)
                      at org.tensorflow.Session.access$100(Session.java:48)
                      at org.tensorflow.Session$Runner.runHelper(Session.java:298)
                      at org.tensorflow.Session$Runner.run(Session.java:248)
                      at org.tensorflow.contrib.android.TensorFlowInferenceInterface.run(TensorFlowInferenceInterface.java:228)
                      at org.tensorflow.contrib.android.TensorFlowInferenceInterface.run(TensorFlowInferenceInterface.java:197)
                      at org.tensorflow.contrib.android.TensorFlowInferenceInterface.run(TensorFlowInferenceInterface.java:187)
                      at com.example.student.projecttest.MainActivity.translateToFrench(MainActivity.java:79)
                      at com.example.student.projecttest.MainActivity$1$1.run(MainActivity.java:42)

我还运行了tensorflow / python / tools / print_selective_registration_header工具,从冻结的.pb模型生成ops_to_register.h文件,在ops_to_register.h文件中,您可以看到Iterator ops

...
|| isequal(op, "GreaterEqual")
     || isequal(op, "HashTableV2")
     || isequal(op, "Identity")
     || isequal(op, "InitializeTableFromTextFileV2")
     || isequal(op, "Iterator")
     || isequal(op, "IteratorGetNext")
     || isequal(op, "Less")
     || isequal(op, "LessEqual")
     || isequal(op, "LogicalAnd")
     || isequal(op, "LogicalNot")
...

...
"LookupTableOp<lookup::HashTable<int64, string>, int64, string>",
"LookupTableOp<lookup::HashTable<string, int64>, string, int64>",
"IdentityOp",
"InitializeTableFromTextFileOp",
"IteratorHandleOp",
"IteratorGetNextOp",
"BinaryOp<CPUDevice, functor::less<int32>>",
...

因此ops_to_register.h文件找到了操作

我尝试使用其他bazel命令查看它是否包含正确的操作:

bazel build -c opt --copt="-DSELECTIVE_REGISTRATION" --copt="-DSUPPORT_SELECTIVE_REGISTRATION" //tensorflow/contrib/android:libtensorflow_inference.so --crosstool_top=//external:android/crosstool --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --cpu=armeabi-v7a

将ops_to_register.h文件移动到tensorflow / core / framework文件夹后,我运行了此文件。产生一个4.1 MB的.so文件

bazel build -c opt --copt=-D__ANDROID_TYPES_FULL__ //tensorflow/contrib/android:libtensorflow_inference.so --crosstool_top=//external:android/crosstool --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --cpu=armeabi-v7a

这个bazel命令应该包含Tensorflow库中的所有内容,我相信这会产生17.2 MB的文件。

我还尝试添加此gradle文件。

implementation 'org.tensorflow:tensorflow-android:+'

但是失败并出现相同的错误。

我可以加载TensorFlowInferenceInterface,从那里获取图形,并迭代所有操作及其名称,但是在进行推断时失败。

为确保我可以通过按名称加载张量和操作来运行模型。我做了一个小的Tensorflow脚本,可以进行预测。

要运行的TF Python脚本:

  1. “ init_all_tables”操作初始化表。

  2. “ MakeIterator”操作,用于初始化迭代器(同时提供一些文本数据和批处理大小)。

  3. 运行“ index_to_string_Lookup:0”张量以获取输出。

在使用.run的android设备上,将抛出此错误。

Example: inferenceInterface.run(new String[]{"init_all_tables"});

将引发与前面提到的相同的“未注册OpKernel”错误。

所以我认为问题出在寻找Iterator op。

我还尝试了一些更改BUILD文件,以按照此处的建议进行尝试: https://github.com/tensorflow/tensorflow/issues/11804#issuecomment-318415228

当弄乱该建议中提到的构建文件时,它在接近完成时会在最后抛出错误,我相信我可能做错了。 我不太确定如何更改tensorflow / core / kernel中的BUILD,因为迭代器文件位于/ tensorflow / core / lib / io /目录中,而不位于内核目录中。

任何帮助将不胜感激

0 个答案:

没有答案