Informazioni su questo codelab
1. Prima di iniziare
In questo codelab, imparerai a eseguire un'inferenza di regressione da un'app per iOS utilizzando TensorFlow Serving con REST e gRPC.
Prerequisiti
- Conoscenza di base dello sviluppo di iOS con Swift
- Conoscenza di base del machine learning con TensorFlow, ad esempio addestramento e deployment
- Conoscenza di base di Colaboratory
- Conoscenza di base di terminali, Python e Docker
Obiettivi didattici
- Come addestrare un modello di regressione con TensorFlow.
- Come creare un'app per iOS semplice e fare previsioni con il modello addestrato tramite TensorFlow Serving (REST e gRPC).
- Come visualizzare il risultato nell'interfaccia utente.
Che cosa ti serve
- Accesso a Colab
- L'ultima versione di Xcode
- CocoaPods
- Docker
- Palla
- Compilatore del buffer di protocollo (necessario solo se vuoi rigenerare lo stub gRPC da solo)
- Plug-in-generatore di codice gRPC-swift (necessario solo se vuoi generare lo stub gRPC da solo)
2. Configura
Per scaricare il codice per questo codelab:
- Accedi al repository GitHub per questo codelab.
- Fai clic su Codice > Scarica zip per scaricare tutto il codice di questo codelab.
- Decomprimi il file ZIP scaricato per decomprimere una cartella principale
codelabs
con tutte le risorse che ti servono.
Per questo codelab, hai bisogno solo dei file nella sottodirectory TFServing/RegressioniOS
del repository, che contiene due cartelle:
- La cartella
starter
contiene il codice di avvio che crei per questo codelab. - La cartella
finished
contiene il codice completato per l'app di esempio terminata.
3. Scarica le dipendenze per il progetto
Scarica i pod richiesti
- Nella cartella
starter/iOS
, esegui:
pod install
Cocoapods installerà tutte le librerie necessarie e genererà un nuovo file regression.xcworkspace
.
4. Esegui l'app iniziale
- Fai doppio clic sul file
regression.xcworkspace
per aprire Xcode.
Esegui ed esplora l'app
- Cambia il target del dispositivo in qualsiasi iPhone, ad esempio iPhone 13.
- Fai clic su
"Esegui', quindi attendi che Xcode compili il progetto e avvii l'app iniziale nel simulatore.
La UI è molto semplice. C'è una casella di testo in cui puoi digitare un numero che viene inviato al backend TensorFlow Serving con REST o gRPC. Il backend esegue la regressione sul valore di input e restituisce il valore previsto all'app client, che mostra nuovamente il risultato nell'interfaccia utente.
Se inserisci un numero e fai clic su Inferenza, non accade nulla perché l'app non è ancora in grado di comunicare con il backend.
5. Addestra un semplice modello di regressione con TensorFlow
La regressione è una delle attività ML più comuni. Il suo obiettivo è prevedere un'unica quantità continua in base all'input. Ad esempio, in base alle condizioni meteo di oggi, è prevista una temperatura massima domani.
Addestra un modello di regressione
- Apri questo link nel tuo browser.
Colab carica il blocco note Python.
- Nel blocco note Python, importa le librerie
TensorFlow
eNumPy
, quindi crea sei coppie di dati di addestramento conxs
come input eys
come etichette.
Se suddividi questi punti dati in un grafico, in realtà si trovano su una linea retta perché sono generati dall'equazione y = 2x -1.
- Utilizza l'API Keras per creare una semplice rete neurale a due livelli per prevedere il valore di
y
in base all'input dix
, quindi compilare e adattare il modello.
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]))
Il modello impiega qualche secondo per essere addestrato e puoi vedere il valore previsto per l'input 10
è 18.999996
, che è una previsione abbastanza buona perché la verità alla base è 2 * 10 -1 = 19.
- Esporta il modello:
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}
- Comprimi il Salvato modello esportato in un unico file
regression.zip
:
!zip -r regression.zip ./regression
- Fai clic su Runtime > Run all (Esegui tutto) nel menu di navigazione per eseguire il blocco note, quindi attendi il termine dell'esecuzione.
- Fai clic su
File e scarica il file
regression.zip
.
6. Esegui il deployment di un modello di regressione con TensorFlow Serving
- Per eseguire il deployment del modello con TensorFlow Serving, decomprimi il file
regression.zip
scaricato con uno strumento di decompressione, ad esempio 7-Zip.
La struttura delle cartelle dovrebbe essere simile a questa:
Puoi impostare la cartella regression
come cartella SavedModel
. 123
è un numero di versione di esempio. Se vuoi, puoi scegliere un altro numero.
Avvia la pubblicazione TensorFlow
- Nel terminale, avvia TensorFlow Serving con Docker, ma sostituisci il segnaposto
PATH/TO/SAVEDMODEL
con il percorso assoluto della cartellaregression
sul tuo 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 scarica automaticamente prima l'immagine di TensorFlow Serving, che richiede un minuto. In seguito, TensorFlow Serving dovrebbe iniziare. Il log dovrebbe avere il seguente aspetto:
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. Collega l'app per iOS a TensorFlow Serving tramite REST
Il backend è pronto, quindi puoi inviare richieste client a TensorFlow Serving per fare previsioni. Esistono due modi per inviare richieste a TensorFlow Serving:
- REST
- gRPC
Inviare richieste e ricevere risposte con REST
Ci sono tre semplici passaggi:
- Crea la richiesta REST.
- Invia la richiesta REST a TensorFlow Serving.
- Estrai il risultato previsto dalla risposta REST e visualizza l'interfaccia utente.
Completa questi passaggi nel file iOS/regression/ViewController.swift
.
Crea la richiesta REST
- Attualmente, la funzione
doInference()
non invia la richiesta REST a TensorFlow Serving. Devi implementare questo ramo REST per creare una richiesta REST:
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
print("Using REST")
// TODO: Add code to send a REST request to TensorFlow Serving.
}
TensorFlow Serving prevede una richiesta POST che contiene un singolo valore, quindi è necessario incorporare il valore di input in un JSON, che è il payload della richiesta.
- Aggiungi questo codice al ramo REST:
//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
Invia la richiesta REST a TensorFlow Serving
- Aggiungi questo codice subito dopo il codice nel ramo REST:
// 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()
Elabora la risposta REST da TensorFlow Serving
- Aggiungi questo codice allo snippet di codice precedente subito dopo il commento
TODO: Add code to process the response.
:
// 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])
}
Ora la funzione di post-elaborazione estrae i valori previsti dalla risposta e visualizza il risultato nell'interfaccia utente.
Esegui
- Fai clic su
"Run', quindi attendi che Xcode avvii l'app nel simulatore.
- Inserisci un numero nella casella di testo, quindi fai clic su Inferenza.
Ora nell'interfaccia utente viene visualizzato il valore previsto.
8. Collega l'app per iOS a TensorFlow Serving tramite gRPC
Oltre a REST, TensorFlow Serving supporta anche gRPC.
gRPC è un framework RPC (Open Procedure Call) moderno e open source eseguibile in qualsiasi ambiente. Può connettere i servizi in modo efficiente all'interno dei diversi data center e fornire un supporto collegabile per bilanciamento del carico, tracciamento, controllo di integrità e autenticazione. È stato osservato che gRPC ha un rendimento migliore rispetto a REST nella pratica.
Inviare richieste e ricevere risposte con gRPC
Sono disponibili quattro semplici passaggi:
- (Facoltativo) Genera il codice stub client gRPC.
- Crea la richiesta gRPC.
- Invia la richiesta gRPC a TensorFlow Serving.
- Estrai il risultato previsto dalla risposta gRPC e visualizza l'interfaccia utente.
Completa questi passaggi nel file iOS/regression/ViewController.swift
.
Facoltativo: genera il codice stub client gRPC
Per utilizzare gRPC con TensorFlow Serving, devi seguire il flusso di lavoro gRPC. Per saperne di più, consulta la documentazione di gRPC.
TensorFlow Serving e TensorFlow definiscono i file .proto
per tuo conto. In data TensorFlow e TensorFlow Serving 2.8, questi file .proto
sono quelli necessari:
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
Per generare il codice stub client gRPC:
- Nel terminale, passa alla cartella
starter/src/proto/
, quindi genera lo stub:
bash generate_grpc_stub_swift.sh
.swift
file vengono generati nella cartella starter/src/proto/generated/import
.
- Se non sono ancora copiati nel progetto, trascina tutti i file
.swift
generati nel tuo progetto in Xcode.
Crea la richiesta gRPC
Come per la richiesta REST, puoi creare la richiesta gRPC nel ramo gRPC.
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
}
else {
print("Using gRPC")
// TODO: add code to send a gRPC request to TF Serving
}
- Per creare la richiesta gRPC, aggiungi questo codice al ramo gRPC:
//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)))
Invia la richiesta gRPC a TensorFlow Serving
- Aggiungi questo codice al ramo gRPC immediatamente dopo il codice nello snippet di codice precedente:
// Send the gRPC request.
let call = stub.predict(request, callOptions: callOptions)
Elabora la risposta gRPC da TensorFlow Serving
- Aggiungere questo codice subito dopo il codice nello snippet di codice precedente:
// 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)")
}
Ora la funzione di post-elaborazione estrae i valori previsti dalla risposta e visualizza il risultato nell'interfaccia utente.
Esegui
- Fai clic su
"Run' nel menu di navigazione, quindi attendi che Xcode avvii l'app nel simulatore.
- Inserisci un numero nella casella di testo, quindi fai clic su Inferenza.
Ora nell'interfaccia utente viene visualizzato il valore previsto.
9. Complimenti
Hai utilizzato TensorFlow Serving per aggiungere funzionalità di regressione alla tua app.