java.lang.IllegalArgumentException:没有注册任何OpKernel支持这些属性的Op'Iterator'。
我正在尝试在Android设备上运行经过训练的张量流模型。我尝试在android移动设备上运行的模型在推理图中使用了Iterator操作。我正在尝试在新创建的Android Studio项目上运行此程序。
我正在使用
我使用README https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/android中的该bazel指南从Tensorflow生成了Tensorflow .jar文件和.so文件。.so文件大小为14.1 MB。
我在Android Studio项目的libs目录下添加了.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脚本:
“ init_all_tables”操作初始化表。
“ MakeIterator”操作,用于初始化迭代器(同时提供一些文本数据和批处理大小)。
运行“ 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 /目录中,而不位于内核目录中。
任何帮助将不胜感激