首先說明以下,這只是把實(shí)踐的過程敘述以下。
參考文章:在Android中借助TensorFlow使用機(jī)器學(xué)習(xí)(譯)
Android TensorFlow Machine Learning Example(科學(xué)上網(wǎng)你懂的
0、前言
環(huán)境
- 系統(tǒng):Deepin1.4 Beta
- java版本:open jdk 1.8
- python版本:2.7
上述環(huán)境用于構(gòu)建bazel,bazel是tensorflow的構(gòu)建系統(tǒng)。 - Android SDK:api 15~api 25
- Android NDK:android-ndk-r13b-linux-x86_64
而下面的sdk和ndk是生成安卓下的so文件和java的必須的。
我們有so文件和java接口的文件就可以了,有興趣當(dāng)然可以去編譯以下,感受一下,期間會(huì)有很多wram,不過不是error就沒事啦。當(dāng)然編譯期間也很占內(nèi)存,我的8g內(nèi)存,飆到97%過了很久才下來。
如果你有興趣,可以下載:
- SDK(含NDK):鏈接:http://pan.baidu.com/s/1qYdfkxm 密碼:fe7d
- NDK:鏈接:http://pan.baidu.com/s/1qYNMr7Y 密碼:0tzy
- tensorflow github文件(當(dāng)然你可以去github直接下載):鏈接:http://pan.baidu.com/s/1jIQazx8 密碼:mxzx
- bazel(0.4.4):鏈接:http://pan.baidu.com/s/1eSxIuie 密碼:ne4l
SDK中的NDK在ndk-bundle文件夾下就是了,不知道的話,在SDK下找找看吧。
bazel源碼編譯不要直接從github直接clone而是去release頁面下載,直接clone會(huì)提示你去release下載編譯。源碼編譯bazel我并沒試過,因?yàn)槲矣胐eb安裝成功了,就沒去折騰了。bazel網(wǎng)盤中有幾個(gè)從release頁面下載的文件。
編寫app前你要如下文件:
- 編譯出來的tensorflow的so庫
- 編譯出來的java的jar包
- tensorflow訓(xùn)練出來的文件
沒有自己編譯的,可以從這下載so和jar包:鏈接:https://pan.baidu.com/s/1VSxnHYyUbbFUszvSbTJokA
官方訓(xùn)練完的文件:鏈接:http://pan.baidu.com/s/1mhPGigg 密碼:w4bx - so文件大?。?0m左右
- jar包大?。?0k+
- 訓(xùn)練完的文件大?。?0m+
所以最后安卓demo App的大小是60m+,運(yùn)行內(nèi)存是75m+(當(dāng)然不同手機(jī)可能不一樣)
總的感受是太大了。但是本地的東西也算可以了,一般的模式都是去服務(wù)器訪問,再把結(jié)果返回的吧。

點(diǎn)Detech Object進(jìn)行識(shí)別,這個(gè)模型的原理大概就是從把拍下的圖片分類到已知的類別里面去,因?yàn)?,下載下來的訓(xùn)練文件有個(gè)txt文件就是放這些名詞。
1、安裝bazel
bazel官網(wǎng):bazel
python和jdk8自己安裝,這里不多講述。
從我上面給出的deb下載下來
sudo dpkg -i '/home/hui/Downloads/bazel_0.4.4-linux-x86_64.deb'
路徑直接把文件拉進(jìn)去。
輸入bazel有顯示bazel參數(shù)選項(xiàng)就安裝成功了。
2、編譯so和jar包
首先下載tensorflow源碼,以供編譯:
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git
修改clone 下來的TensorFlow中的WROKSPACE文件:
# 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)
修改后:
# 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 = "/home/hui/Desktop/Android/android-sdk-linux",
)
android_ndk_repository(
name="androidndk",
path="/home/hui/Desktop/Android/android-sdk-linux/ndk-bundle",
api_level=15)
這個(gè)sdk沒有api 14,所以寫了最小的15
以下編譯命令在tensorflow根目錄執(zhí)行,文件路徑是相對于tensorflow根目錄而言
編譯so:
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
編譯后文件位置:
bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so
編譯jar文件:
bazel build //tensorflow/contrib/android:android_tensorflow_inference_java
編譯后文件位置:
bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar
我編譯jar的時(shí)候,第一失敗了,再用多一次命令就搞定了。
這樣就編譯出so和jar包了。
當(dāng)然你也可以從百度云直接下載,跳過2。
windows下試了很多次的安裝bazel都是敗了,果然有些東西要在linux才是最好的。
3、下載訓(xùn)練模型和標(biāo)簽文件
這里我們用google的數(shù)據(jù)就可以,下載地址,下載后解壓可以得到imagenet_comp_graph_label_strings.txt(label for objects) and tensorflow_inception_graph.pb (pre-trained model) 兩個(gè)文件,這兩個(gè)文件放置在Android工程的Assets中即可。
4、Android demo的構(gòu)建
其實(shí)這里已經(jīng)有一個(gè)完整的demo地址,所以如果僅僅想體驗(yàn)一下機(jī)器學(xué)習(xí),可以直接clone代碼運(yùn)行即可,代碼地址。
如果要自己構(gòu)建demo,則需要引用之前生成的jar文件和so文件:
- 引用jar:
compile files('libs/libandroid_tensorflow_inference_java.jar')
jar包放在安卓項(xiàng)目的libs文件夾下。
- 引用so:
新建jniLibs文件,并把libtensorflow_inference.so 文件放置在jniLibs/armeabi-v7a/ 中。
在安卓項(xiàng)目的main文件夾下創(chuàng)建jniLibs/armeabi-v7a/ ,so放進(jìn)去。
同時(shí)創(chuàng)建不要包含including c++的項(xiàng)目,因?yàn)闀?huì)找不到so路徑。所以普通的項(xiàng)目就行了,因?yàn)閟o是通過ndk生成的,直接放進(jìn)項(xiàng)目就可以用了,不用動(dòng)態(tài)的編譯什么的。
5、自己寫項(xiàng)目(其實(shí)是復(fù)制而已)
https://github.com/MindorksOpenSource/AndroidTensorFlowMachineLearningExample
這是原作者的demo
我們也從demo靜靜的復(fù)制就行了。
放入自己編譯jar包:

放入自己編譯so庫文件:

放入下載訓(xùn)練文件:

從demo復(fù)制兩行到String.xml:
<string name="toggle_camera">Toggle Camera</string>
<string name="detect_object">Detect Object</string>

復(fù)制layout和實(shí)現(xiàn)類:

將框框的4個(gè)文件直接從那個(gè)AndroidTensorFlowMachineLearningExample復(fù)制過來
build.gradle添加:
compile files('libs/libandroid_tensorflow_inference_java.jar')
compile 'com.flurgle:camerakit:0.9.13'

layout.xml會(huì)報(bào)錯(cuò),刪除如下:
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
以上4行是設(shè)置外邊距而已。
編譯運(yùn)行吧。
結(jié)果是這樣的:

的確有點(diǎn)違和感。就這樣了。
寫了很拖沓,你可以去第一個(gè)參考博客看比較清晰明了。