產品環境模型部署、Docker映像、Bazel工作區、匯出模型、伺服器、用戶端

巴扎黑
發布: 2017-06-23 15:11:38
原創
1353 人瀏覽過

產品環境模型部署,建立簡單Web APP,使用者上傳映像,運行Inception模型,實現映像自動分類。

建置TensorFlow服務開發環境。安裝Docker, 。用設定檔在本機上建立Docker映像,docker build --pull -t $USER/tensorflow-serving-devel  。映像運行容器,docker run -v $HOME:/mnt/home -p 9999:9999 -it $USER/tensorflow-serving-devel ,在home目錄載入到容器/mnt/home路徑,在終端機工作。用IDE或編輯器編輯程式碼,用容器運行建置工具,主機透過9999埠訪問,建置伺服器。 exit命令退出容器終端,停止運作。

TensorFlow服務程式C++寫,使用Google的Bazel建置工具。容器運行Bazel。 Bazel程式碼級管理第三方相依性。 Bazel自動下載建置。專案庫根目錄定義WORKSPACE檔案。 TensorFlow模型庫包含Inception模型程式碼。

TensorFlow服務在專案中作為Git子模組。 mkdir ~/serving_example,cd ~/serving_example,git init,git submodule add  ,tf_serving,git submodule update --init --recursive 。

WORKSPACE檔案local_repository規則定義第三方依賴為本機儲存檔案。專案導入tf_workspace規則初始化TensorFlow相依性。

workspace(name = "serving")

local_repository(
        name = "tf_serving",
        path = __workspace_dir__ + "/tf_serving",# 
local_repository(

        name = "org_tensorflow",

        path = __workspace_dir__ + "/tf_serving/tensorflow    path = __workspace_dir__ + "/tf_serving/tensorflow .bzl', 'tf_workspace')
    tf_workspace("tf_serving/tensorflow/", "@org_tensorflow")

bind(

        name = "libssl",

#         name = "libssl",# sl  //:ssl",
    )

bind(
        name = "zlib",
        actual = "@zlib_archive//: #local_repository(
        name = "inception_model",

        path = __workspace_dir__ + "//tf_serving/tf_models/inception",#workspace_dir__ + "/tf_serving/tf_models/inception",##  

,給產品用。模型資料流程圖,必須從佔位符接收輸入,單步推斷計算輸出。 Inception模型(或一般影像辨識模型),JPEG編碼影像字串輸入,與從TFRecord檔案讀取輸入不同。定義輸入佔位符,呼叫函數轉換佔位符表示外部輸入為原始推斷模型輸入格式,影像字串轉換為各分量位於[0, 1]內像素張量,縮放影像尺寸,符合模型期望寬度高度,像素值轉換到模型要求區間[-1, 1]內。呼叫原始模型推斷方法,依據轉換輸入推斷結果。

推斷方法各參數賦值。從檢查點恢復參數值。週期性保存模型訓練檢查點文件,文件包含學習參數。最後一次儲存訓練檢查點檔案包含最後更新模型參數。下去載預訓練檢查點文件: 。在Docker容器中,cd /tmp, curl -0 , tar -xzf inception-v3-2016-03-01.tar.gz 。

tensorflow_serving.session_bundle.exporter.Exporter類別匯出模型。傳入保存器實例建立實例,用exporter.classification_signature建立模型簽章。指定input_tensor、輸出張量。 classes_tensor 包含輸出類別名稱清單、模型分配各類別分數(或機率)socres_tensor。類別數多模型,配置指定僅返田大口tf.nntop_k選擇類別,模型分配分數降序排列前K個類別。呼叫exporter.Exporter.init方法簽名,export方法導出模型,接收輸出路徑、模型版本號、會話物件。 Exporter類別自動產生程式碼有依賴,Doker容器內部使用中bazel執行導出器。程式碼儲存到bazel工作區exporter.py。


import time
    import sys

import tensorflow as tf

    from tensorflow_serving.session_bundle import exporter##del

##def convert_external_inputs(external_x):

        image = tf.image.convert_image_dtype(tf.image.decode_jpeg(external_x, channels=3), tf.image.decode_jpeg(external_x, chan3m=3), tf.image.decode_jpeg(external_x, chan3_3), tf.flo~ tf .expand_dims(image, 0), [299, 299])

        images = tf.mul(tf.sub(images, 0.5), 2)

        return     return :

        logits, _ = inception_model.inference(images, 1001)

        return logits

external_x = c.placeholder(tf.str.  y = inference(x)

saver = tf.train.Saver()

##with tf.Session() as sess:

        ckpt = tf.train.get_checkpoint_state(sys.argv[1])##     pt 和ckpt.model_checkpoint_path:
            saver.restore(sess, sys.argv[1] + "/" + ckpt.model_checkpoint_path)
 )#  # raise SystemExit

scores, class_ids = tf.nn.top_k(y, NUM_CLASSES_TO_RETURN)

classes = tf.contrib.lookup.index_to_string( tf .constant([str(i) for i in range(1001)]))

model_exporter = exporter.Exporter(saver)

        簽名= exporter.classification_signature(##sor0,   =類,scores_tensor=scores)

        model_exporter.init(default_graph_signature=signature, init_op=tf.initialize_all_tables())
      的 model_exporter. . time()), sess)

一個建置規則BUILD檔。 inception -v3提到的檢查點檔案在/tmp/inception-v3/{currenttimestamp}/建立匯出器。 。 #             "export.py",
          "export.py",
        ],
        deps = [
            "@org_tensorflow //tensorflow:tensorflow_py",

            ” @inception_model//inception",

        ],

    )


#("@protobuf//:protobuf.bzl", "cc_proto_library")
#licc name="classification_service_proto",
        srcs=["classification_service.proto"],
        cc_libs = ["@protobuf//:protobuf"],         use_grpc_plugin=1
    )##> [
            " server.cc",
            ],
        deps = [
            ": 選擇 flow:session_bundle_factory",

           「@grpc//: grpc++",

            ],

    )


定義伺服器介面。TensorFlow服務使用gRPC協定(基於HTTP/2二進位協定)。支援建立伺服器和自動產生客戶端存根各種語言協定。緩衝區定義服務契約,用於gRPC IDL(介面定義語言)和二進位編碼。文字服務可用的可一介面。 Service介面必須實作。 ClassificationRequest {
       // 位元組輸入= 1;
       float petalWidth = 1;
       float petalHeight = 1;
       float petalHeight = 2;#       float sepalHeight = 4;
    };

message ClassificationResponse {

       重複 ClassificationClass 類別 = 1;
    };

message ClassificationClass {
       string name = 1;
       float score = 2;
    }

##service ClassificationService { 21Classation 勾選

    }

實作推斷伺服器。載入導出模型,呼叫推斷方法,實作ClassificationService::Service。匯出模型,建立SessionBundle對象,包含完全載入資料流程圖TF會話對象,定義匯出工具分類簽章元資料。 SessionBundleFactory類別建立SessionBundle對象,配置為pathToExportFiles指定路徑載入匯出模型,傳回建立SessionBundle實例unique指標。定義ClassificationServiceImpl,接收SessionBundle實例參數。

載入分類簽名,GetClassificationSignature函數載入模型匯出元資料ClassificationSignature,簽章指定所接收影像真實名稱的輸入張量邏輯名稱,以及資料流程圖輸出張量邏輯名稱對應推斷結果。將protobuf輸入變換為推斷輸入張量,request參數複製JPEG編碼影像字串到推斷張量。運行推斷,sessionbundle獲得TF會話對象,運行一次,傳入輸入輸出張量推斷。推斷輸出張量變換protobuf輸出,輸出張量結果複製到ClassificationResponse訊息指定形狀response輸出參數格式化。設定gRPC伺服器,SessionBundle物件配置,建立ClassificationServiceImpl實例樣板程式碼。

#include

    #include

    #include

#include

#include include "classification_service.grpc.pb.h"

#include "tensorflow_serving/servables/tensorflow/session_bundle_factory.h"

using namespace stdflow;

問題serving;
    using namespace grpc;

unique_ptr createSessionBundle(const string& pathToExportFiles) {

  問題       unique_ptr bundle_factory;
       SessionBundleFactory: :Create(session_bundle_config, &bundle_factory);

。 #     }


    class ClassificationServiceImpl final : public ClassificationService::Service {

private:
       unique_ptr sessionBundle;##coo lt;SessionBundle> sessionBundle) :

       sessionBundle(move(sessionBundle)) {};


Status classify(ServerContext* context, const ClassificationRe* ride {

ClassificationSignature 。     return Status(StatusCode: :INTERNAL, signatureStatus.error_message());
          }

tensorflow::Tensor input(tensorflow::DT_STRING, tensorflow::TensorShape()); () = request->input();

vector outputs;

const tensorflow::Status inferenceStatus = sessionBundle->session->Run(
             {{signature.input().tensor_name(), input}},

             {signature. {},

             &outputs);

if (!inferenceStatus.ok()) {

             return Status(StatusCode::INTERNAL. 選

for (int i = 0; i < outputs[0].NumElements(); ++i) {
ClassificationClass *classificationClass = response->add_classes();
             classificationClass->set_name(outputs[0].flat()(i));
             classificationClass->set_score(outputs[1].flat()(i));
          }

return Status::OK;

}
    };


    int main(int argc, char** argv) {

if (argc < 3) {
cerr << "Usage: server /path/to/export/files" << endl;
          return 1;
        }

const string serverAddress(string("0.0.0.0:") + argv[1]);
       const string pathToExportFiles(argv[2]);

unique_ptr sessionBundle = createSessionBundle(pathToExportFiles);

ClassificationServiceImpl classificationServiceImpl(move(sessionBundle));

ServerBuilder builder;
        builder.AddListeningPort(serverAddress, grpc::InsecureServerCredentials());
        builder.RegisterService(&classificationServiceImpl);

unique_ptr server = builder.BuildAndStart();
        cout << "Server listening on " << serverAddress << endl;

server->Wait();

return 0;
    }

通过服务器端组件从webapp访问推断服务。运行Python protocol buffer编译器,生成ClassificationService Python protocol buffer客户端:pip install grpcio cython grpcio-tools, python -m grpc.tools.protoc -I. --python_out=. --grpc_python_out=. classification_service.proto。生成包含调用服务stub classification_service_pb2.py 。服务器接到POST请求,解析发送表单,创建ClassificationRequest对象 。分类服务器设置一个channel,请求提交,分类响应渲染HTML,送回用户。容器外部命令python client.py,运行服务器。浏览器导航http://localhost:8080 访问UI。

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

import cgi
    import classification_service_pb2
    from grpc.beta import implementations

class ClientApp(BaseHTTPRequestHandler):
        def do_GET(self):
            self.respond_form()

def respond_form(self, response=""):

form = """
           
           

Image classification service


           

           
Image:

           

           
            %s
           
# self. send_response(200)

            self.send_header("Content-type", "text/html")

           self.end_headers( )

            self.wfile.write(response)


def do_POST(self):

form = cgi.FieldStorage(
       headers= self. headers,

                environ={

                    'REQUEST_METHOD': 'POST,#>  TYPE': self.headers['內容類型'],

               })


request = classification_service_pb2 .ClassificationRequest()
            request.input = form['file'].file.read()

channel = Implements.insecure_channel("127.0.0.1", 9999) 存根 9999) ? beta_create_ClassificationService_stub(channel)
            response = Stub.classify(request, 10) # 10 秒逾時

self.respond_form("
回應: %s
回應: %#)>


    if __name__ == '__main__':

        host_port = ('0.0.0.0', 8080)

      host print "Serving in 70%" ClientApp).serve_forever()

產品準備,分類伺服器應用程式產品。 serving_example,cp -R bazel-bin/。 /opt/classification_server, bazel clean 。

參考資料:

《機器智能的TensorFlow實踐》


歡迎付費諮詢(150元人民幣),我的微信:qingxingfengzi
#

以上是產品環境模型部署、Docker映像、Bazel工作區、匯出模型、伺服器、用戶端的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板