ホームページ  >  記事  >  バックエンド開発  >  製品環境モデルのデプロイメント、Docker イメージ、Bazel ワークスペース、エクスポート モデル、サーバー、クライアント

製品環境モデルのデプロイメント、Docker イメージ、Bazel ワークスペース、エクスポート モデル、サーバー、クライアント

巴扎黑
巴扎黑オリジナル
2017-06-23 15:11:381296ブラウズ

製品環境モデルの展開、シンプルな Web APP の作成、ユーザーによる画像のアップロード、インセプション モデルの実行、自動画像分類の実現。

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 を実行し、それをホーム ディレクトリのcontainer/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 サブモジュールの追加、tf_serving、git サブモジュールの更新 --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",
)

load('//tf_serving/tensorflow/tensorflow:workspace.bzl', 'tf_workspace')
tf_workspace("tf_serving/tensorflow/", "@org_tensorflow")

bind(
name = "libssl",
実際 = "@boringssl_git//:ssl",
)

bind(
) name = "zlib",
実際 = "@zlib_archive//:zlib",
)

local_repository (
name = "inception_model",
Path = __workspace_dir__ + "/tf_serving/tf_models/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 sys

import tensorflow as tf
from tensorflow_serving.session_bundle import exporter
from inception import inception_model

NUM_CLASSES_TO_RETURN = 10

def Convert_external_inputs (external_x) :
image = tf.image.convert_image_dtype(tf.image .decode_jpeg(external_x, Channels=3), tf.float32)
画像 = tf.image.resize_bilinear(tf.expand_dims(image, 0), [299, 299])
画像 = tf.mul(tf.sub(images 、0.5)、2)
def inference(images):‑‑ (‑ ) x = Convert_external_inputs( external_x)

y = inference(x)

saver = tf.train.Saver()

with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(sys.argv[1])
if ckpt および ckpt.model_checkpoint_path:
saver.restore( sess, sys.argv[1] + "/" + ckpt.model_checkpoint_path)
else:
print("チェックポイント ファイルが見つかりません")
SystemExit スコアを上げます

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

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

model_exporter = exporter.Exporter(saver)
signature = exporter.classification_signature(
input_tensor=external_x,classes_tensor=classes,scores_tensor=scores)
model_exporter.init(default_graph_signature=signature, init_op=tf.initialize_all_tables() )
model_exporter.export(sys.argv[1] + " /export", tf.constant(time.time()), sess)

構築されたビルド ファイル。コンテナ内コマンド実行、cd /mnt/home/serving_example、hazel run:export /tmp/inception-v3 /tmp/inception-v3 で示された検出ポイント ファイルに基づいて、/tmp/inception-v3/{currenttimestamp}/ にあるハブが作成されます。最初に TensorFlow の評価が実行されます。load は外部から protobuf に入力され、cc_proto_library の定義が行われます。コマンドbazel run :server 9999 /tmp/inception-v3/export/{timestamp}により、コンテナは推論サーバーを実行します。

py_binary(
name = "export",
srcs = [
「エクスポート。 py",
],
deps = [
"@tf_serving//tensorflow_serving/session_bundle:exporter",
"@org_tensorflow//tensorflow:tensorflow_py",
"@inception_model//inception",
],
)

load("@protobuf//:protobuf.bzl", "cc_proto_library")

cc_proto_library(
name="classification_service_proto",
srcs=["classification_service.proto"],
cc_libs = ["@pro tobuf//:protobuf "],
protoc="@protobuf//:protoc",
default_runtime="@protobuf//:protobuf",
use_grpc_plugin=1
)

cc_binary(
name = ",
srcs = [
" server.cc",
],
deps = [
":classification_service_proto",
"@tf_serving//tensorflow_serving/servables/tensorflow:session_bundle_factory",
"@grpc//:grpc++",
],
)

TensorFlow サービスは、gRPC プロトコル (HTTP/2 ベース) を使用します。サーバーの構築と、さまざまなプロトコルのバッファリング サービス プロトコルをサポートします。制编コード分類画像文字列の入力となる JPEG を受信し、classification_service.proto ファイルに定義されます。 bazel build:classification_service_proto は、bazel-genfiles/classification_service.grpc.pb.h の結果を介して構築可能です。推論、ClassificationService::Service インターフェイスは必ず実行する必要があります。

syntax = "proto3";

messageclassificationRequest {
// bytes input = 1;
float petalWidth = 1;
float petalHeight = 2;
フロートセパル幅 = 3 ;
float sepalHeight = 4;
};

message事態ClassificationResponse {
繰り返しClassificationClassクラス = 1;
};

messageclassificationClass {
string name = 1;
float スコア = 2;エクスポートされたモデルを読み込み、推論メソッドを呼び出し、ClassificationService::Service を実装します。モデルをエクスポートし、SessionBundle オブジェクトを作成し、完全にロードされたデータ フロー グラフの TF セッション オブジェクトを含めて、エクスポート ツールの分類署名メタデータを定義します。 SessionBundleFactory クラスは、SessionBundle オブジェクトを作成し、pathToExportFiles で指定されたパスにエクスポート モデルをロードするように構成し、作成された SessionBundle インスタンスへの一意のポインタを返します。 ClassificationServiceImpl を定義し、SessionBundle インスタンス パラメーターを受け取ります。

分類署名をロードし、GetClassificationSignature 関数でモデル エクスポート メタデータ ClassificationSignature をロードし、署名は受信した画像の実名の入力テンソル論理名を指定し、データ フロー グラフはテンソル論理名マッピング推論結果を出力します。 protobuf 入力を推論入力テンソルに変換し、リクエスト パラメーターによって JPEG エンコードされた画像文字列が推論テンソルにコピーされます。推論を実行するために、sessionbundle は TF セッション オブジェクトを取得し、それを 1 回実行して、入力および出力のテンソル推論を渡します。推論された出力テンソルは protobuf 出力を変換し、出力テンソルの結果は、ClassificationResponse メッセージにコピーされ、応答出力パラメーターの形式が Shape で指定されます。 gRPC サーバーをセットアップし、SessionBundle オブジェクトを構成し、ClassificationServiceImpl インスタンスのサンプル コードを作成します。


#include
#include

#include

#include

#include "classification_service.grpc.pb.h"


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

名前空間 std を使用;

名前空間 tensorflow::serving を使用;

名前空間 grpc を使用;

unique_ptr createSessionBundle(const string& pathToExportFiles) {

SessionB undleConfig session_bundle_config = SessionBundleConfig( );

unique_ptrbundle_factory;

SessionBundleFactory::Create(session_bundle_config, &bundle_factory);

unique_ptrCreateSessionBundle(pathToExportFiles, & sessionBundle);

return sessionBundle;
}

classclassificationServiceImpl Final : publicclassificationService::Service {


private:

unique_ptr sessionBundle;


public:

classificationServiceImpl(unique_ptr sessionBundle) :

sessionBundle(move(sessionBundle)) {};

ステータス分類(サーバーコンテキスト* context、const 分類リクエスト* リクエスト、

Bundle->meta_graph_def, &signature);

if (!signatureStatus.ok ()) {

return Status(StatusCode::INTERNAL, signalStatus.error_message()); }

tensorflow::Tensor input(tensorflow::DT_STRING, tensorflow::TensorShape());

.scalar ()() = request->input();


vector tensorflow :: status IsenterenceStatus = sessionbundle-> session-> run(

).tensor_name()、input}}、

s.ok()){
return status(statuscode :: internal、intermencestatus.error_message( ));
}

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

"""

response = フォーム % レスポンス

self.send_response(200)
self.send_header("コンテンツタイプ" , "text/html")
self.send_header("Content-length", len(response))
self.end_headers()
self.wfile.write(response)

def do_POST(self):

形式 = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={
'REQUEST_METH OD': 'POST',
'CONTENT_TYPE': self.headers['Content-Type'],
})

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

channel =implements.insecure_channel("127.0.0.1", 9999)
stub =classification_service_pb2.be ta_create_ClassificationService_stub(チャネル)
response = stub.classify(request, 10) # 10 秒のタイムアウト

self.respond_form("

Response: %s
" % response)


if __name__ == '__main__':
host_port = ('0.0.0.0', 8080)
print "Serving in %s:%s" % host_port
HTTPServer(host_port, ClientApp).serve_forever()

产品標準备,分类服务器应使用製品。コンテナ内の、mkdir /opt/classification_server、cd /mnt/home/serving_example、cp -R bazel-bin/。 /opt/classification_server, bazel clean 。コンテナ外部、状態は新しい Docker イメージを渡し、仮想ファイル システム変更のニュース写真を作成します。コンテナ外部、docker ps、dock commit 。イメージは自分自身にプッシュされます。

参考资料:
《面向机智能的TensorFlow实実践》

欢迎付费咨询(150元每小時),我的微信:qingxingfengzi

以上が製品環境モデルのデプロイメント、Docker イメージ、Bazel ワークスペース、エクスポート モデル、サーバー、クライアントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。