尝试将 ML onnx 模型合并到 Android 应用程序中

问题描述

我有一个经过训练的 onnx 模型,我想将其合并到一个 android 应用程序中。 我实际上正在从事一个 uni 项目,结合 ML 和 Android 开发。

经过长时间的研究,由于我不想使用 python 私有 REST API,我得出的结论是有两种方法可以从这里继续:我可以尝试将我的 onnx 模型转换为 TF 模型然后通过TFLite Converter API生成TFLite模型,或者用onnxruntime试试。

我用 TFLite 尝试了第一种方法,使用来自 this post 的答案,因此代码如下:

import onnx

from onnx_tf.backend import prepare

onnx_model = onnx.load("input_path")  # load onnx model
tf_rep = prepare(onnx_model)  # prepare tf representation
tf_rep.export_graph("output_path")  # export the model

但我在第一次从 .onnx 到 .pb 的转换中陷入困境,因为我认为 onnx-tf 不支持动态维度(我的模型支持)。我不断收到 "Input size (depth of inputs) must be accessible via shape inference,"RuntimeError: Node name is not unique in your model. Please recreate your model with unique node name. 和类似错误

我也尝试使用 onnxruntime,但我似乎无法“为具有 nnapi 支持的 Android 创建最小构建”。构建时出现此错误

[1/67] Building CXX object CMakeFiles/libprotobuf.dir/C_/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc.obj
Failed: CMakeFiles/libprotobuf.dir/C_/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc.obj
C:\PROGRA~2\CODEBL~1\MinGW\bin\C__~1.EXE -DGOOGLE_PROTOBUF_CMAKE_BUILD -DHAVE_PTHREAD -I. -IC:/Users/chris/onnxruntime/cmake/external/protobuf/src -std=c++11 -MD -MT CMakeFiles/libprotobuf.dir/C_/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc.obj -MF CMakeFiles\libprotobuf.dir\C_\Users\chris\onnxruntime\cmake\external\protobuf\src\google\protobuf\io\io_win32.cc.obj.d -o CMakeFiles/libprotobuf.dir/C_/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc.obj -c C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc
C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc: In function 'int google::protobuf::io::win32::stat(const char*,google::protobuf::io::win32::_stat*)':
C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc:315:40: error: cannot convert 'google::protobuf::io::win32::_stat*' to '_stat*' for argument '2' to 'int _wstat(const wchar_t*,_stat*)'
   return ::_wstat(wpath.c_str(),buffer);
                                        ^
In file included from C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc:52:0:
C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.h:75:51: note: class type 'google::protobuf::io::win32::_stat' is incomplete
 PROTOBUF_EXPORT int stat(const char* path,struct _stat* buffer);
                                                   ^
C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc: In function 'FILE* google::protobuf::io::win32::fopen(const char*,const char*)':
C:/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/io/io_win32.cc:337:10: error: '::_wfopen' has not been declared
   return ::_wfopen(wpath.c_str(),wmode.c_str());
          ^
[6/67] Building CXX object CMakeFiles/libprotobuf.dir/C_/Users/chris/onnxruntime/cmake/external/protobuf/src/google/protobuf/message_lite.cc.obj
ninja: build stopped: subcommand Failed.
Traceback (most recent call last):
  File "C:\Users\chris\onnxruntime\\tools\ci_build\build.py",line 2023,in <module>
    sys.exit(main())
  File "C:\Users\chris\onnxruntime\\tools\ci_build\build.py",line 1918,in main
    cmake_path,source_dir,build_dir,args)
  File "C:\Users\chris\onnxruntime\\tools\ci_build\build.py",line 1673,in build_protoc_for_host
    run_subprocess(cmd_args)
  File "C:\Users\chris\onnxruntime\\tools\ci_build\build.py",line 544,in run_subprocess
    return run(*args,cwd=cwd,capture_stdout=capture_stdout,shell=shell,env=my_env)
  File "C:\Users\chris\onnxruntime\tools\python\util\run.py",line 44,in run
    env=env,shell=shell)
  File "C:\Users\chris\AppData\Local\Programs\Python\python37\lib\subprocess.py",line 512,in run
    output=stdout,stderr=stderr)
subprocess.CalledProcessError: Command '['C:\\Program Files\\CMake\\bin\\cmake.EXE','--build','C:\\Users\\chris\\onnxruntime\\\\build\\Windows\\host_protoc','--config','Release','--target','protoc']' returned non-zero exit status 1.

我是不是走错了路?这是我第一次尝试将 ML 与 Android 结合,所以我没有这方面的经验。非常欢迎任何建议。

解决方法

对于 onnxruntime 的问题,请尝试更改 CMakeCache.txt :

CMAKE_CXX_FLAGS:STRING=-U__STRICT_ANSI__

它应该修复你提到的错误。我认为您使用 onnxruntime 走在正确的道路上。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...