1. 程式人生 > >Tensorflow Lite 0.1 for Android

Tensorflow Lite 0.1 for Android

直接使用JCenter庫方式:
移動裝置上使用谷歌開源的深度學習框架 Tensorflow Lite,最新原始碼位置:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite
要求:
Android Studio 3.0
SDK Version API25,或者API26
NDK Version 14
步驟:
1 匯入tensorflow/contrib/lite/java/demo 這個專案到Studio,
2 如果沒有gradle,則安裝好gradle,根據Studio的提示進行安裝就好(測試使用的是2.3.1)
3 下載移動端的模型(model)和標籤資料(lables)(

https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip
4 下載完成解壓mobilenet_v1_224_android_quant_2017_11_08.zip檔案得到一個xxx.tflite和labes.txt檔案,分別是模型和標籤檔案,並且把這兩個檔案複製到assets資料夾下。
5 構建app,在run一下不出意外應該是可以看到以下畫面:

這裡寫圖片描述

 Android_sdk_repository (
   name = "androidsdk"
, api_level = 23, build_tools_version = "23.0.2", path = "/home/xxxx/android-sdk-linux/", ) android_ndk_repository( name="androidndk", path="/home/xxxx/android-ndk-r10e/", api_level=19)

5 用命令開始構建原始碼
使用bazel 構建一個demo app :

(注意:構建app時,由於bazel 存在的bug,需要在python2 的環境中進行)

關於mobilenet_v1_224_android_quant_2017_11_08.zip模型

 demo是調整每個攝像機的影象幀(224寬×224高)與量化室移動模型被使用。調整後的影象是由排尺寸1×224×224×3位元組轉換成一個位元組緩衝區的行,其中1是在一批224×224影象的數量是3個位元組的影象的寬度和高度是三種顏色的畫素。本程式使用java API tensorflow Lite推理模型以單輸入單輸出提供。這輸出一個二維陣列,第一個維度是類別索引,第二個維度是分類的自信度。該室移動模型具有1001個不同的類別和應用程式型別的所有類別的概率,顯示前三個可能性。

關於Tensorflow Lite
根據不同的使用情況下,可以選擇使用一個流行的開源模型如inceptionv3或mobilenets,重新訓練這些模型用自己的自定義資料集或甚至建立自己的自定義模型。

直接使用一個預訓練好的模型
mobilenets是tensorflow移動計算機視覺模型家族,這個設計有效地提高精度並且在的資源受限的裝置或嵌入式應用。mobilenets的優點是模型資源小、低延遲、低功耗模型引數來滿足各種使用情況下的資源約束。他們可以建立在分類、檢測、嵌入和分割類似於其他流行的大型模型,如成立以來,使用。谷歌提供了16個預訓練的ImageNet分類檢查用於各種尺寸的移動專案mobilenets
以上例子中使用的inception-v3:
是影象識別模型與1000類一般物體識別,達到了較高的精度,如“斑馬”、“狗”、“洗碗機”。該模型採用卷積神經網路的輸入影象提取的一般特點和分類的基礎上的特徵完全連線和softmax層。
其他預訓練好的模型下載地址可以在 tensorflow/tensorflow/contrib/lite/g3doc/models.md 檔案中找到。

使用inception-v3或MobileNet為自定義的資料集
上述預先訓練模式已經被訓練在ImageNet資料集,包括1000個預定義的類。如果這些類對給定的用例不相關或有用,則需要對模型進行再培訓。這項技術被稱為遷移學習,開始用一個模型已經訓練上的問題,將被訓練在一個類似的問題。從零開始深入學習可能需要幾天時間,但是轉移學習可以很快完成。為了做到這一點,開發人員需要生成與相關類標記的自定義資料集。

訓練自定義模型
第二種利用已經有的網路框架訓練自己的資料基本可以滿足大部分需求,但是除了以上方式,也可以自定義網路模型。如:先使用python構建出深度網路,訓練好以後進行資料匯出,大概會有這些檔案xxx.pb,xxx.ckpt等檔案,可以根據這些檔案轉換成Lite 可用的模型xxx.tflite。具體見下文。
模型格式轉換
把一個標準的tensorflow模型轉換成mobileNets 。標準模型中有保護 .pb 或者 .pbtxt 圖( GraphDef ) 檔案。如果應用程式開發人員使用預先培訓過的模型(如上面步驟1中所定義的),他們可以從這裡下載一個現成的、已經轉換過的模型。使用再培訓(即遷移學習)或自定義模型生成的模型需要使用下面提到的步驟進行轉換。
(GraphDef ) xxx.pb :一個protobuf表示tensorflow培訓或計算圖。這包含運算子、張量和變數定義。
(CheckPoint) xxx.ckpt:這是一個GraphDef 延伸變數,這個檔案一般無法被單獨解釋。
(FrozenGraphDef) graphdef不含變數的子類。一個graphdef可以轉換為一個凍結狀態的graphdef通過CheckPoint 和graphdef轉換每個變數
(TensorFlow lite model ).lite:檔案是序列化flatbuffer,含tensorflow Lite運算元和張量的tensorflow Lite的翻譯。這是最類似於TensorFlow frozen GraphDefs凍結“圖”要在TensorFlow Lite中使用此.pb GraphDef檔案,我們需要包含經過訓練的權重引數的CheckPoint。 .pb只包含圖形的結構。 合併CheckPoint值與圖形結構的過程稱為“凍結”圖形。

首先要確檢查點資料夾存在的位置,或者也可以下載一個預先訓練的模型的檢查點(例如:這裡是一個MobileNets的連結)。
圖凍結可以使用下面的命令完成(並適當地修改引數)

bazel build tensorflow/python/tools:freeze_graph
bazel-bin/tensorflow/python/tools/freeze_graph\
    --input_graph=/tmp/mobilenet_v1_224.pb \
    --input_checkpoint=/tmp/checkpoints/mobilenet-10202.ckpt \
    --input_binary=true --output_graph=/tmp/frozen_mobilenet_v1_224.pb \
    --output_node_names=MobileNet/Predictions/Reshape_1

使用者必須首先使用bazel構建freeze_graph指令碼,然後執行指令碼。 必須啟用input_binary標誌以確保protobuf以二進位制格式讀取和寫入。 使用者必須輸入.pb和.ckpt檔案才能凍結圖形。output_node_names可能在構建模型的程式碼之外不明顯。 找到它們的最簡單方法是用graphviz或tensorboard視覺化圖形。

這個凍結的Graphdef現在已經準備好轉換為flatbuffer格式(.lite),以便在Android或iOS上使用。 在Android使用者可以使用Tensorflow Optimizing Converter工具,靈活地使用凍結graphdef的浮點或量化版本(如果有的話)。

下面是一個示例命令列,用於將凍結的Graphdef轉換為“.lite”格式。Tensorflow Optimizing Converter支援浮點模型和量化模型,但是,根據是否使用FLOAT或QUANTIZED模式,需要使用不同的配置引數。

bazel build tensorflow/contrib/lite/toco:toco
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- \
  --input_file=(pwd)/mobilenet_v1_1.0_224/frozen_graph.pb \
  --input_format=TENSORFLOW_GRAPHDEF  --output_format=TFLITE \
  --output_file=/tmp/mobilenet_v1_1.0_224.lite --inference_type=FLOAT \
  --input_type=FLOAT --input_arrays=input \
  --output_arrays=MobilenetV1/Predictions/Reshape_1 --input_shapes=1,224,224,3

引數說明:
input_file引數應指向包含模型體系結構的凍結GraphDef檔案。
output_file引數應指向TensorFlow Lite模型檔案的生成位置。
input_type和inference_type引數應設定為FLOAT,除非轉換量化的模型。
設定input_array,output_array和input_shape引數有點棘手。 找到這些值最簡單的方法是測試TensorBoard中的圖形。 使用者應該重用現有的freeze_graphstep中用於指定輸出節點進行推理的引數。

請注意,也可以通過protos使用Tensorflow Optimizing Converter,可以將轉換步驟整合到模型設計工作流程中,以確保模型可以輕鬆轉換為移動推理圖。 例如:

import tensorflow as tf
img = tf.placeholder(name="img", dtype=tf.float32, shape=(1, 64, 64, 3))
val = img + tf.constant([1., 2., 3.]) + tf.constant([1., 4., 4.])
out = tf.identity(val, name="out")
with tf.Session() as sess:
  tflite_model = tf.contrib.lite.toco_convert(sess.graph_def, [img], [out])
  open("converteds_model.tflite", "wb").write(tflite_model)