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

相關文章
相關標籤/搜索