机器学习: 在 Android 中集成 TensorFlow
集成的代码是在 AndroidTensorFlowMachineLearningExample 基础上修改.
Android 上集成 tensorflow 最简单是步骤是:
1 complile 引入
- compile 'org.tensorflow:tensorflow-android:1.4.0'
2 拿到 AI 算法开发人员训练好并压缩好的 pb 文件
3 根据其 java 的 api 开始写代码
一般 so 库通过 compile 引入后自动会打入, pb 放在 asserts 文件夹, 但这样会增大 apk 包体积. so 库一般一个 abi 就 10-15M,pb 文件 20-100M 不等. 所以需要动态加载: 放在服务器, 下载到本地, 需要时直接从本地读取.
AndroidTensorFlowMachineLearningExample 中 api 并无从流中加载 pb 文件的 api, 而 1.4.0 中 java api 提供了以下构造方法, 可以从文件中加载. 只要预先下载好就行了.
- new TensorFlowInferenceInterface(inputStream);
略显麻烦, 一需要识别所支持的 abi, 然后下载对应的 so 文件 二 需要注释掉 java 代码中的静态代码块加载 so 库的代码
依赖引入方式不再是上方的一行代码 compile, 而是将 gradle 缓存中的 tensorflow-android:1.4.0 的 jar 包和 jni 包拷贝出来. jni 包中的 so 文件上传到服务器.
jar 包需要注释掉里面静态代码块加载 so 库的代码: jar 包中多处调用 TensorFlow.init() 初始化, 所以只要注释 init 内部内容就好.
- TensorFlow类中的:
- static void init() {
- //NativeLibrary.load();//注释掉此行,由我们自己动态加载
- }
- static {
- init();
- }
操作方法:
新建一个包名相同的 TensorFlow 类, 将 jar 包中代码拷贝至此, 注释掉那一行代码, 用 java7(不能用 java8) 编译后, 将 jar 包用 winrar 打开, 将编译后的 class 文件拖进 jar 包替换即可. 然后将 jar 包添加到工程 libs 目录, 添加为依赖.
获取手机系统首选 abi, 然后去获取对应 url, 下载到 app 内目录, 加载即可.
- private static String getFirstSupportedAbi() {
- String abi1 = "";
- if (Build.VERSION.SDK_INT >= 21) {
- String[] abis = Build.SUPPORTED_ABIS;
- if (abis != null) {
- String abistr = "";
- //第一个是原生支持的,后面的是兼容模式.虽然是兼容,但手动加载时很多并不兼容.
- abi1 = abis[0];
- for (String abi: abis) {
- abistr = abistr + abi + ",";
- }
- if (showLog) Log.e(TAG, "[copySo] supported api:" + abistr);
- }
- } else {
- if (showLog) Log.e(TAG, "[copySo] supported api:" + Build.CPU_ABI + "--- " + Build.CPU_ABI2);
- if (!TextUtils.isEmpty(Build.CPU_ABI)) {
- abi1 = Build.CPU_ABI;
- } else if (!TextUtils.isEmpty(Build.CPU_ABI2)) {
- abi1 = Build.CPU_ABI2;
- }
- }
- return abi1;
- }
- String abi = getFirstSupportedAbi();
- File dir = context.getDir("jnilibs", Context.MODE_PRIVATE);
- File subDir = new File(dir, abi);
- try {
- System.load(filePath);
- } catch(Throwable e) {
- e.printStackTrace();
- }
都是大文件, 选一个比较靠谱, 能够断点续传的库: FileDownloader
同时还需要注意:
来源: https://juejin.im/post/5a339c546fb9a0452405e398