眾所周知喳整,google谷歌有一個(gè)名為TensorFlow的開源庫(kù)洼怔,可用來(lái)在Android中實(shí)現(xiàn)機(jī)器學(xué)習(xí)涩馆。
TensorFlow是一個(gè)由google谷歌提供的機(jī)器智能開源軟件庫(kù)提陶。我在網(wǎng)上搜索了很多關(guān)于在Android端 構(gòu)建 TensorFlow的簡(jiǎn)單簡(jiǎn)單方法和簡(jiǎn)單demo烫沙,都一無(wú)所獲。在閱讀了眾多資源后隙笆,我總算可以構(gòu)建成功了锌蓄。然后我決定寫下這篇博客升筏,以便其他人不用花費(fèi)太多時(shí)間。
本篇Demo——圖像分類器瘸爽,是取材于google谷歌官方的TensorFlow的Demo您访。
閱讀這篇文章,你需要已經(jīng)熟悉機(jī)器學(xué)習(xí)剪决,并且知道如何為機(jī)器學(xué)習(xí)構(gòu)建相關(guān)的模型(在這個(gè)Demo里我暫時(shí)用一套預(yù)訓(xùn)練模型)灵汪。不久之后,我將要寫下關(guān)于機(jī)器學(xué)習(xí)的一系列文章柑潦,以便所有人都可以學(xué)習(xí)如何來(lái)為機(jī)器學(xué)習(xí)構(gòu)建模型享言。
開啟Android機(jī)器學(xué)習(xí) 構(gòu)建之門
你需要了解一些重要的點(diǎn):
- TensorFlow的核心是用C++編寫的。
- 為了在Android中構(gòu)建渗鬼,我們不得不使用JNI(Java Native Interface)來(lái)調(diào)用C++函數(shù)览露,例如loadModel, getPredictions等等。
- 我們將使用一個(gè)jar包和一個(gè).so動(dòng)態(tài)鏈接庫(kù)文件乍钻,前者里面由調(diào)用native C++的JAVA API構(gòu)成肛循,后者是C++編譯的so文件铭腕。然后我們可以僅通過(guò)調(diào)用JAVA API來(lái)把事情搞定银择。
- 因此,請(qǐng)注意累舷,我們需要一個(gè)jar文件(JAVA API)和一個(gè).so文件(C++編譯好)
- 我們必須還有2個(gè)東西:提前訓(xùn)練的模型文件(.pb)浩考,用來(lái)分類的標(biāo)簽文件(.txt)。
我們將構(gòu)建一個(gè)如下圖的物體探測(cè)器:
接下來(lái)被盈,讓我們構(gòu)建jar文件和.so文件
執(zhí)行如下命令:
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git
注意:--recurse-submodules 非常重要析孽,用來(lái)下拉子模塊的代碼。
需要使用官方推薦的NDK r12b來(lái)構(gòu)建so, 太新或太舊的版本都會(huì)有問(wèn)題只怎,如果你沒(méi)有NDK r12b,請(qǐng)?jiān)?a target="_blank" rel="nofollow">這里下載.
如果你不用r12b編譯袜瞬,你就會(huì)遇到各種各樣的錯(cuò)誤。
如果你是全新玩家身堡,那么你當(dāng)然還需要下載Android SDK了邓尤,或者采用Android Studio 下載的Android SDK也可以,后面我們需要的是SDK的路徑贴谎。
你需要了解谷歌的構(gòu)建工具Bazel汞扎,它是TensorFlow的首席構(gòu)建工具。你可以在這里安裝Bazel擅这。
當(dāng)你對(duì)Bazel有所了解之后:
現(xiàn)在澈魄,編輯WORKSPACE文件,我們可以在之前clone下來(lái)的TensorFlow的根路徑里找到WORKSPACE文件仲翎。
# Uncomment and update the paths in these entries to build the Android demo.
#android_sdk_repository(
# name = "androidsdk",
# api_level = 23,
# build_tools_version = "25.0.1",
# # Replace with path to Android SDK on your system
# path = "<PATH_TO_SDK>",
#)
#
#android_ndk_repository(
# name="androidndk",
# path="<PATH_TO_NDK>",
# api_level=14)
將以上文件內(nèi)容改為我們自己的sdk痹扇、ndk的路徑:
android_sdk_repository(
name = "androidsdk",
api_level = 23,
build_tools_version = "25.0.1",
# Replace with path to Android SDK on your system
path = "/Users/xxx/Library/Android/sdk/",
)
android_ndk_repository(
name="androidndk",
path="/Users/xxx/Downloads/android-ndk-r13/",
api_level=14)
下一步铛漓,構(gòu)建.so文件,執(zhí)行如下命令:
bazel build -c opt //tensorflow/contrib/android:libtensorflow_inference.so \
--crosstool_top=//external:android/crosstool \
--host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=armeabi-v7a
其中的armeabi-v7a
參數(shù)可以換成你所需的目標(biāo)cpu架構(gòu)帘营。
構(gòu)建完成后票渠,.so文件將在如下路徑生成:
bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so
接著構(gòu)建JAVA jar文件:
bazel build //tensorflow/contrib/android:android_tensorflow_inference_java
jar文件在如下路徑生成:
bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar
現(xiàn)在我們同時(shí)擁有了jar文件和.so文件了。
如果你構(gòu)建失敗了芬迄,可以直接從這里可以下載demo工程问顷,里面都有構(gòu)建好的文件。
但是我們還需要預(yù)訓(xùn)練模型文件和標(biāo)簽文件禀梳。
在這個(gè)demo里杜窄,我們使用Google提供的預(yù)訓(xùn)練模型文件,這個(gè)文件用來(lái)從已有的圖片中檢測(cè)物體(圖像識(shí)別)算途。
在這里下載模型文件塞耕。
下載完zip包解壓縮,得到2個(gè)文件:
- imagenet_comp_graph_label_strings.txt(物體的標(biāo)簽文件)
- tensorflow_inception_graph.pb (預(yù)訓(xùn)練模型文件).
現(xiàn)在我們使用Android Studio來(lái)創(chuàng)建一個(gè)樣例工程嘴瓤。把.pb扫外、.txt這2個(gè)文件放入assets文件夾。
將生成的jar包廓脆,放入libs文件筛谚,在build.gradle中加入:
compile files('libs/libandroid_tensorflow_inference_java.jar')
在main目錄創(chuàng)建jniLibs文件夾,把編譯好的.so文件放進(jìn)jniLibs/armeabi-v7a/
路徑
到現(xiàn)在為止停忿,我們就可以調(diào)用TensorFlow的JAVA API了驾讲。
TensorFlow的JAVA層API通過(guò)TensorFlowInferenceInterface來(lái)暴露所有需要的方法。
我們需要先通過(guò)模型路徑裝載模型席赂,才能進(jìn)一步調(diào)用這些JAVA API吮铭。
并且,我們可以提供輸入圖像颅停,來(lái)得到識(shí)別的結(jié)果谓晌。
上面已經(jīng)說(shuō)過(guò)了,想圖省事癞揉,直接clone現(xiàn)成的項(xiàng)目纸肉,看看代碼,編譯運(yùn)行即可烧董。