1. 程式人生 > >當微信小程式遇上TensorFlow:Server端實現

當微信小程式遇上TensorFlow:Server端實現

image

又是一年一度的十一黃金旅遊周,你是在景區看人從眾叕,還是在高速公路上觀看大媽打太極呢?旅遊黃金週我一般是儘量不出門,這個十一也不例外。十月一日跑了一個半馬迎接國慶,十月二號選擇去了一個偏門的景點:張之洞與武漢博物館。今天則宅在家,吃吃喝喝之餘,琢磨起識別狗狗的微信小程式。

image

自打想到開發一款識別狗狗的app,我的第一直覺是應該開發一款微信小程式。相對於手機原生app,微信小程式具有開發和部署簡單,特別是無需安裝,即用即走,特別適合這種功能單一,偶爾用一用的app。

實現方案,首先想到的是TensorFlow.js,手機端實現深度學習,無需伺服器端,但是TensorFlow.js並不支援微信小程式,無奈只得選擇小程式 + server

的模式。而我並不擅長web + server的開發,所以在《這個中秋,我開發了一個識別狗狗的app》中談到,我先使用TensorFlow Lite實現了一個Android App。這個Android App 更多的是一個實驗性的專案,這個國慶節,空餘時間比較多,決定整一整微信小程式。

因為採用端加server的模式,圖片識別在server端完成,所以主要功能實現在server端。我們就先來談一談Server端的實現。

TensorFlow Serving

Server端的實現方案有好多種,C++/Java/Python都可以,我一度甚至考慮採用Node.js實現。上週瀏覽Google開發者大會資料時發現,TensorFlow已經提供了伺服器部署方案: TensorFlow Serving。

TensorFlow Serving是一種靈活的高效能服務系統,適用於機器學習模型,專為生產環境而設計。 TensorFlow Serving可以輕鬆部署新演算法和實驗,同時保持相同的伺服器架構和API。 TensorFlow Serving提供與TensorFlow模型的一攬子整合方案,也可以輕鬆擴充套件以服務於其他型別的模型。

TensorFlow Serving正在不斷完善中,直接參考示例並不能實現需要的功能,在多方查詢資料之後,終於把整個流程走通。

SavedModel

TensorFlow提供兩種模型格式:

  • checkpoints,這是一種依賴於建立模型的程式碼的格式。
  • SavedModel
    ,這是一種獨立於建立模型的程式碼的格式。

SaveModel是一種與語言無關,可恢復的密封式序列化格式。TensorFlow提供了多種與SavedModel互動的機制,如tf.saved_model API、Estimator API和CLI。TensorFlow Serving需要使用SavedModel格式的模型檔案。

retrain並儲存為SavedModel

在《這個中秋,我開發了一個識別狗狗的app》一文中提到,我們不需要從頭訓練識別狗狗的深度學習模型,而是採用遷移學習,在現有模型的基礎上再訓練。考慮到模型是部署到伺服器端,所以我選擇了識別能力更強的Inception V3模型。

帶標籤的狗狗資料集採用stanford dog datasets,請自行下載並解壓,然後執行如下命令進行訓練:

python retrain.py --image_dir=./Images --saved_model_dir=models/inception_v3

訓練的模型保存於models/inception_v3/1,其中1是版本號,可以通過retrain.py指令碼的命令列引數進行指定。

安裝tensorflow model server

在Ubuntu下這個非常容易,只需要使用下面的命令即可:

sudo apt install tensorflow-model-server

為了開發方便,需要安裝TensorFlow Serving Python API:

pip install tensorflow-serving-api

啟動tensorflow model server

按照文件,啟動tensorflow model server非常簡單,這裡加上rest_api_port引數是啟動server,並提供RESTful API,這種API介面方便微信小程式與之進行通訊。

tensorflow_model_server --rest_api_port=8501 --model_base_path=$PWD/models/inception_v3

image

簡單說,Simple TensorFlow Serving是一個TensorFlow Serving的封裝,是機器學習模型的通用且易於使用的服務。

其野心也很大,號稱支援如下功能:

  • 支援分散式TensorFlow模型
  • 支援常規RESTful / HTTP API
  • 支援GPU加速推理
  • 支援curl和其他命令列工具
  • 支援客戶端使用任何程式語言
  • 支援自動生成客戶端程式碼,無需編碼
  • 支援影象模型中使用原始圖片檔案進行推斷
  • 支援詳細請求的統計指標
  • 支援同時為多個模型提供服務
  • 支援動態的線上和離線模型版本
  • 支援為TensorFlow模型載入新的自定義操作
  • 通過可配置的基本身份驗證支援安全身份驗證
  • 支援TensorFlow / MXNet / PyTorch / Caffe2 / CNTK / ONNX / H2o / Scikit-learn / XGBoost / PMML 等多種模型

我最看中的就是它的自動生成客戶端程式碼功能,在沒有這個之前,我查找了很多資料,都沒有搞定客戶端與服務端之間的通訊。另外它還提供了一個web介面,可以檢視模型的結構以及signature(簽名),這個signature也是折騰了我好久都沒有搞定的。

image

Simple TensorFlow Serving的安裝非常簡單:

pip install simple_tensorflow_serving

接下來啟動server:

simple_tensorflow_serving --model_base_path="./models/inception_v3" &

客戶端

微信小程式的開發還沒有開始學,先用python寫一個客戶端先測試一下,我們可以使用自動生成客戶端程式碼功能:

curl http://localhost:8500/v1/models/default/gen_client?language=python > test_client.py

自動生成的程式碼如下:

#!/usr/bin/env python

import requests

def main():
  endpoint = "http://ilego.club:8500"
  json_data = {"model_name": "default", "data": {"image": [[[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]]]}}
  result = requests.post(endpoint, json=json_data)
  print(result.text)

if __name__ == "__main__":
  main()

可以嘗試測試一張狗狗圖片:

python test_client.py --image=./Images/n02116738-African_hunting_dog/n02116738_1105.jpg

結果如下:

n02116738 african hunting dog 0.780203342438
n02115913 dhole 0.0102733308449
n02092002 scottish deerhound 0.00600153999403

前面是類別標籤,後面是屬於某個類別的概率,上面結果中Top 1概率0.78。

總結

這個伺服器端遠還沒有達到完善,還存在一下問題:

  1. 客戶端與伺服器端的圖片採用JSON格式傳遞,影象資料由二進位制轉為JSON字串,空間效率低,後面考慮對影象資料進行base64編碼。
  2. 預測的效率比較第,從發出請求到收到迴應,有幾十秒的時間,還沒有查詢瓶頸在何處。
  3. 併發支援,因為現在只是一個簡單的測試,如果考慮到產品階段,多個手機的微信小程式同時進行識別,這還是會有很多工作需要做的。

好了,關於服務端的開發部署就先到這裡,下一篇文章我將談談微信小程式的開發和與server端的通訊,敬請關注!

image