1. 程式人生 > >編譯TensorFlow Android Camera Demo

編譯TensorFlow Android Camera Demo

最近這兩天探索將TensorFlow移植到Android上的問題,跑了下官方的Demo

由於環境的不一致,遇到了各種坑,現在將其寫下來,以做記憶

1、下載程式碼

第一步當然是下載程式碼

git下載程式碼:

--recurse-submodules這個必須新增

Demo在原始碼中的位置:tensorflow/examples/android


2、安裝Bazel

我的系統是ubuntu14.04,也不想研究Bazel的程式碼,就沒有下載原始碼編譯安裝

第一步,安裝JDK8

    執行:

        sudo apt-get install openjdk-8-jdk

   Ubuntu 14.04 執行下面命令:

        sudo add-apt-repository ppa:webupd8team/java 
        sudo apt-get update && sudo apt-get install oracle-java8-installer 
第二步,新增Bazel作為一個包資源
    echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
    curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
第三步,安裝
    sudo apt-get update && sudo apt-get install bazel
第四步,更新
    sudo apt-get upgrade bazel

3、安裝SDK與NDK

去官網下載,然後放到專案目錄下,下載地址自行百度

配置位置,在專案根目錄下找到WORKSPACE這個檔案,開啟

找到android_sdk_repository與android_ndk_repository這個兩個配置項,本來它們是被註釋掉的,把它們開啟

然後修改path屬性指向相應的目錄,修改使用的版本資訊等

android_sdk_repository(
    name = "androidsdk",
    api_level = 26,
    # Ensure that you have the build_tools_version below installed in the
    # SDK manager as it updates periodically.
    build_tools_version = "26.0.1",
    # Replace with path to Android SDK on your system
    path = "android-sdk-linux",
)

android_ndk_repository(
    name="androidndk",
    path="android-ndk-r14b",
    # This needs to be 14 or higher to compile TensorFlow.
    # Please specify API level to >= 21 to build for 64-bit
    # archtectures or the Android NDK will automatically select biggest
    # API level that it supports without notice.
    # Note that the NDK version is not the API level.
    api_level=14)

這裡講下,這裡遇到的兩個坑。

1、NDK的版本問題,這裡不能用最新的NDK,最大隻支援到14,但也不要小於10。我就是去官網下了個最新的,然後編譯各種c++標頭檔案找不到,崩潰

2、NDK對cmake的版本有要求,我的ubuntu14.04系統的cmake是2.8的,但ndk_r14最小要求3.6版本,所以又去官網下了個最新的3.9版本才可以

4、模型下載問題

原始碼專案下的編譯,每次清空重新編譯,都會重新下載下模型檔案。這很浪費時間,可以如下改下:

開啟檔案tensorflow/examples/android/BUILD,把下面紅色內容註釋掉,即在編譯的時候不再下載檔案了

android_binary(
    name = "tensorflow_demo",
    srcs = glob([
        "src/**/*.java",
    ]),
    # Package assets from assets dir as well as all model targets. Remove undesired models
    # (and corresponding Activities in source) to reduce APK size.
    assets = [
        "//tensorflow/examples/android/assets:asset_files",
        #":external_assets",
    ],
    assets_dir = "",
    custom_package = "org.tensorflow.demo",
    inline_constants = 1,
    manifest = "AndroidManifest.xml",
    manifest_merger = "legacy",
    resource_files = glob(["res/**"]),
    tags = [
        "manual",
        "notap",
    ],
    deps = [
        ":tensorflow_native_libs",
        "//tensorflow/contrib/android:android_tensorflow_inference_java",
    ],
)

手動下載模型檔案,並解壓到assert目錄,執行下面的shell

BASE_URL=https://storage.googleapis.com/download.tensorflow.org/models
for MODEL_ZIP in inception5h.zip ssd_mobilenet_v1_android_export.zip stylize_v1.zip
do
  curl -L ${BASE_URL}/${MODEL_ZIP} -o /tmp/${MODEL_ZIP}
  unzip /tmp/${MODEL_ZIP} -d tensorflow/examples/android/assets/
done

5、編譯

bazel build -c opt //tensorflow/examples/android:tensorflow_demo

成功之後生成下面三個檔案

bazel-bin/tensorflow/examples/android/tensorflow_demo_deploy.jar 
bazel-bin/tensorflow/examples/android/tensorflow_demo_unsigned.apk 
bazel-bin/tensorflow/examples/android/tensorflow_demo.apk

上述命令編譯出來的是armv7版本的,只可以在arm手機上跑,我的模擬器是x86的還是無法執行,後來找到專案裡其實有編譯的指令碼,式了下還是可以用的

編譯其它cpu版本的軟體:

    開啟指令碼檔案tensorflow/tools/ci_build/builds/android.sh

    將裡面的--fat_apk_cpu=x86_64修改為你需要的,然後編譯

編譯所有cpu支援版本軟體:

    執行指令碼tensorflow/tools/ci_build/builds/android_full.sh