Creare un'app per iOS per prevedere i valori

Creare un'app per iOS per prevedere i valori

Informazioni su questo codelab

subjectUltimo aggiornamento: apr 8, 2022
account_circleScritto da: Wei Wei

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

2. Configura

Per scaricare il codice per questo codelab:

  1. Accedi al repository GitHub per questo codelab.
  2. Fai clic su Codice > Scarica zip per scaricare tutto il codice di questo codelab.

a72f2bb4caa9a96.png

  1. 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

  1. Cambia il target del dispositivo in qualsiasi iPhone, ad esempio iPhone 13.

a57198a4f21f970.png

  1. Fai clic su cacc15c5638260ed.png "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.

d2976072474ce0b1.png

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

  1. Apri questo link nel tuo browser.

Colab carica il blocco note Python.

  1. Nel blocco note Python, importa le librerie TensorFlow e NumPy, quindi crea sei coppie di dati di addestramento con xs come input e ys 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.

56d05252cfc9df9d.png

  1. Utilizza l'API Keras per creare una semplice rete neurale a due livelli per prevedere il valore di y in base all'input di x, 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.

  1. 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}
  1. Comprimi il Salvato modello esportato in un unico file regression.zip:
!zip -r regression.zip ./regression
  1. Fai clic su Runtime > Run all (Esegui tutto) nel menu di navigazione per eseguire il blocco note, quindi attendi il termine dell'esecuzione.
  2. Fai clic su c55600d42359f901.png File e scarica il file regression.zip.

bceda15d86571583.png

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:

7faeb4f03af39646.png

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 cartella regression 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:

  1. Crea la richiesta REST.
  2. Invia la richiesta REST a TensorFlow Serving.
  3. 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

  1. 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.

  1. 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

  1. Fai clic su cacc15c5638260ed.png "Run', quindi attendi che Xcode avvii l'app nel simulatore.
  2. Inserisci un numero nella casella di testo, quindi fai clic su Inferenza.

Ora nell'interfaccia utente viene visualizzato il valore previsto.

df9bcb9aa21bb30e.png

8. Collega l'app per iOS a TensorFlow Serving tramite gRPC

Oltre a REST, TensorFlow Serving supporta anche gRPC.

b6f4449c2c850b0e.png

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:

  1. (Facoltativo) Genera il codice stub client gRPC.
  2. Crea la richiesta gRPC.
  3. Invia la richiesta gRPC a TensorFlow Serving.
  4. 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.

a9d0e5cb543467b4.png

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:

  1. 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.

  1. Se non sono ancora copiati nel progetto, trascina tutti i file .swift generati nel tuo progetto in Xcode.

9e65705cf6be7aac.png

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

  1. Fai clic su cacc15c5638260ed.png "Run' nel menu di navigazione, quindi attendi che Xcode avvii l'app nel simulatore.
  2. 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.

Scopri di più