1. Prima di iniziare
I motori per i consigli, noti anche come motori per suggerimenti, sono un'applicazione molto importante del machine learning, che si tratti di consigliare film o ristoranti all'evidenziazione di video di intrattenimento. I motori per suggerimenti ti aiutano a far emergere contenuti interessanti da un ampio pool di candidati per i tuoi utenti. Ad esempio, il Google Play Store offre milioni di app da installare, mentre YouTube offre miliardi di video da guardare. Ogni giorno vengono aggiunti sempre più video e app.
In questo codelab, imparerai come creare un motore per suggerimenti fullstack utilizzando:
- Motori per suggerimenti TensorFlow per addestrare un modello di recupero e ranking per i suggerimenti relativi ai film
- TensorFlow Serving per fornire i modelli
- Flutter per creare un'app multipiattaforma per mostrare i film consigliati
Prerequisiti
- Conoscenza di base dello sviluppo Flutter con Dart
- Conoscenza di base del machine learning con TensorFlow, ad esempio addestramento e deployment
- Familiarità di base con i sistemi di suggerimenti
- Conoscenza di base di Python, terminali e Docker
Obiettivi didattici
- Come addestrare i modelli di recupero e ranking utilizzando i motori per suggerimenti di TensorFlow
- Come gestire i modelli di suggerimenti addestrati utilizzando TensorFlow Serving
- Come creare un'app Flutter multipiattaforma per mostrare gli articoli consigliati
Che cosa ti serve
- SDK Flutter
- Configurazione di Flutter per Android e iOS
- Configurazione di Flutter su computer
- Configurazione di Flutter sul web
- Configurazione di Visual Studio Code (VS Code) per Flutter e Dart
- Docker
- Picchi
- Python 3.7 o versioni successive
- Accesso a Colab
2. Configura l'ambiente di sviluppo di Flutter
Per lo sviluppo di Flutter, hai bisogno di due parti di software per completare questo codelab: l'SDK Flutter e un editor.
Puoi eseguire il frontend del codelab utilizzando uno di questi dispositivi:
- Il simulatore iOS (richiede l'installazione degli strumenti Xcode).
- L'emulatore Android (richiede la configurazione in Android Studio).
- Un browser (per il debug è richiesto Chrome).
- Come applicazione desktop Windows, Linux o macOS. Devi svilupparle sulla piattaforma in cui prevedi di eseguire il deployment. Quindi, se vuoi sviluppare un'app desktop per Windows, devi sviluppare su Windows per accedere alla catena di build appropriata. Alcuni requisiti specifici del sistema operativo sono descritti in dettaglio all'indirizzo docs.flutter.dev/desktop.
Per il backend, avrai bisogno di:
- Un computer Linux o un Mac basato su Intel.
3. Configurazione
Per scaricare il codice per questo codelab:
- Vai al repository GitHub per questo codelab.
- Fai clic su Codice > Scarica il file ZIP per scaricare tutto il codice per questo codelab.
- Decomprimi il file ZIP scaricato per aprire una cartella principale
codelabs-main
con tutte le risorse di cui hai bisogno.
Per questo codelab, ti servono solo i file nella sottodirectory tfrs-flutter/
del repository, che contiene più cartelle:
- Le cartelle da
step0
astep5
contengono il codice iniziale che creerai per ogni passaggio in questo codelab. - La cartella
finished
contiene il codice completato per l'app di esempio completata. - Ogni cartella contiene una sottocartella
backend
, che include il codice backend del motore per suggerimenti, e una sottocartellafrontend
, che include il codice frontend di Flutter
4. Scarica le dipendenze per il progetto
Backend
Utilizzeremo Flask per creare il backend. Apri il terminale ed esegui questo comando:
pip install Flask flask-cors requests numpy
Frontend
- In VS Code, fai clic su File > Apri cartella, quindi seleziona la cartella
step0
dal codice sorgente scaricato in precedenza. - Apri il file
step0/frontend/lib/main.dart
. Se viene visualizzata una finestra di dialogo VS Code che ti chiede di scaricare i pacchetti richiesti per l'app iniziale, fai clic su Ottieni pacchetti. - Se non vedi questa finestra di dialogo, apri il terminale ed esegui il comando
flutter pub get
nella cartellastep0/frontend
.
5. Passaggio 0: esegui l'app iniziale
- Apri il file
step0/frontend/lib/main.dart
in VS Code, assicurati che l'emulatore Android o il simulatore iOS sia configurato correttamente e appaia nella barra di stato.
Ad esempio, ecco cosa vedi quando usi Pixel 5 con l'emulatore Android:
Ecco cosa vedi quando usi iPhone 13 con il Simulatore di iOS:
- Fai clic su Avvia debug.
Esegui ed esplora l'app
L'app dovrebbe avviarsi sull'emulatore Android o sul simulatore iOS. L'interfaccia utente è piuttosto semplice. C'è un campo di testo che consente all'utente di digitare il testo come ID utente. L'app Flutter invierà la richiesta di query al backend, che esegue due modelli di consigli e restituisce un elenco classificato di consigli sui film. Il frontend mostrerà il risultato nella UI dopo aver ricevuto la risposta.
Se fai clic su Consiglia ora, non succede nulla perché l'app non può ancora comunicare con il backend.
6. Passaggio 1: crea i modelli di recupero e ranking per il motore per suggerimenti
I motori per suggerimenti reali sono spesso composti da più fasi:
- La fase di recupero prevede la selezione di un insieme iniziale di centinaia di candidati tra tutti i possibili candidati. L'obiettivo principale di questo modello è escludere in modo efficiente tutti i candidati a cui l'utente non è interessato. Poiché il modello di recupero potrebbe avere a che fare con milioni di candidati, deve essere efficiente dal punto di vista computazionale.
- La fase di ranking prende gli output del modello di recupero e li perfeziona per selezionare il maggior numero possibile di suggerimenti. Il suo compito è restringere l'insieme di elementi che l'utente potrebbe essere interessato a una lista di candidati probabili nell'ordine di centinaia.
- La fase di post-ranking contribuisce a garantire diversità, aggiornamento ed equità e riorganizza gli elementi candidati in una serie di consigli utili dell'ordine di decine.
Per questo codelab, addestrerai un modello di recupero e un modello di ranking utilizzando il popolare set di dati MovieLens. Puoi aprire il codice di addestramento di seguito tramite Colab e seguire le istruzioni:
7. Passaggio 2: crea il backend del motore per suggerimenti
Ora che hai addestrato i modelli di recupero e ranking, puoi eseguirne il deployment e creare un backend.
Avvia la pubblicazione di TensorFlow
Poiché devi utilizzare entrambi i modelli di recupero e ranking per generare l'elenco di film consigliati, esegui il deployment di entrambi contemporaneamente utilizzando TensorFlow Serving.
- Nel terminale, vai alla cartella
step2/backend
sul tuo computer e avvia TensorFlow Serving con Docker:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/:/models/" tensorflow/serving --model_config_file=/models/models.config
Docker scarica automaticamente prima l'immagine di TensorFlow Serving, che richiede un minuto. Successivamente, verrà avviata la pubblicazione di TensorFlow. Il log dovrebbe essere simile al seguente snippet di codice:
2022-04-24 09:32:06.461702: I tensorflow_serving/model_servers/server_core.cc:465] Adding/updating models. 2022-04-24 09:32:06.461843: I tensorflow_serving/model_servers/server_core.cc:591] (Re-)adding model: retrieval 2022-04-24 09:32:06.461907: I tensorflow_serving/model_servers/server_core.cc:591] (Re-)adding model: ranking 2022-04-24 09:32:06.576920: I tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: retrieval version: 123} 2022-04-24 09:32:06.576993: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: retrieval version: 123} 2022-04-24 09:32:06.577011: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: retrieval version: 123} 2022-04-24 09:32:06.577848: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/retrieval/exported-retrieval/123 2022-04-24 09:32:06.583809: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve } 2022-04-24 09:32:06.583879: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/retrieval/exported-retrieval/123 2022-04-24 09:32:06.584970: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2022-04-24 09:32:06.629900: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle. 2022-04-24 09:32:06.634662: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2800000000 Hz 2022-04-24 09:32:06.672534: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/retrieval/exported-retrieval/123 2022-04-24 09:32:06.673629: I tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: ranking version: 123} 2022-04-24 09:32:06.673765: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: ranking version: 123} 2022-04-24 09:32:06.673786: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: ranking version: 123} 2022-04-24 09:32:06.674731: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/ranking/exported-ranking/123 2022-04-24 09:32:06.683557: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve } 2022-04-24 09:32:06.683601: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/ranking/exported-ranking/123 2022-04-24 09:32:06.688665: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 110815 microseconds. 2022-04-24 09:32:06.690019: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/retrieval/exported-retrieval/123/assets.extra/tf_serving_warmup_requests 2022-04-24 09:32:06.693025: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: retrieval version: 123} 2022-04-24 09:32:06.702594: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle. 2022-04-24 09:32:06.745361: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/ranking/exported-ranking/123 2022-04-24 09:32:06.772363: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 97633 microseconds. 2022-04-24 09:32:06.774853: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/ranking/exported-ranking/123/assets.extra/tf_serving_warmup_requests 2022-04-24 09:32:06.777706: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: ranking version: 123} 2022-04-24 09:32:06.778969: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models 2022-04-24 09:32:06.779030: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled 2022-04-24 09:32:06.784217: 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-04-24 09:32:06.785748: 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 ...
Crea un nuovo endpoint
Poiché TensorFlow Serving non supporta il "chaining" è necessario creare un nuovo servizio che colleghi i modelli di recupero e ranking.
- Aggiungi questo codice alla funzione
get_recommendations()
nel filestep2/backend/recommendations.py
:
user_id = request.get_json()["user_id"] retrieval_request = json.dumps({"instances": [user_id]}) retrieval_response = requests.post(RETRIEVAL_URL, data=retrieval_request) movie_candidates = retrieval_response.json()["predictions"][0]["output_2"] ranking_queries = [ {"user_id": u, "movie_title": m} for (u, m) in zip([user_id] * NUM_OF_CANDIDATES, movie_candidates) ] ranking_request = json.dumps({"instances": ranking_queries}) ranking_response = requests.post(RANKING_URL, data=ranking_request) movies_scores = list(np.squeeze(ranking_response.json()["predictions"])) ranked_movies = [ m[1] for m in sorted(list(zip(movies_scores, movie_candidates)), reverse=True) ] return make_response(jsonify({"movies": ranked_movies}), 200)
Avvia il servizio Flask
Ora puoi avviare il servizio Flask.
- Nel terminale, vai alla cartella
step2/backend/
ed esegui questo comando:
FLASK_APP=recommender.py FLASK_ENV=development flask run
Flask supporterà un nuovo endpoint alle ore http://localhost:5000/recommend
. Il log dovrebbe essere visualizzato come segue:
* Serving Flask app 'recommender.py' (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 705-382-264 127.0.0.1 - - [25/Apr/2022 19:44:47] "POST /recommend HTTP/1.1" 200 -
Puoi inviare una richiesta di esempio all'endpoint per assicurarti che funzioni come previsto:
curl -X POST -H "Content-Type: application/json" -d '{"user_id":"42"}' http://localhost:5000/recommend
L'endpoint restituirà un elenco di film consigliati per l'utente 42
:
{ "movies": [ "While You Were Sleeping (1995)", "Preacher's Wife, The (1996)", "Michael (1996)", "Lion King, The (1994)", "Father of the Bride Part II (1995)", "Sleepless in Seattle (1993)", "101 Dalmatians (1996)", "Bridges of Madison County, The (1995)", "Rudy (1993)", "Jack (1996)" ] }
È tutto. Hai creato un backend per consigliare film in base a un ID utente.
8. Passaggio 3: crea l'app Flutter per Android e iOS
Il backend è pronto. Puoi iniziare a inviare richieste per ottenere consigli sui film dall'app Flutter.
L'app frontend è piuttosto semplice. Ha solo un campo di testo che accetta l'ID utente e invia la richiesta (nella funzione recommend()
) al backend che hai appena creato. Dopo aver ricevuto la risposta, l'interfaccia utente dell'app mostra i film consigliati in un ListView.
- Aggiungi questo codice alla funzione
recommend()
nel filestep3/frontend/lib/main.dart
:
final response = await http.post( Uri.parse('http://' + _server + ':5000/recommend'), headers: <String, String>{ 'Content-Type': 'application/json', }, body: jsonEncode(<String, String>{ 'user_id': _userIDController.text, }), );
Quando l'app riceve la risposta dal backend, aggiorni la UI in modo da visualizzare l'elenco di film consigliati per l'utente specificato.
- Aggiungi questo codice proprio sotto il codice riportato sopra:
if (response.statusCode == 200) { return List<String>.from(jsonDecode(response.body)['movies']); } else { throw Exception('Error response'); }
Eseguilo
- Fai clic su Avvia debug, quindi attendi il caricamento dell'app.
- Inserisci un ID utente (ad es. 42) e seleziona Consiglia.
9. Passaggio 4: esegui l'app Flutter sulle piattaforme desktop
Oltre ad Android e iOS, Flutter supporta anche piattaforme desktop come Linux, Mac e Windows.
Linux
- Assicurati che il dispositivo di destinazione sia impostato su nella barra di stato di VSCode.
- Fai clic su Avvia debug, quindi attendi il caricamento dell'app.
- Inserisci un ID utente (ad es. 42) e seleziona Consiglia.
Mac
- Per Mac, devi configurare i diritti appropriati poiché l'app invierà richieste HTTP al backend. Per maggiori dettagli, consulta Diritti e sandbox dell'app.
Aggiungi questo codice rispettivamente a step4/frontend/macOS/Runner/DebugProfile.entitlements
e step4/frontend/macOS/Runner/Release.entitlements
:
<key>com.apple.security.network.client</key>
<true/>
- Assicurati che il dispositivo di destinazione sia impostato su nella barra di stato di VSCode.
- Fai clic su Avvia debug, quindi attendi il caricamento dell'app.
- Inserisci un ID utente (ad es. 42) e seleziona Consiglia.
Windows
- Assicurati che il dispositivo di destinazione sia impostato su nella barra di stato di VSCode.
- Fai clic su Avvia debug, quindi attendi il caricamento dell'app.
- Inserisci un ID utente (ad es. 42) e seleziona Consiglia.
10. Passaggio 5: esegui l'app Flutter sulla piattaforma web
Un'altra cosa che puoi fare è aggiungere il supporto web all'app Flutter. Per impostazione predefinita, la piattaforma web è abilitata automaticamente per le app Flutter, quindi non devi fare altro che avviarla.
- Assicurati che il dispositivo di destinazione sia impostato su nella barra di stato di VSCode.
- Fai clic su Avvia debug, quindi attendi il caricamento dell'app nel browser Chrome.
- Inserisci un ID utente (ad es. 42) e seleziona Consiglia.
11. Complimenti
Hai creato un'app full stack per consigliare film ai tuoi utenti.
Anche se l'app consiglia solo film, hai appreso il flusso di lavoro generale per creare un potente motore per suggerimenti e padroneggiando la capacità di utilizzare i consigli in un'app Flutter. Puoi applicare facilmente ciò che hai imparato ad altri scenari (ad es. e-commerce, cibo e brevi video).