Full-Stack-Empfehlungssystem für Filme entwickeln

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

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:

  1. Rufen Sie für dieses Codelab das GitHub-Repository auf.
  2. Klicken Sie auf Code > Lade eine ZIP-Datei herunter, um den gesamten Code für dieses Codelab herunterzuladen.

2cd45599f51fb8a2.png

  1. 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 bis step5 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 einen frontend-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

  1. 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.
  2. 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).
  3. Wenn dieses Dialogfeld nicht angezeigt wird, öffnen Sie Ihr Terminal und führen Sie den Befehl flutter pub get im Ordner step0/frontend aus.

7ada07c300f166a6.png

5. Schritt 0: Start-App ausführen

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

9767649231898791.png

Wenn Sie das iPhone 13 mit dem iOS-Simulator verwenden, sehen Sie Folgendes:

95529e3a682268b2.png

  1. Klicken Sie auf a19a0c68bc4046e6.png 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 Benutzeroberfläche an.

d21427db9587560f.png 73e8272a5ce8dfbc.png

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:

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

70dfc0d7e989164f.png

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 nun 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 Datei step2/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 Datei step3/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

  1. Klicken Sie auf a19a0c68bc4046e6.png Debugging starten und warten Sie, bis die Anwendung geladen ist.
  2. Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.

badb59d8b96959ae.png a0d2d4020aebfb0a.png

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

  1. Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf 86cba523de82b4f9.png gesetzt ist.
  2. Klicken Sie auf a19a0c68bc4046e6.png Debugging starten und warten Sie, bis die Anwendung geladen ist.
  3. Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.

2665514231033f1.png

Mac

  1. 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/>
  1. Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf eb4b0b5563824138.png festgelegt ist.
  2. Klicken Sie auf a19a0c68bc4046e6.png Debugging starten und warten Sie, bis die Anwendung geladen ist.
  3. Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.

860d523a7ac537e0.png

Windows

  1. Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf 9587be1bb375bc0f.png festgelegt ist.
  2. Klicken Sie auf a19a0c68bc4046e6.png Debugging starten und warten Sie, bis die Anwendung geladen ist.
  3. Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.

7d77c1e52a5927fc.png

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.

  1. Achten Sie darauf, dass das Zielgerät in der Statusleiste von VSCode auf 71db93efa928d15d.png festgelegt ist.
  2. Klicken Sie auf a19a0c68bc4046e6.png Debugging starten und warten Sie, bis die App im Chrome-Browser geladen wird.
  3. Geben Sie eine Nutzer-ID ein (z.B. 42) und wählen Sie dann Empfehlen aus.

9376e1e432c18bef.png

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

Weitere Informationen