機器學習:如何在安卓上整合TensorFlow
我們都知道,谷歌有一個開源庫叫做TensorFlow,可被用在安卓系統中實現機器學習。換言之,TensorFlow是谷歌為機器智慧提供的一個開源軟體庫。
我在網路上搜尋了很久,都沒有找到在安卓上搭建TensorFlow的簡單的方法或例項。仔細查閱許多資料以後,我終於可以搭建它了。於是,我決定把我搭建的過程寫出來,這樣其他人就不必再浪費時間了。
這篇文章是寫給那些熟悉機器學習並且知道怎樣為機器學習搭建模型的人的(在這個示例中我會使用一個預訓練模型)。近期,我會寫一系列關於機器學習的文章,這樣每個人都能夠學到如何為機器學習搭建模型。
從搭建安卓上的機器學習模型過程講起
我們需要知道的幾個要點:
-
TensorFlow的核心是用C++編寫的;
-
為了在安卓上搭建TensorFlow,我們需要用JNI(Java本地介面)來呼叫C++函式,比如說loadModel,getPredictions,等等;
-
我們會用到.so(shared object,即共享物件)檔案,它是C++編譯檔案;還會用到jar檔案,它由能夠呼叫本地C++的Java API組成。之後,我們就可以呼叫Java API輕鬆地把事情做好;
-
所以我們需要jar(Java API)和一個.so(C++編譯)檔案;
-
我們必須要有一個預訓練模型檔案和一個用於分類的標籤檔案。
我們會做以下的目標檢測:
編譯jar和.so檔案
注意:--recurse-submodules對於提取子模組(pull submodules)很重要。
在這裡(https://developer.android.com/ndk/downloads/older_releases.html#ndk-12b-downloads)下載NDK。
下載安卓SDK,或者,我們也可以從Android Studio SDK提供路徑。
安裝Bazel(https://bazel.build/versions/master/docs/install.html)。Bazel是TensorFlow的主要編譯系統。
現在,編輯工作空間(WORKSPACE),我們可以在早先克隆的TesnsorFlow根路徑中找到工作空間(WORKSPACE)檔案。
我們的SDK和NDK路徑就跟下面一樣:
然後編譯生成.so檔案:
將armeabi-v7a換成我們所需要的目標架構。
庫會被放置在:
編譯Java副本:
我們可以在這裡找到JAR檔案:
現在我們有了jar和.so檔案。你也可以從下面的工程中直接提取使用我已經建立好的.so檔案和jar。
我已經在這裡(https://github.com/MindorksOpenSource/AndroidTensorFlowMachineLearningExample)建立了一個完整可執行的示例應用。
但是,我們需要預訓練模型和標籤檔案。
在這個例子中,我們會使用Google預訓練模型,它實現了在一張給定的照片上做目標檢測。
解壓縮zip檔案,我們就會得到imagenet_comp_graph_label.strings.txt(目標標籤)以及tensorflow_inception_graph.pb(預訓練模型)。
現在,在Android Studio上建立安卓示例工程吧。
將imagenet_comp_graph_label.strings.txt(目標標籤)以及tensorflow_inception_graph.pb放進assets資料夾。
將libandroid_tensorflow_inference_java.jar放進lib資料夾,單擊右鍵,新增庫。
在主目錄新建一個jniLibs資料夾並且將libtensorflow_inference.so放到jniLibs/armeabi-v7a資料夾中。
現在,我們就可以呼叫TensorFlow Java API了。
TensorFlow Java API通過TensorFlowInferenceInterface類開放了所有需要的方法。
現在,我們可以用模型路徑呼叫TensorFlow Java API並且載入它了。
然後,我們可以輸入一張圖片來獲取預測結果。
如果想要體會完整的流程,克隆這個專案(https://github.com/MindorksOpenSource/AndroidTensorFlowMachineLearningExample),搭建並執行它吧。
如果你在搭建這個專案的過程中有任何問題的話,聯絡我,我會非常樂意幫助你。
Happy Coding:)
讀者問答
Q:我很疑惑要怎麼連線到‘so’庫?也沒有任何一行像’System.loadLibray’的程式碼?
A:System.loadLibrary已經寫在TensorFlow jar中了。
Q:所以這是一個C++應用還是Java應用啊?你用的是什麼語言?
A:這是一個用Java語言編寫的安卓應用,它通過Java本地介面(JNI: Java Native Interface)呼叫C++做預測(機器學習)。