Full-Stack-Empfehlungssystem für Filme entwickeln

1. Hinweis

Empfehlungssysteme, auch Recommender genannt, sind eine sehr wichtige Anwendung von maschinellem Lernen. Sie können beispielsweise Filme oder Restaurants empfehlen oder unterhaltsame Videos hervorheben. Mit Empfehlungen können Sie Ihren Nutzern ansprechende Inhalte aus einem großen Pool von Kandidaten präsentieren. Der Google Play Store bietet beispielsweise Millionen von Apps, die installiert werden können, während YouTube Milliarden von Videos bereitstellt. Jeden Tag kommen weitere Apps und Videos hinzu.

In diesem Codelab erfahren Sie, wie Sie ein Full-Stack-Empfehlungssystem mit den folgenden Tools erstellen:

  • TensorFlow Recommenders zum Trainieren eines Retrieval- und eines Ranking-Modells für Filmempfehlungen
  • TensorFlow Serving zum Bereitstellen der Modelle
  • Mit Flutter eine plattformübergreifende App zum Anzeigen empfohlener Filme erstellen

Vorbereitung

  • Grundkenntnisse der Flutter-Entwicklung mit Dart
  • Grundkenntnisse im Bereich maschinelles Lernen mit TensorFlow, z. B. Training im Vergleich zur Bereitstellung
  • Grundkenntnisse zu Empfehlungssystemen
  • Grundlegende Kenntnisse von Python, Terminals und Docker

Lerninhalte

  • Abruf- und Ranking-Modelle mit TensorFlow Recommenders trainieren
  • Bereitstellen der trainierten Empfehlungsmodelle mit TensorFlow Serving
  • Plattformübergreifende Flutter-App zum Anzeigen der empfohlenen Artikel erstellen

Voraussetzungen

2. Flutter-Entwicklungsumgebung einrichten

Für die Flutter-Entwicklung benötigen Sie zwei Softwarekomponenten, um dieses Codelab durchzuarbeiten: das Flutter SDK und einen Editor.

Sie können das Frontend des Codelabs auf einem der folgenden Geräte ausführen:

  • Der iOS-Simulator (erfordert die Installation von Xcode-Tools).
  • Android Emulator (Einrichtung in Android Studio erforderlich)
  • Ein Browser (für das Debugging ist Chrome erforderlich).
  • Als Windows-, Linux- oder macOS-Desktopanwendung. Sie müssen auf der Plattform entwickeln, auf der Sie die Bereitstellung planen. Wenn Sie also eine Windows-Desktop-App entwickeln möchten, müssen Sie unter Windows entwickeln, um auf die entsprechende Build-Kette zuzugreifen. Es gibt betriebssystemspezifische Anforderungen, die auf docs.flutter.dev/desktop ausführlich beschrieben werden.

Für das Backend benötigen Sie Folgendes:

  • Ein Linux-Computer oder ein Intel-basierter Mac

3. Einrichten

So laden Sie den Code für dieses Codelab herunter:

  1. Rufen Sie das GitHub-Repository für dieses Codelab auf.
  2. Klicken Sie auf Code > Download zip, um den gesamten Code für dieses Codelab herunterzuladen.

2cd45599f51fb8a2.png

  1. Entpacken Sie 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 vollständigen Code der fertigen Beispiel-App.
  • Jeder Ordner enthält einen backend-Unterordner mit dem Backend-Code der Empfehlungs-Engine und einen frontend-Unterordner mit dem Flutter-Frontend-Code.

4. Abhängigkeiten für das Projekt herunterladen

Backend

Wir verwenden Flask, um unser Backend zu erstellen. Öffnen Sie das Terminal und führen Sie Folgendes aus:

pip install Flask flask-cors requests numpy

Frontend

  1. Klicken Sie in VS Code auf Datei > Ordner öffnen und wählen Sie dann den Ordner step0 aus dem Quellcode aus, den Sie zuvor heruntergeladen haben.
  2. Öffnen Sie die Datei step0/frontend/lib/main.dart. Wenn ein VS Code-Dialogfeld angezeigt wird, in dem Sie aufgefordert werden, die erforderlichen Pakete für die Starter-App herunterzuladen, klicken Sie auf Pakete herunterladen.
  3. Wenn dieses Dialogfeld nicht angezeigt wird, öffnen Sie das 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. Achten Sie darauf, dass der Android-Emulator oder iOS-Simulator richtig eingerichtet ist und in der Statusleiste angezeigt wird.

So sieht es beispielsweise aus, wenn Sie das Pixel 5 mit dem Android-Emulator verwenden:

9767649231898791.png

So sieht es aus, wenn Sie das iPhone 13 mit dem iOS-Simulator verwenden:

95529e3a682268b2.png

  1. Klicken Sie auf a19a0c68bc4046e6.png Fehlerbehebung starten.

App ausführen und ausprobieren

Die App sollte im Android Emulator oder iOS Simulator gestartet werden. Die Benutzeroberfläche ist recht einfach. Es gibt ein Textfeld, in das der Nutzer den Text als Nutzer-ID eingeben kann. Die Flutter-App sendet die Anfrage an das Backend, in dem zwei Empfehlungsmodelle ausgeführt werden. Das Backend gibt eine sortierte Liste mit Filmempfehlungen zurück. Das Frontend zeigt das Ergebnis in der Benutzeroberfläche an, nachdem es die Antwort erhalten hat.

d21427db9587560f.png 73e8272a5ce8dfbc.png

Wenn Sie jetzt auf Empfehlen klicken, passiert nichts, da die App noch nicht mit dem Backend kommunizieren kann.

6. Schritt 1: Abruf- und Ranking-Modelle für die Empfehlungs-Engine erstellen

Empfehlungssysteme in der Praxis bestehen oft aus mehreren Phasen:

  1. In der Abrufphase wird eine erste Gruppe von Hunderten von Kandidaten aus allen möglichen Kandidaten ausgewählt. Das Hauptziel dieses Modells ist es, alle Kandidaten, an denen der Nutzer nicht interessiert ist, effizient auszusortieren. Da das Abrufmodell möglicherweise Millionen von Kandidaten verarbeiten muss, muss es recheneffizient sein.
  2. In der Ranking-Phase werden die Ausgaben des Abrufmodells optimiert, um die bestmöglichen Empfehlungen auszuwählen. Die Aufgabe besteht darin, die Menge der Artikel, an denen der Nutzer interessiert sein könnte, auf eine Shortlist von wahrscheinlichen Kandidaten in der Größenordnung von Hunderten einzugrenzen.
  3. In der Phase nach dem Ranking werden die Kandidaten neu organisiert, um für Vielfalt, Aktualität und Fairness zu sorgen. So entsteht eine Reihe von nützlichen Empfehlungen in der Größenordnung von Dutzenden.

70dfc0d7e989164f.png

In diesem Codelab trainieren Sie ein Abrufmodell und ein Ranking-Modell mit dem beliebten MovieLens-Dataset. Sie können den Trainingscode unten über Colab öffnen und der Anleitung folgen:

7. Schritt 2: Backend für das Empfehlungssystem erstellen

Nachdem Sie die Abruf- und Rankingmodelle trainiert haben, können Sie sie bereitstellen und ein Backend 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.

  • Wechseln Sie in Ihrem Terminal zum Ordner step2/backend auf Ihrem Computer 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 zuerst automatisch das TensorFlow Serving-Image herunter. Das dauert etwa eine Minute. Danach sollte TensorFlow Serving gestartet werden. Das Log sollte so 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 das „Verketten“ mehrerer sequenzieller Modelle nicht unterstützt, müssen Sie einen neuen Dienst erstellen, der die Abruf- und Ranking-Modelle verbindet.

  • Fügen Sie diesen Code der Funktion get_recommendations() in der Datei step2/backend/recommendations.py 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.

  • Wechseln Sie im Terminal zum Ordner step2/backend/ und führen Sie Folgendes aus:
FLASK_APP=recommender.py FLASK_ENV=development flask run

Flask richtet einen neuen Endpunkt unter http://localhost:5000/recommend ein. Das Log sollte so aussehen:

 * 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 zu prüfen, ob 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 der empfohlenen Filme für 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)"
  ]
}

Geschafft! Sie haben erfolgreich ein Backend erstellt, das Filme auf Grundlage einer Nutzer-ID empfehlen kann.

8. Schritt 3: Flutter-App für Android und iOS erstellen

Das Backend ist bereit. Sie können jetzt Anfragen senden, um Filmpfehlungen von der Flutter-App abzurufen.

Die Frontend-App ist recht einfach. Es enthält nur ein TextField, in das die Nutzer-ID eingegeben wird, und sendet die Anfrage (in der Funktion recommend()) an das Backend, das Sie gerade erstellt haben. Nachdem die Antwort eingegangen ist, werden die empfohlenen Filme in der App-Benutzeroberfläche in einer ListView angezeigt.

  • Fügen Sie diesen Code der Funktion recommend() in der Datei step3/frontend/lib/main.dart 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 App die Antwort vom Backend empfängt, 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 oben stehenden 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 Fehlerbehebung starten und warten Sie, bis die App geladen ist.
  2. Geben Sie eine Nutzer-ID ein (z.B. 42) – wähle 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 eingestellt ist.
  2. Klicken Sie auf a19a0c68bc4046e6.png Fehlerbehebung starten und warten Sie, bis die App geladen ist.
  3. Geben Sie eine Nutzer-ID ein (z.B. 42) – wähle dann Empfehlen aus.

2665514231033f1.png

Mac

  1. Für Mac müssen Sie entsprechende Berechtigungen einrichten, da die App HTTP-Anfragen an das Backend sendet. Weitere Informationen finden Sie unter Berechtigungen und die App-Sandbox.

Fügen Sie diesen Code zu step4/frontend/macOS/Runner/DebugProfile.entitlements und 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 eingestellt ist.
  2. Klicken Sie auf a19a0c68bc4046e6.png Fehlerbehebung starten und warten Sie, bis die App geladen ist.
  3. Geben Sie eine Nutzer-ID ein (z.B. 42) – wähle dann Empfehlen aus.

860d523a7ac537e0.png

Windows

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

7d77c1e52a5927fc.png

10. Schritt 5: Flutter-App auf der Webplattform ausführen

Sie können der Flutter-App auch Webunterstützung hinzufügen. Standardmäßig ist die Webplattform für Flutter-Apps automatisch aktiviert. Sie müssen die App also nur starten.

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

9376e1e432c18bef.png

11. Glückwunsch

Sie haben eine Full-Stack-App erstellt, mit der Sie Ihren Nutzern Filme empfehlen können.

Obwohl die App nur Filme empfiehlt, haben Sie den allgemeinen Workflow zum Erstellen eines leistungsstarken Empfehlungssystems kennengelernt und gelernt, wie Sie die Empfehlungen in einer Flutter-App nutzen. Sie können das Gelernte problemlos auf andere Szenarien anwenden, z.B. E-Commerce, Lebensmittel und Kurzvideos.

Weitere Informationen