search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

十分鐘搞定 Tensorflow 服務

歡迎大家參與在留言區交流

AI 研習社兩大福利就在文末!

不可錯過~

Tensorflow 服務是谷歌推薦用來部署 Tensorflow 模型的方法。如果你不具備一定的計算機工程知識背景,即使你對 Tensorflow 本身感覺很順手,但是我覺得想要搞定 Tensorflow 服務也不是辣么容易的。以下三點是我總結的難點:

  • (谷歌官方)教程含有 C++ 代碼(我不會 C++)

  • 教程里含有 kubernetes,gRPG,Bezel(其中一些我也是第一次見)

  • 需要被編譯出來。那個過程時間太長了,恐怕要用一個世紀吧!

這裡介紹一種可能是最簡單的方式——用 tensorflow 服務部署你的演算法模型。看完本教程,你也可以讓自己的模型在 TF 服務裡面運行。這個服務框架是彈性的,可以通過 REST 來請求。

本教程用的是 Docker 鏡像。可以利用 Kitematic 來啟動:

avloss/tensorflow-serving-rest.

起初,我試著在 DockerHub 上面搞 - 但是試了兩個小時都沒成功,所以我不得不棄坑去用 https://quay.io

我將一步步做好的鏡像上傳到 DockerHub,假如你想驗證本文,你可以去拉取 https://quay.io/repository/avloss/tensorflow-serving-rest 上的鏡像。

你可以用 Kitematic 啟動 Docker 容器,或者在 console 裡面用這行命令:

docker run --rm -it -p 8888:8888 -p 9000:9000 -p 5000:5000 quay.io/avloss/tensorflow-serving-rest

運行之後,執行這個腳本 http://localhost:8888/notebooks/tf_serving_rest_example.ipynb。(如果你用的是 Kitematic 的話,埠號要改改)

下面的內容最好用容器自帶的 Jupyter notebook!

為了進一步演示運行細節,我們下面用典型的 TF 官方教程 MNIST 示例:https://www.tensorflow.org/get_started/mnist/pros

我們用一個標準模型來舉個例子。

import tensorflow as tf x = tf.placeholder(tf.float32, shape=[None, 784]) y_ = tf.placeholder(tf.float32, shape=[None, 10]) W = tf.Variable(tf.zeros([78410])) b = tf.Variable(tf.zeros([10])) y = tf.matmul(x,W) + b cross_entropy = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)) train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)另外,我們說明一下pred值,該值就是我們得到的預測值。pred = tf.argmax(y,axis=1)

我們下載示例訓練部分的代碼並訓練這個模型。from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST_data', one_hot=True) sess = tf.InteractiveSession sess.run(tf.global_variables_initializer)for _ in range(1000): batch = mnist.train.next_batch(100) train_step.run(feed_dict={x: batch[0], y_: batch[1]})Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
接下來確保一切都如預期的那樣。我們用數據集中某個數字的圖片number%matplotlib inlineimport matplotlib.pyplot as plt number = mnist.train.next_batch(1)[0] plt.imshow(number.reshape(2828))<matplotlib.image.AxesImage at 0x7fa28919ae90>

確認一下我們的模型可以很快得到預測結果:

這個示例 99% 管用!

sess.run(pred,feed_dict={x: number})[0]6

現在我們要保存這個模型,並把它放在 tensorflow 服務裡面供外部調用。我們為要保存的權重和模型版本的定義一下保存路徑。

注意,如果你想保存另外一個模型的話,需要調高 「VERSION」 基準值,並且重構你的計算圖(重啟這 Jupyter notbook 腳本)。

EXPORT_PATH = "/tmp/models"VERSION=1

這裡我們保存得到的權重值。

from tensorflow.contrib.session_bundle import exporter saver = tf.train.Saver(sharded=True) model_exporter = exporter.Exporter(saver) model_exporter.init( sess.graph.as_graph_def, named_graph_signatures={
'inputs': exporter.generic_signature({'x': x}),
'outputs''pred': pred})}) model_exporter.export(EXPORT_PATH, tf.constant(VERSION), sess)
INFO:tensorflow:/tmp/models/00000001-tmp/export is notin all_model_checkpoint_paths. Manually adding it.'/tmp/models/00000001'

下面讓我們確認一下權重是否保存正確。

!ls -lhR /tmp/models/tmp/models: total 12K drwxr-xr-x 2 root root 4.0K Mar 1010:2900000001-rw-r--r-- 1 root root 7.6K Mar 1010:29 model.log

/tmp/models/00000001: total 72K -rw-r--r-- 1 root root 119 Mar 1010:29 checkpoint -rw-r--r-- 1 root root 31K Mar 1010:29export.data-00000-of-00001-rw-r--r-- 1 root root 159 Mar 1010:29export.index -rw-r--r-- 1 root root 29K Mar 1010:29export.meta
Services

當這個 Docker 鏡像啟動時,會運行 "example_jupyter/setup.sh"。其實下面的服務已經啟動:

  • jupyter notebook

這就是我們現在要運行的 jupyter notebook。

  • /serving/bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server

這是 TF 模型服務正在運行。它來自 TF 服務的標準分散式,使用 gRPC 協議調用模型。

  • /serving/bazel-bin/tensorflow_serving/example/flask_client

我還把這個 Flask web 應用從 REST 請求轉成 gPRC 請求。這樣做可能會降低運行性能,但是至少能把每一步過程搞清楚 - 你可以在下面的網頁中找到代碼:tensorflow_serving/example/flask_client.py.

讓我們驗證一下 TF 模型伺服器。截至目前,伺服器一直處於空閑狀態,正在等待文件夾里出現一個模型。我們現在可以檢查一下日誌來確定伺服器辨識並載入了剛剛存檔的模型:

!tail -n2 /tmp/models/model.log2017-03-1010:29:49.461339: I tensorflow_serving/core/loader_harness.cc:86] Successfully loaded servable version {name: default version: 1}
2017-03-1010:29:49.464518: I tensorflow_serving/model_servers/main.cc:257] Running ModelServer at 0.0.0.0:9000 ...
REST 請求

接下來的部分可以單獨運行之前做的 - 因此你可以在不同的 notebook 運行,或者說甚至在別的主機上運行

下面是用 REST 調用我們模型的函數的示例。

import numpy as np
import cPickle as pickle
import requests

deftest_flask_client(x): URL = "http://localhost:5000/model_prediction" s = pickle.dumps({"x":x}, protocol=0) DATA = {"model_name": "default"
"input": requests.utils.quote(s)} r = requests.get(URL, data=DATA)
return r.json

確保對訓練數據依然有效。

%matplotlib inline
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST_data', one_hot=True) number = mnist.train.next_batch(1)[0] plt.imshow(number.reshape(2828))
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

<matplotlib.image.AxesImage at 0x7fa28d001050>

預測過程

最後,用 Tensorflow 服務做預測。

test_flask_client(number){u'outputs': {u'pred': {u'dtype': u'DT_INT64'
u'int64Val': [u'7'],
u'tensorShape': {u'dim': [{u'size': u'1'}]}}}}

從這裡提取得到的預測值

int(test_flask_client(number)["outputs"]["pred"]["int64Val"][0])7 完成!

就這樣,你學會用 Tensorflow 服務的 Docker 容器調用 tensorflow 模型。這個模型需要 REST 或者 gRPC(埠 9000)

也容易導出 Docker 鏡像,可以在任何地方執行。在你的主機終端上執行下面的命令。 docker ps

會顯示你正在運行的容器的 ID,在下面的命令中用這容器 ID 替代 「xxxxx"。

docker commit XXXXXX my_name/my_model:version1

docker save my_name/my_model:version1 > my_name.my_model.version1.tar

你的(內置模型的)Docker 鏡像保存在 "tar」 包里,便於移動。我認為是這不是最佳實踐,但是有用。如果把這文件解壓到伺服器,用下面的命令執行。

docker load --input my_name.my_model.version1.tar

docker run --rm -it -p 8888:8888 -p 9000:9000 -p 5000:5000 my_name/my_model:version1

這你就在新的伺服器里運行你的模型。希望這篇博文能幫助到大家。

本期雷鋒字幕組志願者

另外,「雷鋒字幕組」也在招募更多的小夥伴加入。目前組內有來自華為、騰訊等大公司的 AI 從業者及高校青年學者。加入字幕組不僅可以結識很多志趣相投的夥伴,還能獲得雷鋒網內部的獨家資源福利,包括不定期線下聚會,免費的 AI 課程等。 有點心動?不如行動。

歡迎添加組長微信 jadelover11 加入字幕組~

新人福利



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦