tensorflow集成到Android以及so库和pb文件的动态加载实践

主要参考

官方集成指南java

官方demoandroid

深度学习利器:TensorFlow在智能终端中的应用git

机器学习:在Android中集成TensorFlow github

动态加载so库的实现方法与问题处理算法

集成简述

集成的代码是在AndroidTensorFlowMachineLearningExample基础上修改.api

Android上集成tensorflow最简单是步骤是:缓存

1 complile引入bash

compile 'org.tensorflow:tensorflow-android:1.4.0'
复制代码

2 拿到AI算法开发人员训练好并压缩好的pb文件服务器

3 根据其java的api开始写代码app

通常so库经过compile引入后自动会打入,pb放在asserts文件夹,但这样会增大apk包体积. so库通常一个abi就10-15M,pb文件20-100M不等. 因此须要动态加载: 放在服务器,下载到本地,须要时直接从本地读取.

pb文件的加载

AndroidTensorFlowMachineLearningExample中api并没有从流中加载pb文件的api,而1.4.0中java api提供了如下构造方法,能够从文件中加载. 只要预先下载好就好了.

new TensorFlowInferenceInterface(inputStream);
复制代码

so库的动态加载

略显麻烦, 一须要识别所支持的abi,而后下载对应的so文件 二 须要注释掉java代码中的静态代码块加载so库的代码

依赖引入方式再也不是上方的一行代码compile,而是将gradle缓存中的tensorflow-android:1.4.0的jar包和jni包拷贝出来. jni包中的so文件上传到服务器.

注释静态方法中的加载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目录,添加为依赖.

so库动态加载

获取手机系统首选abi,而后去获取对应url,下载到app内目录,加载便可.

获取首选abi:

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;
    }

复制代码

下载后的so文件要放到app内目录,不要放到sd卡:

String abi = getFirstSupportedAbi();
File dir = context.getDir("jnilibs", Context.MODE_PRIVATE);
File subDir = new File(dir, abi);
复制代码

加载so:

try {
                    System.load(filePath);
                }catch (Throwable e){
                    e.printStackTrace();
                }

复制代码

文件下载

都是大文件,选一个比较靠谱,可以断点续传的库:FileDownloader

同时还须要注意:

  • 文件很大,只在wifi时下载,以避免耗流量
  • 下载完校验md5.

代码

TensorFlowAndroidDynamic

相关文章
相关标签/搜索