iOS-App zur Vorhersage von Werten erstellen

1. Hinweis

In diesem Codelab lernen Sie, wie Sie mithilfe von TensorFlow Serving mit REST und gRPC eine Regressionsinferenz von einer iOS-App ausführen.

Vorbereitung

  • Grundkenntnisse der iOS-Entwicklung mit Swift
  • Grundkenntnisse in Machine Learning mit TensorFlow, z. B. für Training und Bereitstellung
  • Grundlagenwissen zu Colaboratory
  • Grundkenntnisse zu Terminals, Python und Docker

Lerninhalte

  • Regressionsmodellsmodell mit TensorFlow trainieren.
  • Hier erfahren Sie, wie Sie mit TensorFlow (REST und gRPC) mit dem trainierten Modell eine einfache iOS-App erstellen und Vorhersagen treffen.
  • So können Sie das Ergebnis in der Benutzeroberfläche anzeigen lassen.

Voraussetzungen

2. Einrichten

So laden Sie den Code für dieses Codelab herunter:

  1. Rufen Sie das GitHub-Repository für dieses Codelab auf.
  2. Klicken Sie auf Code gt; ZIP herunterladen, um den gesamten Code für dieses Codelab herunterzuladen.

a72f2bb4caa9a96

  1. Entpacken Sie die heruntergeladene ZIP-Datei, um den Stammordner codelabs mit allen benötigten Ressourcen zu entpacken.

Für dieses Codelab benötigen Sie nur die Dateien im Unterverzeichnis TFServing/RegressioniOS des Repositorys mit zwei Ordnern:

  • Der Ordner starter enthält den Startcode, den Sie für dieses Codelab erstellen.
  • Der Ordner finished enthält den abgeschlossenen Code für die fertige Beispiel-App.

3. Abhängigkeiten für das Projekt herunterladen

Erforderliche Pods herunterladen

  • Führen Sie im Ordner starter/iOS Folgendes aus:
pod install

Cocoapods installiert alle erforderlichen Bibliotheken und generiert eine neue regression.xcworkspace-Datei.

4. Start-App ausführen

  • Klicken Sie doppelt auf die Datei regression.xcworkspace, um Xcode zu öffnen.

App ausführen und entdecken

  1. Ändern Sie das Zielgerät auf ein beliebiges iPhone, z. B. iPhone 13.

a57198a4f21f970

  1. Klicken Sie auf Cacc15c5638260ed.png Run' und warten Sie, bis Xcode das Projekt kompiliert und die Start-App im Simulator startet.

Die Benutzeroberfläche ist ziemlich einfach. Es gibt ein Textfeld, in das Sie eine Zahl eingeben können. Diese Nummer wird an das TensorFlow-Back-End mit REST oder gRPC gesendet. Das Back-End führt eine Regression im Eingabewert aus und gibt den vorhergesagten Wert an die Client-App zurück, mit der das Ergebnis noch einmal in der UI angezeigt wird.

d2976072474ce0b1

Wenn Sie eine Zahl eingeben und auf Ableiten klicken, passiert nichts, da die App noch nicht mit dem Back-End kommunizieren kann.

5. Einfaches Regressionsmodell mit TensorFlow trainieren

Regression ist eine der häufigsten ML-Aufgaben. Ziel ist es, basierend auf den Eingaben eine einzelne kontinuierliche Menge vorherzusagen. Anhand des aktuellen Wetters können Sie zum Beispiel morgen die höchste Temperatur vorhersagen.

Regressionsmodell trainieren

  1. Öffnen Sie diesen Link in Ihrem Browser.

Colab lädt das Python-Notebook.

  1. Importieren Sie in das Python-Notebook die Bibliotheken TensorFlow und NumPy und erstellen Sie dann sechs Paar Trainingsdaten mit xs als Eingabe und ys als Labels.

Wenn Sie diese Datenpunkte auf einer Grafik darstellen, liegen sie in einer direkten Linie, weil sie aus der Gleichung y = 2x -1 generiert werden.

56d05252cfc9df9d

  1. Sie können mit der Keras API ein einfaches neuronales Netzwerk mit zwei Schichten erstellen, um den y-Wert basierend auf der x-Eingabe vorherzusagen, und dann das Modell kompilieren und anpassen.
xs = np.array([-1.0,  0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)

model = tf.keras.Sequential([
   tf.keras.layers.Dense(units=10, input_shape=[1]),
   tf.keras.layers.Dense(units=1),
   ])

model.compile(optimizer='sgd',
             loss='mean_squared_error')

history = model.fit(xs, ys, epochs=500, verbose=0)

print("Finished training the model")

print(model.predict([10.0]))

Das Training des Modells dauert einige Sekunden. Der vorhergesagte Wert für die 10-Eingabe ist 18.999996. Das ist eine ziemlich gute Vorhersage, da die Ground Truth „2 * 10 - 1 = 19“ ist.

  1. Exportieren Sie das Modell:
model_dir = './regression/'
version = 123
export_path = os.path.join(model_dir, str(version))
model.save(export_path, save_format="tf")
print('\nexport_path = {}'.format(export_path))
!ls -l {export_path}
  1. Komprimieren Sie das exportierte SavedModel in eine einzelne regression.zip-Datei:
!zip -r regression.zip ./regression
  1. Klicken Sie im Navigationsmenü auf Laufzeit > Ausführen, um das Notebook auszuführen, und warten Sie, bis die Ausführung abgeschlossen ist.
  2. Klicke auf c55600d42359f901.png Dateien und lade dann die Datei regression.zip herunter.

bceda15d86571583

6. Regressionsmodell mit TensorFlow Serving bereitstellen

  • Um das Modell mit TensorFlow Serving bereitzustellen, dekomprimieren Sie die heruntergeladene Datei regression.zip mit einem Dekomprimierungstool, z. B. 7-Zip.

Die Ordnerstruktur sollte so aussehen:

7faeb4f03af39646

Du kannst den Ordner regression als Ordner SavedModel verwenden. 123 ist eine Beispielversionsnummer. Wenn du möchtest, kannst du eine andere Nummer auswählen.

TensorFlow-Bereitstellung starten

  • Starten Sie in Ihrem Terminal TensorFlow Serving mit Docker, aber ersetzen Sie den Platzhalter PATH/TO/SAVEDMODEL durch den absoluten Pfad des Ordners regression auf Ihrem Computer.
docker pull tensorflow/serving

docker run -it --rm -p 8500:8500 -p 8501:8501 -v "PATH/TO/SAVEDMODEL:/models/regression" -e MODEL_NAME=regression tensorflow/serving

Docker lädt automatisch das TensorFlow Serving-Image herunter. Das dauert eine Minute. Danach sollte die TensorFlow-Bereitstellung beginnen. Das Protokoll sollte so aussehen:

2022-02-25 06:01:12.513231: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle.
2022-02-25 06:01:12.585012: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 3000000000 Hz
2022-02-25 06:01:13.395083: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/ssd_mobilenet_v2_2/123
2022-02-25 06:01:13.837562: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 1928700 microseconds.
2022-02-25 06:01:13.877848: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/ssd_mobilenet_v2_2/123/assets.extra/tf_serving_warmup_requests
2022-02-25 06:01:13.929844: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: regression version: 123}
2022-02-25 06:01:13.985848: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models
2022-02-25 06:01:13.985987: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled
2022-02-25 06:01:13.988994: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ...
[warn] getaddrinfo: address family for nodename not supported
2022-02-25 06:01:14.033872: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ...
[evhttp_server.cc : 245] NET_LOG: Entering the event loop ...

7. iOS-App mit TensorFlow Serving über REST verbinden

Das Back-End ist jetzt bereit, sodass Sie Clientanfragen an Vorhersagen senden können, um Vorhersagen zu treffen. Es gibt zwei Möglichkeiten, Anfragen an die TensorFlow-Bereitstellung zu senden:

  • REST
  • gRPC

Anfragen mit REST senden und Antworten erhalten

Es sind drei einfache Schritte:

  1. Erstellen Sie die REST-Anfrage.
  2. Senden Sie die REST-Anfrage an TensorFlow Serving.
  3. Extrahieren Sie das vorhergesagte Ergebnis aus der REST-Antwort und rendern Sie die UI.

Diese Schritte führen Sie in der Datei iOS/regression/ViewController.swift aus.

REST-Anfrage erstellen

  1. Aktuell sendet die Funktion doInference() die REST-Anfrage nicht an TensorFlow Serving. Sie müssen diesen REST-Branch implementieren, um eine REST-Anfrage zu erstellen:
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
    print("Using REST")
    // TODO: Add code to send a REST request to TensorFlow Serving.
    
}

Für TensorFlow Serving wird eine POST-Anfrage erwartet, die einen einzelnen Wert enthält. Sie müssen also den Eingabewert in eine JSON-Datei einbetten, also die Nutzlast der Anfrage.

  1. Fügen Sie diesen Code dem REST-Branch hinzu:
//Create the REST request.
let json: [String: Any] = ["signature_name" : "serving_default", "instances" : [[value]]]

let jsonData = try? JSONSerialization.data(withJSONObject: json)

let url = URL(string: "http://localhost:8501/v1/models/regression:predict")!
var request = URLRequest(url: url)
request.httpMethod = "POST"

// Insert JSON data into the request.
request.httpBody = jsonData

REST-Anfrage an TensorFlow Serving senden

  • Fügen Sie diesen Code direkt nach dem Code im REST-Branch hinzu:
// Send the REST request.
let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {
        print(error?.localizedDescription ?? "No data")
        return
    }
    
    // TODO: Add code to process the response.
}

task.resume()

REST-Antwort von TensorFlow Serving verarbeiten

  • Fügen Sie diesen Code unmittelbar nach dem Kommentar TODO: Add code to process the response. in das vorherige Code-Snippet ein:
// Process the REST response.
let results: RESTResults = try! JSONDecoder().decode(RESTResults.self, from: data)
DispatchQueue.main.async{
    self.txtOutput.text = String(results.predictions[0][0])
}

Die Nachbearbeitungsfunktion extrahiert jetzt vorhergesagte Werte aus der Antwort und zeigt das Ergebnis in der Benutzeroberfläche an.

Ausführen

  1. Klicken Sie auf Cacc15c5638260ed.png Ausführen und warten Sie, bis Xcode die App im Simulator startet.
  2. Geben Sie eine Zahl in das Textfeld ein und klicken Sie auf Ableiten.

Auf der Benutzeroberfläche wird jetzt ein vorhergesagter Wert angezeigt.

df9bcb9aa21bb30e.png

8. iOS-App mit TensorFlow über gRPC verbinden

Zusätzlich zur REST-Unterstützung unterstützt TensorFlow Serving auch BeyondCorp.

b6f4449c2c850b0e.png

gRPC ist ein modernes, leistungsstarkes Open-Source-RPC-Framework (Remote Procedure Call), das in jeder Umgebung ausgeführt werden kann. Dank der flexiblen Unterstützung für Load-Balancing, Tracing, Systemdiagnose und Authentifizierung lassen sich Dienste effizient in und zwischen Rechenzentren verbinden. Es wurde festgestellt, dass gRPC in der Praxis leistungsstärker ist als REST.

Anfragen mit gRPC senden und Antworten erhalten

Es sind vier einfache Schritte:

  1. Optional: Erstellen Sie den gRPC-Client-Stub-Code.
  2. Erstellen Sie die gRPC-Anfrage.
  3. Senden Sie die gRPC-Anfrage an TensorFlow Serving.
  4. Extrahieren Sie das vorhergesagte Ergebnis aus der gRPC-Antwort und rendern Sie die UI.

Diese Schritte führen Sie in der Datei iOS/regression/ViewController.swift aus.

Optional: gRPC-Client-Stub-Code generieren

Wenn Sie gRPC mit TensorFlow Serving verwenden möchten, müssen Sie dem gRPC-Workflow folgen. Weitere Informationen finden Sie in der BeyondCorp-Dokumentation.

a9d0e5cb543467b4.png

Die Bereitstellung von .proto-Dateien wird durch TensorFlow Serving und TensorFlow definiert. Ab TensorFlow und TensorFlow Serving 2.8 sind diese .proto-Dateien erforderlich:

tensorflow/core/example/example.proto
tensorflow/core/example/feature.proto
tensorflow/core/protobuf/struct.proto
tensorflow/core/protobuf/saved_object_graph.proto
tensorflow/core/protobuf/saver.proto
tensorflow/core/protobuf/trackable_object_graph.proto
tensorflow/core/protobuf/meta_graph.proto
tensorflow/core/framework/node_def.proto
tensorflow/core/framework/attr_value.proto
tensorflow/core/framework/function.proto
tensorflow/core/framework/types.proto
tensorflow/core/framework/tensor_shape.proto
tensorflow/core/framework/full_type.proto
tensorflow/core/framework/versions.proto
tensorflow/core/framework/op_def.proto
tensorflow/core/framework/graph.proto
tensorflow/core/framework/tensor.proto
tensorflow/core/framework/resource_handle.proto
tensorflow/core/framework/variable.proto

tensorflow_serving/apis/inference.proto
tensorflow_serving/apis/classification.proto
tensorflow_serving/apis/predict.proto
tensorflow_serving/apis/regression.proto
tensorflow_serving/apis/get_model_metadata.proto
tensorflow_serving/apis/input.proto
tensorflow_serving/apis/prediction_service.proto
tensorflow_serving/apis/model.proto

So generieren Sie den gRPC-Client-Stub-Code:

  1. Gehen Sie in Ihrem Terminal zum Ordner starter/src/proto/ und generieren Sie die Stubs:
bash generate_grpc_stub_swift.sh

Im Ordner starter/src/proto/generated/import werden .swift-Dateien generiert.

  1. Wenn sie noch nicht in Ihr Projekt kopiert wurden, ziehen Sie alle generierten .swift-Dateien in das Xcode-Projekt.

9e65705cf6be7aac

gRPC-Anfrage erstellen

Ähnlich wie bei der REST-Anfrage erstellen Sie die gRPC-Anfrage im gRPC-Branch.

if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
    
}
else {
    print("Using gRPC")
    // TODO: add code to send a gRPC request to TF Serving
    
}
  • Fügen Sie dem gRPC-Branch folgenden Code hinzu, um die gRPC-Anfrage zu erstellen:
//Create the gRPC request.
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let channel = ClientConnection.insecure(group: group).connect(host: "localhost", port: 8500)
let stub = Tensorflow_Serving_PredictionServiceClient(channel: channel)

var modelSpec = Tensorflow_Serving_ModelSpec()
modelSpec.name = "regression"
modelSpec.signatureName = "serving_default"

// Prepare the input tensor.
var batchDim = Tensorflow_TensorShapeProto.Dim()
batchDim.size = 1
var inputDim = Tensorflow_TensorShapeProto.Dim()
inputDim.size = 1
var inputTensorShape = Tensorflow_TensorShapeProto()
inputTensorShape.dim = [batchDim, inputDim]
var inputTensor = Tensorflow_TensorProto()
inputTensor.dtype = Tensorflow_DataType.dtFloat
inputTensor.tensorShape = inputTensorShape
inputTensor.floatVal = [Float(value)]

var request = Tensorflow_Serving_PredictRequest()
request.modelSpec = modelSpec
request.inputs = ["dense_input" : inputTensor]

let callOptions = CallOptions(timeLimit: .timeout(.seconds(15)))

gRPC-Anfrage an TensorFlow Serving senden

  • Fügen Sie diesen Code direkt nach dem Code im vorherigen Code-Snippet in den gRPC-Branch ein:
// Send the gRPC request.
let call = stub.predict(request, callOptions: callOptions)

gRPC-Antwort von TensorFlow Serving verarbeiten

  • Fügen Sie diesen Code direkt nach dem Code im vorherigen Code-Snippet ein:
// Process the response.
call.response.whenSuccess { response in
    let result = response.outputs["dense_1"]?.floatVal[0]
    DispatchQueue.main.async{
        self.txtOutput.text = String(describing: result!)
    }
}
call.response.whenFailure { error in
    print("Call failed with error\n\(error)")
}

Die Nachbearbeitungsfunktion extrahiert jetzt vorhergesagte Werte aus der Antwort und zeigt das Ergebnis in der Benutzeroberfläche an.

Ausführen

  1. Klicken Sie im Navigationsmenü auf Cacc15c5638260ed.png Ausführen und warten Sie, bis Xcode die App im Simulator startet.
  2. Geben Sie eine Zahl in das Textfeld ein und klicken Sie auf Ableiten.

Auf der Benutzeroberfläche wird jetzt ein vorhergesagter Wert angezeigt.

9. Glückwunsch

Sie haben mithilfe von TensorFlow Serving Regressionen in Ihre App eingefügt.

Weitere Informationen