1. Zanim zaczniesz
Systemy rekomendacji to bardzo ważne zastosowanie systemów uczących się – od polecania filmów lub restauracji po wyróżnianie zabawnych filmów. Usługi polecające pomagają prezentować Twoim użytkownikom atrakcyjne treści pochodzące od dużej liczby kandydatów. Na przykład Sklep Google Play oferuje do zainstalowania miliony aplikacji, a YouTube zapewnia dostęp do miliardów filmów do obejrzenia. Codziennie dodajemy kolejne aplikacje i filmy.
Z tego ćwiczenia w Codelabs dowiesz się, jak utworzyć usługę polecającą typu fullstack za pomocą:
- Usługi polecające TensorFlow trenują pobieranie i model rankingowy na potrzeby rekomendacji filmów
- TensorFlow Serving (udostępnianie TensorFlow) do obsługi modeli
- Flutter tworzy aplikację wieloplatformową do wyświetlania polecanych filmów
Wymagania wstępne
- Podstawowa wiedza o rozwoju technologii Flutter w Dart
- Podstawowa wiedza na temat systemów uczących się z wykorzystaniem TensorFlow, np. do trenowania i wdrażania
- Podstawowa znajomość systemów rekomendacji
- Podstawowa znajomość Pythona, terminali i Dockera
Czego się nauczysz
- Jak trenować modele pobierania i wyznaczania pozycji w rankingu za pomocą usług polecających TensorFlow
- Jak udostępniać wytrenowane modele rekomendacji za pomocą TensorFlow Serving
- Jak utworzyć wieloplatformową aplikację Flutter do wyświetlania zalecanych elementów
Czego potrzebujesz
- Pakiet SDK Flutter
- Konfiguracja aplikacji Flutter na Androida i iOS
- Konfiguracja Flutter na komputerze
- Konfigurowanie przeglądarki na potrzeby Flutter
- Konfigurowanie kodu VS Code w usługach Flutter i Dart
- Docker
- Bash
- Python w wersji 3.7 lub nowszej
- Dostęp do Colab
2. Konfigurowanie środowiska programistycznego Flutter
Do programowania w technologii Flutter potrzebujesz 2 programów do ukończenia ćwiczenia – pakietu SDK Flutter i edytora.
Frontend ćwiczeń z programowania możesz uruchomić na dowolnym z tych urządzeń:
- Symulator iOS (wymaga zainstalowania narzędzi Xcode).
- Emulator Androida (wymaga skonfigurowania Android Studio).
- Przeglądarka (do debugowania wymagany jest Chrome).
- Aplikacja komputerowa w systemie Windows, Linux lub macOS Programowanie należy tworzyć na platformie, na której zamierzasz wdrożyć usługę. Jeśli więc chcesz opracować aplikację komputerową dla systemu Windows, musisz to zrobić w tym systemie, aby uzyskać dostęp do odpowiedniego łańcucha kompilacji. Istnieją wymagania związane z konkretnymi systemami operacyjnymi, które zostały szczegółowo omówione na stronie docs.flutter.dev/desktop.
Co będzie potrzebne do korzystania z backendu:
- Komputer z systemem Linux lub Mac z procesorem Intel.
3. Konfiguracja
Aby pobrać kod do tego ćwiczenia z programowania:
- Aby przeprowadzić ten moduł, przejdź do repozytorium GitHub.
- Kliknij Kod > Pobierz plik ZIP, aby pobrać cały kod do tego ćwiczenia z programowania.
- Rozpakuj pobrany plik ZIP, aby rozpakować folder główny
codelabs-main
ze wszystkimi potrzebnymi zasobami.
Aby wykonać te ćwiczenia w Codelabs, potrzebujesz tylko plików w podkatalogu tfrs-flutter/
repozytorium, które zawiera wiele folderów:
- Foldery od
step0
dostep5
zawierają kod startowy, który powstał w każdym kroku tego ćwiczenia z programowania. - Folder
finished
zawiera kompletny kod gotowej przykładowej aplikacji. - Każdy folder zawiera podfolder
backend
zawierający kod backendu systemu rekomendacji oraz podfolderfrontend
zawierający kod frontendu Flutter
4. Pobierz zależności w projekcie
Backend
Do utworzenia backendu użyjemy Flask. Otwórz terminal i uruchom to polecenie:
pip install Flask flask-cors requests numpy
Frontend
- W sekcji VS Code kliknij File (Plik) > Otwórz folder, a następnie wybierz folder
step0
z pobranego wcześniej kodu źródłowego. - Otwórz plik
step0/frontend/lib/main.dart
. Jeśli pojawi się okno VS Code z prośbą o pobranie pakietów wymaganych do aplikacji startowej, kliknij Pobierz pakiety. - Jeśli nie widzisz tego okna, otwórz terminal i uruchom polecenie
flutter pub get
w folderzestep0/frontend
.
5. Krok 0. Uruchom aplikację startową
- Otwórz plik
step0/frontend/lib/main.dart
w VS Code. Sprawdź, czy emulator Androida lub symulator iOS są prawidłowo skonfigurowane i wyświetlają się na pasku stanu.
Na przykład podczas używania Pixela 5 z emulatorem Androida możesz zobaczyć takie elementy:
Oto, co możesz zobaczyć, używając iPhone'a 13 za pomocą symulatora iOS:
- Kliknij Rozpocznij debugowanie.
Uruchamianie i poznawanie aplikacji
Aplikacja powinna się uruchomić w emulatorze Androida lub symulatorze iOS. Interfejs jest dość prosty. Dostępne jest pole tekstowe, w którym użytkownik może wpisać tekst jako identyfikator użytkownika. Aplikacja Flutter wyśle żądanie zapytania do backendu, który uruchamia 2 modele rekomendacji i zwraca uporządkowaną listę rekomendacji filmów. Po otrzymaniu odpowiedzi frontend wyświetli wynik w interfejsie użytkownika.
Jeśli teraz klikniesz Polecaj, nic się nie stanie, ponieważ aplikacja nie może jeszcze komunikować się z backendem.
6. Krok 1. Utwórz modele pobierania i rankingu dla systemu rekomendacji
Rzeczywiste systemy rekomendacji często składają się z wielu etapów:
- Etap pobierania odpowiada za wybranie początkowego zestawu setek propozycji spośród wszystkich możliwych. Głównym celem tego modelu jest skuteczne usuwanie wszystkich kandydatów, którymi użytkownik nie jest zainteresowany. Model pobierania może obejmować miliony kandydatów, dlatego musi być wydajny pod względem obliczeń.
- Na etapie tworzenia rankingu analizuje dane wyjściowe modelu pobierania i dostosowuje je, aby wybrać najlepszą możliwą grupę rekomendacji. Jego zadaniem jest zawężenie listy pozycji, które mogą zainteresować użytkownika, do opartej na kilkuset krótkiej liście prawdopodobnych kandydatów.
- Etap po rankingu pomaga zapewnić różnorodność, aktualność i obiektywność, a także reorganizuje kandydujące elementy w zestaw przydatnych rekomendacji w kolejności dziesiątek.
Na potrzeby tego ćwiczenia w Codelabs wytrenujesz model pobierania i model rankingowy, korzystając z popularnego zbioru danych MovieLens. Możesz otworzyć w Colab poniższy kod trenowania i postępować zgodnie z instrukcjami:
7. Krok 2. Utwórz backend systemu rekomendacji
Po wytrenowaniu modeli pobierania i ustalania rankingu możesz je wdrożyć i utworzyć backend.
Rozpocznij udostępnianie TensorFlow
Do wygenerowania zalecanej listy filmów musisz używać obu modeli pobierania i modelowania rankingu, więc wdrażasz je jednocześnie przy użyciu TensorFlow Serving.
- W terminalu otwórz folder
step2/backend
na komputerze i uruchom TensorFlow Serving with Docker:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/:/models/" tensorflow/serving --model_config_file=/models/models.config
Docker automatycznie pobiera najpierw obraz TensorFlow Serving, co zajmuje minutę. Następnie powinna uruchomić się usługa TensorFlow Serving. Dziennik powinien wyglądać tak:
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 ...
Utwórz nowy punkt końcowy
Ponieważ TensorFlow Serving nie obsługuje „łańcuchów” wielu modeli sekwencyjnych, musisz utworzyć nową usługę, która łączy modele pobierania i rankingu.
- Dodaj ten kod do funkcji
get_recommendations()
w plikustep2/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)
Uruchamianie usługi Flask
Teraz możesz uruchomić usługę Flask.
- W terminalu przejdź do folderu
step2/backend/
i uruchom to polecenie:
FLASK_APP=recommender.py FLASK_ENV=development flask run
Flask ustawi nowy punkt końcowy na http://localhost:5000/recommend
. Dziennik powinien wyświetlić się poniżej:
* 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 -
Możesz wysłać przykładowe żądanie do punktu końcowego, aby sprawdzić, czy działa on zgodnie z oczekiwaniami:
curl -X POST -H "Content-Type: application/json" -d '{"user_id":"42"}' http://localhost:5000/recommend
Punkt końcowy zwróci listę filmów polecanych dla użytkownika 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)" ] }
Znakomicie. Udało Ci się utworzyć backend do polecania filmów na podstawie identyfikatora użytkownika.
8. Krok 3. Utwórz aplikację Flutter na Androida i iOS
Backend jest gotowy. Możesz zacząć wysyłać do niej żądania, aby otrzymywać z aplikacji Flutter zapytania o rekomendacje filmów.
Aplikacja frontendu jest dość prosta. Zawiera tylko pole TextField, które pobiera identyfikator użytkownika i wysyła żądanie (w funkcji recommend()
) do właśnie utworzonego backendu. Po otrzymaniu odpowiedzi interfejs aplikacji wyświetli polecane filmy w widoku ListView.
- Dodaj ten kod do funkcji
recommend()
w plikustep3/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, }), );
Gdy aplikacja otrzyma odpowiedź z backendu, zaktualizujesz interfejs, aby wyświetlić listę polecanych filmów dla określonego użytkownika.
- Dodaj ten kod tuż pod kodem powyżej:
if (response.statusCode == 200) { return List<String>.from(jsonDecode(response.body)['movies']); } else { throw Exception('Error response'); }
Uruchom
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Wpisz identyfikator użytkownika (np. 42) a następnie wybierz Polecaj.
9. Krok 4. Uruchom aplikację Flutter na platformach komputerowych
Oprócz Androida i iOS Flutter obsługuje także platformy komputerowe, takie jak Linux, Mac i Windows.
Linux
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Wpisz identyfikator użytkownika (np. 42) a następnie wybierz Polecaj.
Mac
- W przypadku Maca musisz skonfigurować odpowiednie uprawnienia, ponieważ aplikacja będzie wysyłać żądania HTTP do backendu. Więcej informacji znajdziesz w artykule Uprawnienia i piaskownica aplikacji.
Dodaj ten kod odpowiednio do step4/frontend/macOS/Runner/DebugProfile.entitlements
i step4/frontend/macOS/Runner/Release.entitlements
:
<key>com.apple.security.network.client</key>
<true/>
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Wpisz identyfikator użytkownika (np. 42) a następnie wybierz Polecaj.
Windows
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji.
- Wpisz identyfikator użytkownika (np. 42) a następnie wybierz Polecaj.
10. Krok 5. Uruchom aplikację Flutter na platformie internetowej
Możesz też dodać obsługę sieci do aplikacji Flutter. Domyślnie platforma internetowa jest automatycznie włączona dla aplikacji Flutter, więc wystarczy ją uruchomić.
- Upewnij się, że urządzenie docelowe na pasku stanu VSCode jest ustawione na .
- Kliknij Rozpocznij debugowanie i poczekaj na wczytanie aplikacji w przeglądarce Chrome.
- Wpisz identyfikator użytkownika (np. 42) a następnie wybierz Polecaj.
11. Gratulacje
Udało Ci się stworzyć aplikację fullstack do polecania filmów Twoim użytkownikom.
Chociaż aplikacja tylko poleca filmy, znasz już ogólny przepływ pracy związany z tworzeniem zaawansowanego systemu rekomendacji i opanujesz umiejętność korzystania z rekomendacji w aplikacji Flutter. Zdobytą wiedzę możesz z łatwością wykorzystać w innych scenariuszach (np. w branży e-commerce, jedzenia czy krótkich filmów).