Heim  >  Artikel  >  Backend-Entwicklung  >  Bereitstellung des Produktumgebungsmodells, Docker-Image, Bazel-Arbeitsbereich, Exportmodell, Server, Client

Bereitstellung des Produktumgebungsmodells, Docker-Image, Bazel-Arbeitsbereich, Exportmodell, Server, Client

巴扎黑
巴扎黑Original
2017-06-23 15:11:381347Durchsuche

Bereitstellung eines Produktumgebungsmodells, Erstellen einer einfachen Web-APP, Benutzer laden Bilder hoch, führen das Inception-Modell aus und realisieren eine automatische Bildklassifizierung.

Erstellen Sie eine TensorFlow-Dienstentwicklungsumgebung. Installieren Sie Docker, . Verwenden Sie die Konfigurationsdatei, um lokal ein Docker-Image zu erstellen, docker build --pull -t $USER/tensorflow-serving-devel . Um den Container auf dem Image auszuführen, führen Sie docker -v $HOME:/mnt/home -p 9999:9999 -it $USER/tensorflow-serving-devel aus und laden Sie ihn in den Container/mnt/home-Pfad im Home-Verzeichnis. und im Terminal arbeiten. Verwenden Sie eine IDE oder einen Editor, um den Code zu bearbeiten, verwenden Sie den Container, um das Build-Tool auszuführen, und greifen Sie über Port 9999 auf den Host zu, um den Server zu erstellen. Der Exit-Befehl verlässt das Containerterminal und stoppt die Ausführung.

Das TensorFlow-Dienstprogramm ist in C++ geschrieben und verwendet das Bazel-Build-Tool von Google. Der Container führt Bazel aus. Bazel verwaltet Abhängigkeiten von Drittanbietern auf Codeebene. Bazel lädt den Build automatisch herunter. Das Stammverzeichnis der Projektbibliothek definiert die WORKSPACE-Datei. Die TensorFlow-Modellbibliothek enthält den Inception-Modellcode.

Der TensorFlow-Dienst ist als Git-Submodul im Projekt enthalten. mkdir ~/serving_example, cd ~/serving_example, git init, git submodule add, tf_serving, git submodule update --init --recursive.

Die Regel „local_repository“ der WORKSPACE-Datei definiert Abhängigkeiten von Drittanbietern als lokale Speicherdateien. Das Projekt importiert die Regel tf_workspace, um TensorFlow-Abhängigkeiten zu initialisieren.

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",
actual = "@ langweiligssl_git //:ssl",
)

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

local_repository(
name = "inception_model",
path = __workspace_dir__ + "/tf_serving/tf_models/inception",
)

Exportieren Sie das trainierte Modell, exportieren Sie das Datenflussdiagramm und Variablen für Produkte. Das Modelldatenflussdiagramm muss Eingaben von Platzhaltern empfangen und die Ausgabe in einem einzigen Schritt berechnen. Das Inception-Modell (oder Bilderkennungsmodell im Allgemeinen), die JPEG-codierte Bildzeichenfolgeneingabe, unterscheidet sich vom Lesen der Eingabe aus der TFRecord-Datei. Definieren Sie den Eingabeplatzhalter, rufen Sie die Funktion zum Konvertieren des Platzhalters auf, um die externe Eingabe in das ursprüngliche Eingabeformat des Inferenzmodells darzustellen, konvertieren Sie die Bildzeichenfolge in einen Pixeltensor, wobei sich jede Komponente innerhalb von [0, 1] befindet, und skalieren Sie die Bildgröße entsprechend die erwartete Breite und Höhe des Modells. Der Pixelwert wird in das für das Modell erforderliche Intervall [-1, 1] umgewandelt. Rufen Sie die ursprüngliche Modellinferenzmethode auf und leiten Sie die Ergebnisse basierend auf der transformierten Eingabe ab.

Weisen Sie jedem Parameter der Inferenzmethode Werte zu. Parameterwerte vom Prüfpunkt wiederherstellen. Speichern Sie regelmäßig Prüfpunktdateien für das Modelltraining, die Lernparameter enthalten. Die zuletzt gespeicherte Trainingskontrollpunktdatei enthält die zuletzt aktualisierten Modellparameter. Gehen Sie zum Herunterladen der Checkpoint-Datei vor dem Training: . Im Docker-Container cd /tmp, curl -0 , tar -xzf inception-v3-2016-03-01.tar.gz.

tensorflow_serving.session_bundle.exporter.Exporter-Klasse exportiert das Modell. Übergeben Sie die Saver-Instanz, um die Instanz zu erstellen, und verwenden Sie exporter.classification_signature, um die Modellsignatur zu erstellen. Geben Sie den Eingabetensor und den Ausgabetensor an. „classes_tensor“ enthält eine Liste der Namen der Ausgabeklassen, und das Modell weist jeder Kategorie eine Punktzahl (oder Wahrscheinlichkeit) „socres_tensor“ zu. Für Modelle mit mehreren Kategorien gibt die Konfiguration an, dass nur tf.nntop_k zur Auswahl von Kategorien zurückgegeben wird und die Modellzuordnungswerte in absteigender Reihenfolge in die obersten K-Kategorien sortiert werden. Rufen Sie die Methodensignatur exporter.Exporter.init auf. Die Exportmethode exportiert das Modell und empfängt den Ausgabepfad, die Modellversionsnummer und das Sitzungsobjekt. Die Exporter-Klasse generiert automatisch Code mit Abhängigkeiten, und der Doker-Container verwendet Bazel, um den Exporter auszuführen. Der Code wird in bazel workspace exporter.py gespeichert.

Importzeit
System importieren

Tensorflow als TF importieren
von tensorflow_serving.session_bundle Import Exporter
von 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)
images = tf.image.resize_bilinear(tf .expand_dims(image, 0), [299, 299])
images = tf.mul(tf.sub(images, 0.5), 2)
Bilder zurückgeben

def inference(images) :
logits, _ = inception_model.inference(images, 1001)
return logits

external_x = tf.placeholder(tf.string)
x = convert_external_inputs(external_x)
y = Schlussfolgerung(x)

saver = tf.train.Saver()

mit tf.Session() as sess:
        ckpt = tf.train.get_checkpoint_state(sys.argv[1])
        if ckpt und ckpt.model_checkpoint_path:
            saver.restore(sess, sys.argv[1] + "/" + ckpt.model_checkpoint_path)
        else:
            print("Checkpoint-Datei nicht gefunden")
           erhöhen SystemExit

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

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

model_exporter = exporter.Exporter(saver)
        signatur = exporter.classification_signature(
            input_tensor=external_x,classes_tensor= Klassen, 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)

一个构建规则BUILD文件-v3 ist die neueste Version von TensorFlow.load, protobuf und protobuf Die cc_proto_library-Bibliothek ist die einzige, die die cc_proto_library-Bibliothek enthält.通过命令bazel run :server 9999 /tmp/inception-v3/export/{timestamp},容器运行推断服务器。

py_binary(
        name = "export",
        s rcs = [
            "export.py",
        ],
        deps = [
            "@tf_serving//tensorflow_serving/session_bundle:exporter",
            "@org_tensor flow//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 = ["@protobuf//:protobuf"],
        protoc="@protobuf//:protoc",
        default_runtime="@protobuf//:protobuf",
        use_grpc_plugin=1
    )

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

定义服务器接口。TensorFlow服务使用gRPC协议(基于HTTP/2二进制协议). Protokollpuffer, gRPC分数排列推断类别列表.定义在classification_service.proto文件。接收图像、音频片段、文字服务可用可一接口.proto编译器转换proto文件为客户端和服务器类定义.bazel build:classification_service_proto可行构建,通过bazel-genfiles/ Classification_service.grpc.pb.h ist die neueste Version von ClassificationService::Service必须实现。检查bazel-genfiles/classification_service.pb.h查看request、response消息定义。proto定义变成每种类型C++接口。

syntax = "proto3";

Nachricht ClassificationRequest {
       // bytes input = 1;
       float petalWidth = 1;
       float petalHeight = 2;
       float sepalWidth = 3;
       float sepalHeight = 4;
    };

message ClassificationResponse {
       repeated ClassificationClassclasses = 1;
    };

Nachrichtenklassifizierungsklasse {
                                                                                                                                                            > }

Implementieren Sie den Inferenzserver. Laden Sie das exportierte Modell, rufen Sie die Inferenzmethode auf und implementieren Sie ClassificationService::Service. Exportieren Sie das Modell, erstellen Sie ein SessionBundle-Objekt, schließen Sie ein vollständig geladenes Datenflussdiagramm-TF-Sitzungsobjekt ein und definieren Sie die Metadaten der Klassifizierungssignatur des Exporttools. Die SessionBundleFactory-Klasse erstellt ein SessionBundle-Objekt, konfiguriert es so, dass es das Exportmodell unter dem durch pathToExportFiles angegebenen Pfad lädt, und gibt einen eindeutigen Zeiger auf die erstellte SessionBundle-Instanz zurück. Definieren Sie ClassificationServiceImpl und empfangen Sie SessionBundle-Instanzparameter.

Laden Sie die Klassifizierungssignatur, die GetClassificationSignature-Funktion lädt die Modellexportmetadaten ClassificationSignature, die Signatur gibt den logischen Namen des Eingabetensors des empfangenen Bildes an und das Ergebnis der Mapping-Inferenz des logischen Namens des Datenflussdiagramms des Ausgabetensors . Transformieren Sie die Protobuf-Eingabe in einen Inferenzeingabetensor, und der Anforderungsparameter kopiert die JPEG-codierte Bildzeichenfolge in den Inferenztensor. Um die Inferenz auszuführen, ruft sessionbundle das TF-Sitzungsobjekt ab, führt es einmal aus und übergibt die Eingabe- und Ausgabetensorinferenz. Der abgeleitete Ausgabetensor transformiert die Protobuf-Ausgabe, und das Ergebnis des Ausgabetensors wird in die ClassificationResponse-Nachricht kopiert und mit den Antwortausgabeparametern in der angegebenen Form formatiert. Richten Sie den gRPC-Server ein, konfigurieren Sie das SessionBundle-Objekt und erstellen Sie den Beispielcode für die ClassificationServiceImpl-Instanz.

#include

#include

#include

#include

#include "classification_service.grpc.pb.h"

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

using namespace std;

using namespace tensorflow:: Serving;

using namespace grpc;

unique_ptr createSessionBundle(const string& pathToExportFiles) {

SessionBundleConfig session_bundle_config = SessionBundleConfig();

unique_ptr bundle_factory;
SessionBundleFactory: ;turn sessionBundle;
}


class ClassificationServiceImpl final: public ClassificationService::Service {

private:

unique_ptr sessionBundle;


public:

ClassificationServiceImpl(unique_ptr sessionBundle) :

sessionBundle(move(sessionBundle)) {};

Status classify(ServerContext* context, const ClassificationRequest* request,

ClassificationResponse * Antwort) override {

ClassificationSignature Signatur;

const tensorflow::Status SignaturStatus =
GetClassificationSignature(sessionBundle->meta_graph_def, &signature);

if (!signatureStatus.ok ()) {
return Status(StatusCode: :INTERNAL, signaturStatus.error_message());
          }

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

vector Outputs;


const tensorflow::Status inferenceStatus = sessionBundle->session->Run(
                                                                                                                                                           🎜>           &outputs);

if (!inferenceStatus.ok()) {
                                                                                 🎜>

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
           
            """

Antwort = Form % Antwort

self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.send_header("Content-length", len(response))
            self.end_headers( )
            self.wfile.write(response)

def do_POST(self):

form = cgi.FieldStorage(
                fp=self.rfile,
               headers= self.headers,
                environ={
                  'REQUEST_METHOD': 'POST',
                  'CONTENT_TYPE': self.headers['Content-Type'],
                })

request = classification_service_pb2.ClassificationRequest()
         = classification_service_pb2.beta_create_ClassificationService_stub(channel)

            Response = stub.classify(request, 10) # 10 Sekunden Timeout


self.respond_form("

Response: %s
" % Antwort )

    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 Sie haben die Möglichkeit, Docker-Geräte zu installieren.

参考资料:

《面向机器智能的TensorFlow实践》

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

Das obige ist der detaillierte Inhalt vonBereitstellung des Produktumgebungsmodells, Docker-Image, Bazel-Arbeitsbereich, Exportmodell, Server, Client. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn