1. Hinweis
Empfehlungssysteme, auch Recommender genannt, sind eine sehr wichtige Anwendung des maschinellen Lernens, von der Empfehlung von Filmen oder Restaurants bis hin zur Hervorhebung unterhaltsamer Videos. Recommender helfen Ihnen, Ihren Nutzern überzeugende Inhalte aus einer großen Anzahl von Kandidaten zu präsentieren. So bietet beispielsweise der Google Play Store Millionen von Apps, die Sie installieren können, und auf YouTube finden Sie Milliarden von Videos. Und jeden Tag kommen neue Apps und Videos hinzu.
In diesem Codelab erfahren Sie, wie Sie einen Fullstack-Recommender erstellen mit:
- TensorFlow Recommender zum Trainieren eines Abruf- und Rankingmodells für Filmempfehlungen
- TensorFlow Serving zum Bereitstellen der Modelle
- Flutter zur Erstellung einer plattformübergreifenden App mit empfohlenen Filmen
Vorbereitung
- Grundkenntnisse der Flutter-Entwicklung mit Dart
- Grundkenntnisse des maschinellen Lernens mit TensorFlow, z. B. Training oder Bereitstellung
- Grundkenntnisse zu Empfehlungssystemen
- Grundkenntnisse in Python, Terminals und Docker
Lerninhalte
- Abruf- und Rankingmodelle mit TensorFlow Recommender trainieren
- Trainierte Empfehlungsmodelle mithilfe von TensorFlow Serving bereitstellen
- So erstellen Sie eine plattformübergreifende Flutter-App zur Anzeige der empfohlenen Artikel
Voraussetzungen
- Flutter-SDK
- Flutter unter Android und iOS einrichten
- Flutter-Einrichtung auf Computer
- Web-Einrichtung für Flutter
- Visual Studio Code (VS Code) für Flutter und Dart einrichten
- Docker
- Bash
- Python 3.7 und höher
- Zugriff auf Colab
2. Flutter-Entwicklungsumgebung einrichten
Für die Flutter-Entwicklung benötigen Sie zwei Softwareprogramme für dieses Codelab: das Flutter SDK und einen Editor.
Sie können das Front-End des Codelabs mit einem der folgenden Geräte ausführen:
- Den iOS-Simulator (erfordert die Installation von Xcode-Tools).
- Android-Emulator (Einrichtung in Android Studio erforderlich)
- Ein Browser (zur Fehlerbehebung wird Chrome benötigt)
- Als Windows-, Linux- oder macOS-Desktopanwendung Die Entwicklung muss auf der Plattform erfolgen, auf der Sie die Bereitstellung planen. Wenn Sie also eine Windows-Desktop-App entwickeln möchten, müssen Sie die Entwicklung unter Windows ausführen, damit Sie auf die entsprechende Build-Kette zugreifen können. Es gibt betriebssystemspezifische Anforderungen, die unter docs.flutter.dev/desktop ausführlich beschrieben werden.
Für das Back-End benötigen Sie Folgendes:
- Einen Linux-Computer oder einen Intel-basierten Mac.
3. Einrichten
So laden Sie den Code für dieses Codelab herunter:
- Rufen Sie für dieses Codelab das GitHub-Repository auf.
- Klicken Sie auf Code > Lade eine ZIP-Datei herunter, um den gesamten Code für dieses Codelab herunterzuladen.
- Entpacke die heruntergeladene ZIP-Datei, um einen
codelabs-main
-Stammordner mit allen benötigten Ressourcen zu entpacken.
Für dieses Codelab benötigen Sie nur die Dateien im Unterverzeichnis tfrs-flutter/
im Repository, das mehrere Ordner enthält:
- Die Ordner
step0
bisstep5
enthalten den Startcode, auf dem Sie für jeden Schritt in diesem Codelab aufbauen. - Der Ordner
finished
enthält den fertigen Code für die fertige Beispiel-App. - Jeder Ordner enthält einen
backend
-Unterordner mit dem Backend-Code des Empfehlungssystems und einenfrontend
-Unterordner mit dem Flutter-Frontend-Code
4. Abhängigkeiten für das Projekt herunterladen
Backend
Das Back-End wird mit Flask erstellt. Öffnen Sie Ihr Terminal und führen Sie folgenden Befehl aus:
pip install Flask flask-cors requests numpy
Frontend
- Klicken Sie in VS Code auf File > Öffnen Sie den Ordner und wählen Sie dann den Ordner
step0
aus dem Quellcode aus, den Sie zuvor heruntergeladen haben. - Datei „
step0/frontend/lib/main.dart
“ öffnen. Wenn ein VS Code-Dialogfeld angezeigt wird, in dem Sie aufgefordert werden, die erforderlichen Pakete für die Start-App herunterzuladen, klicken Sie auf Getpackages (Pakete abrufen). - Wenn dieses Dialogfeld nicht angezeigt wird, öffnen Sie Ihr Terminal und führen Sie den Befehl
flutter pub get
im Ordnerstep0/frontend
aus.
5. Schritt 0: Start-App ausführen
- Öffnen Sie die Datei „
step0/frontend/lib/main.dart
“ in VS Code und prüfen Sie, ob der Android-Emulator oder iOS-Simulator richtig eingerichtet ist und in der Statusleiste angezeigt wird.
Wenn Sie Pixel 5 mit dem Android-Emulator verwenden, sehen Sie beispielsweise Folgendes:
Wenn Sie das iPhone 13 mit dem iOS-Simulator verwenden, sehen Sie Folgendes:
- Klicken Sie auf Debugging starten.
App ausführen und kennenlernen
Die App sollte im Android-Emulator oder iOS-Simulator gestartet werden. Die Benutzeroberfläche ist ziemlich einfach gehalten. Es gibt ein Textfeld, in das der Nutzer den Text als User-ID eingeben kann. Die Flutter-App sendet die Anfrage an das Back-End, das zwei Empfehlungsmodelle ausführt und eine Rangliste mit Filmempfehlungen zurückgibt. Das Frontend zeigt das Ergebnis nach Empfang der Antwort in der UI an.
Wenn Sie jetzt auf Empfehlen klicken, passiert nichts, da die App noch nicht mit dem Back-End kommunizieren kann.
6. Schritt 1: Abruf- und Rankingmodelle für das Empfehlungssystem erstellen
Reale Empfehlungssysteme setzen sich oft aus mehreren Phasen zusammen:
- In der Abrufphase wird eine erste Reihe von Hunderten von Kandidaten aus allen möglichen Kandidaten ausgewählt. Das Hauptziel dieses Modells besteht darin, alle Kandidaten herauszufiltern, an denen die Nutzenden nicht interessiert sind. Da das Abrufmodell möglicherweise Millionen von Kandidaten verarbeitet, muss es recheneffizient sein.
- In der Ranking-Phase werden die Ergebnisse des Abrufmodells optimiert, um die bestmöglichen Empfehlungen auszuwählen. Die Aufgabe besteht darin, die Gruppe von Elementen, die für die Nutzenden interessant sein könnten, auf eine Auswahlliste wahrscheinlicher Kandidaten (in der Größenordnung von Hunderten) einzugrenzen.
- Die Phase nach dem Ranking trägt dazu bei, für Vielfalt, Aktualität und Fairness zu sorgen und die Kandidaten in eine Reihe nützlicher Empfehlungen in der Reihenfolge Dutzende von Kandidaten neu zu organisieren.
In diesem Codelab trainieren Sie mithilfe des beliebten MovieLens-Datasets ein Abrufmodell und ein Ranking-Modell. Sie können den Trainingscode unten über Colab öffnen und der Anleitung folgen:
7. Schritt 2: Back-End des Empfehlungssystems erstellen
Nachdem Sie die Abruf- und Rankingmodelle trainiert haben, können Sie sie bereitstellen und ein Back-End erstellen.
TensorFlow Serving starten
Da Sie sowohl das Abruf- als auch das Ranking-Modell verwenden müssen, um die Liste der empfohlenen Filme zu generieren, stellen Sie beide gleichzeitig mit TensorFlow Serving bereit.
- Rufen Sie im Terminal den Ordner
step2/backend
auf Ihrem Computer auf und starten Sie TensorFlow Serving mit Docker:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/:/models/" tensorflow/serving --model_config_file=/models/models.config
Docker lädt automatisch zuerst das TensorFlow-Bereitstellungs-Image herunter, was eine Minute dauert. Danach sollte TensorFlow Serving gestartet werden. Das Protokoll sollte wie dieses Code-Snippet aussehen:
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 ...
Neuen Endpunkt erstellen
Da TensorFlow Serving keine Verkettung unterstützt sequenzielle Modelle verwenden, müssen Sie einen neuen Dienst erstellen, der die Abruf- und Rankingmodelle miteinander verbindet.
- Fügen Sie der Funktion
get_recommendations()
in der Dateistep2/backend/recommendations.py
diesen Code hinzu:
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)
Flask-Dienst starten
Jetzt können Sie den Flask-Dienst starten.
- Rufen Sie in Ihrem Terminal den Ordner
step2/backend/
auf und führen Sie folgenden Befehl aus:
FLASK_APP=recommender.py FLASK_ENV=development flask run
Flask richtet einen neuen Endpunkt um http://localhost:5000/recommend
ein. Sie sollten das Protokoll so sehen:
* 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 -
Sie können eine Beispielanfrage an den Endpunkt senden, um sicherzustellen, dass er wie erwartet funktioniert:
curl -X POST -H "Content-Type: application/json" -d '{"user_id":"42"}' http://localhost:5000/recommend
Der Endpunkt gibt eine Liste mit empfohlenen Filmen für den Nutzer 42
zurück:
{ "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)" ] }
Fertig! Sie haben erfolgreich ein Backend erstellt, um Filme basierend auf einer Nutzer-ID zu empfehlen.
8. Schritt 3: Flutter-App für Android und iOS erstellen
Das Back-End ist bereit. Sie können Anfragen an ihn senden, um Filmempfehlungen aus der Flutter App abzufragen.
Die Front-End-Anwendung ist relativ einfach. Es enthält nur ein TextField-Element, das die Nutzer-ID aufnimmt und die Anfrage (in der Funktion recommend()
) an das soeben erstellte Back-End sendet. Nach Erhalt der Antwort zeigt die App-Benutzeroberfläche die empfohlenen Filme in einer Listenansicht an.
- Fügen Sie der Funktion
recommend()
in der Dateistep3/frontend/lib/main.dart
diesen Code hinzu:
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, }), );
Sobald die Anwendung die Antwort vom Back-End erhält, aktualisieren Sie die Benutzeroberfläche, um die Liste der empfohlenen Filme für den angegebenen Nutzer anzuzeigen.
- Fügen Sie diesen Code direkt unter dem obigen Code ein:
if (response.statusCode == 200) { return List<String>.from(jsonDecode(response.body)['movies']); } else { throw Exception('Error response'); }
Ausführen
- Klicken Sie auf Debugging starten und warten Sie, bis die Anwendung geladen ist.
- Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.
9. Schritt 4: Flutter-App auf den Desktop-Plattformen ausführen
Neben Android und iOS unterstützt Flutter auch Desktop-Plattformen wie Linux, Mac und Windows.
Linux
- Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf gesetzt ist.
- Klicken Sie auf Debugging starten und warten Sie, bis die Anwendung geladen ist.
- Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.
Mac
- Auf einem Mac musst du entsprechende Berechtigungen einrichten, da die App HTTP-Anfragen an das Backend sendet. Weitere Informationen findest du unter Berechtigungen und App Sandbox.
Fügen Sie diesen Code step4/frontend/macOS/Runner/DebugProfile.entitlements
bzw. step4/frontend/macOS/Runner/Release.entitlements
hinzu:
<key>com.apple.security.network.client</key>
<true/>
- Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf gesetzt ist.
- Klicken Sie auf Debugging starten und warten Sie, bis die Anwendung geladen ist.
- Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.
Windows
- Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf gesetzt ist.
- Klicken Sie auf Debugging starten und warten Sie, bis die Anwendung geladen ist.
- Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.
10. Schritt 5: Flutter-App auf der Webplattform ausführen
Eine weitere Möglichkeit besteht darin, die Flutter-App mit Webunterstützung zu ergänzen. Standardmäßig ist die Webplattform automatisch für Flutter-Apps aktiviert, Sie müssen sie also nur starten.
- Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf gesetzt ist.
- Klicken Sie auf Debugging starten und warten Sie, bis die App im Chrome-Browser geladen wird.
- Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.
11. Glückwunsch
Sie haben eine Full-Stack-App entwickelt, mit der Sie Ihren Nutzern Filme empfehlen können.
Obwohl die App nur Filme empfiehlt, haben Sie den gesamten Workflow zum Erstellen eines leistungsstarken Empfehlungssystems kennengelernt und die Fähigkeit gemeistert, die Empfehlungen in einer Flutter-App umzusetzen. Das Gelernte lässt sich einfach auf andere Szenarien anwenden (z.B. E-Commerce, Essen und kurze Videos).