1. Zanim zaczniesz
Systemy rekomendacji, zwane też rekomendatorami, to bardzo ważne zastosowanie uczenia maszynowego. Mogą one polecać filmy lub restauracje albo wyróżniać ciekawe filmy. Systemy rekomendacji pomagają Ci wyświetlać użytkownikom atrakcyjne treści z dużej puli kandydatów. Na przykład w Sklepie Google Play możesz zainstalować miliony aplikacji, a w YouTube obejrzeć miliardy filmów. Każdego dnia dodajemy kolejne aplikacje i filmy.
Z tego ćwiczenia w Codelabs dowiesz się, jak utworzyć pełną usługę polecającą przy użyciu:
- TensorFlow Recommenders do trenowania modelu pobierania i modelu rankingowego na potrzeby rekomendacji filmów.
- TensorFlow Serving do udostępniania modeli.
- Flutter do tworzenia aplikacji na wielu platformach, która wyświetla rekomendowane filmy
Wymagania wstępne
- Podstawowa wiedza na temat tworzenia aplikacji w Flutterze za pomocą języka Dart.
- Podstawowa wiedza o uczeniu maszynowym za pomocą TensorFlow, np. różnice między trenowaniem a wdrażaniem.
- Podstawowa znajomość systemów rekomendacji
- Podstawowa znajomość Pythona, terminali i Dockera
Czego się nauczysz
- Jak trenować modele wyszukiwania i rankingu za pomocą biblioteki TensorFlow Recommenders
- Jak obsługiwać wytrenowane modele rekomendacji za pomocą TensorFlow Serving
- Tworzenie aplikacji Flutter na wielu platformach do wyświetlania polecanych produktów
Czego potrzebujesz
- Pakiet SDK Flutter
- Konfiguracja Android i iOS na potrzeby Fluttera
- Konfiguracja na komputerze w przypadku Fluttera
- Konfiguracja w internecie w przypadku Fluttera
- Konfigurowanie Visual Studio Code (VS Code) na potrzeby Fluttera i Darta
- Docker
- Bash
- Python 3.7 lub nowszy
- Dostęp do Colab
2. Konfigurowanie środowiska programistycznego Fluttera
Aby ukończyć to ćwiczenie, potrzebujesz 2 programów: pakietu SDK Flutter i edytora.
Frontend ćwiczeń możesz uruchomić na dowolnym z tych urządzeń:
- Symulator iOS (wymaga zainstalowania narzędzi Xcode).
- Android Emulator (wymaga konfiguracji w Android Studio).
- przeglądarka (do debugowania wymagana jest Chrome);
- Jako aplikacja komputerowa na Windows, Linux lub macOS. Musisz tworzyć aplikację na platformie, na której zamierzasz ją wdrożyć. Jeśli chcesz opracować aplikację na komputery z systemem Windows, musisz to zrobić na komputerze z tym systemem, aby mieć dostęp do odpowiedniego łańcucha kompilacji. Istnieją wymagania dotyczące poszczególnych systemów operacyjnych, które są szczegółowo opisane na stronie docs.flutter.dev/desktop.
W przypadku backendu potrzebne są:
- komputer z systemem Linux lub Mac z procesorem Intel;
3. Konfiguracja
Aby pobrać kod do tego ćwiczenia:
- Otwórz repozytorium GitHub tego ćwiczenia.
- Aby pobrać cały kod do tych ćwiczeń z programowania, kliknij Code > Download zip (Kod > Pobierz plik ZIP).

- Rozpakuj pobrany plik ZIP, aby wyodrębnić folder główny
codelabs-mainze wszystkimi potrzebnymi zasobami.
W tym module potrzebne są tylko pliki z podkatalogu tfrs-flutter/ w repozytorium, który zawiera kilka folderów:
- Foldery
step0–step5zawierają kod startowy, który będziesz rozwijać w kolejnych krokach tego ćwiczenia. - Folder
finishedzawiera gotowy kod ukończonej przykładowej aplikacji. - Każdy folder zawiera podfolder
backend, który zawiera kod backendu silnika rekomendacji, oraz podfolderfrontend, który zawiera kod frontendowy Fluttera.
4. Pobierz zależności projektu.
Backend
Do utworzenia backendu użyjemy Flaska. Otwórz terminal i uruchom to polecenie:
pip install Flask flask-cors requests numpy
Frontend
- W VS Code kliknij File > Open folder (Plik > Otwórz folder), a następnie wybierz folder
step0z 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 wymaganych pakietów dla aplikacji startowej, kliknij Pobierz pakiety. - Jeśli nie widzisz tego okna, otwórz terminal, a następnie uruchom polecenie
flutter pub getw folderzestep0/frontend.

5. Krok 0. Uruchom aplikację startową
- Otwórz plik
step0/frontend/lib/main.dartw VS Code i upewnij się, że emulator Androida lub symulator iOS jest prawidłowo skonfigurowany i wyświetla się na pasku stanu.
Oto przykład tego, co zobaczysz, gdy użyjesz Pixela 5 z emulatorem Androida:

Oto co zobaczysz, gdy użyjesz iPhone'a 13 z symulatorem iOS:

- Kliknij
Rozpocznij debugowanie.
Uruchamianie aplikacji i jej poznawanie
Aplikacja powinna się uruchomić w emulatorze Androida lub symulatorze iOS. Interfejs jest dość prosty. Jest tam 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 uruchomi 2 modele rekomendacji i zwróci uporządkowaną listę rekomendacji filmów. Po otrzymaniu odpowiedzi interfejs wyświetli wynik w interfejsie użytkownika.

Jeśli teraz klikniesz Poleć, 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
Systemy rekomendacji w rzeczywistości często składają się z kilku etapów:
- Etap pobierania odpowiada za wybranie początkowego zestawu setek kandydatów spośród wszystkich możliwych kandydatów. Głównym celem tego modelu jest skuteczne odfiltrowanie wszystkich kandydatów, którymi użytkownik nie jest zainteresowany. Model pobierania może mieć do czynienia z milionami kandydatów, dlatego musi być wydajny obliczeniowo.
- Na etapie rankingu dane wyjściowe modelu pobierania są dopracowywane w celu wybrania najlepszych rekomendacji. Jego zadaniem jest zawężenie zbioru produktów, które mogą zainteresować użytkownika, do krótkiej listy prawdopodobnych kandydatów w liczbie setek.
- Etap pozycjonowania pomaga zapewnić różnorodność, aktualność i uczciwość oraz reorganizuje kandydatów w zestaw przydatnych rekomendacji w liczbie kilkudziesięciu.

W tym ćwiczeniu w Codelabs wytrenujesz model wyszukiwania i model rankingowy przy użyciu popularnego zbioru danych MovieLens. Poniższy kod szkoleniowy możesz otworzyć w Colab i postępować zgodnie z instrukcjami:
7. Krok 2. Utwórz backend systemu rekomendacji
Po wytrenowaniu modeli wyszukiwania i rankingu możesz je wdrożyć i utworzyć backend.
Uruchamianie TensorFlow Serving
Aby wygenerować listę rekomendowanych filmów, musisz użyć zarówno modelu pobierania, jak i modelu rankingowego, więc wdrażasz je jednocześnie za pomocą TensorFlow Serving.
- W terminalu przejdź do folderu
step2/backendna komputerze i uruchom TensorFlow Serving za pomocą Dockera:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/:/models/" tensorflow/serving --model_config_file=/models/models.config
Docker najpierw automatycznie pobierze obraz TensorFlow Serving, co zajmie minutę. Następnie powinna się uruchomić usługa TensorFlow Serving. Dziennik powinien wyglądać jak ten fragment kodu:
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 ...
Tworzenie nowego punktu końcowego
TensorFlow Serving nie obsługuje „łączenia” wielu modeli sekwencyjnych, dlatego musisz utworzyć nową usługę, która połączy modele wyszukiwania 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)
Uruchom usługę 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 utworzy nowy punkt końcowy pod adresem http://localhost:5000/recommend. Dziennik powinien wyglądać tak:
* 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ć do punktu końcowego przykładowe żądanie, aby upewnić się, że 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ę polecanych filmów 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)"
]
}
To wszystko. 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 niego żądania, aby uzyskać rekomendacje filmów z aplikacji Flutter.
Aplikacja frontendowa jest dość prosta. Zawiera tylko pole tekstowe, które przyjmuje identyfikator użytkownika i wysyła żądanie (w funkcji recommend()) do utworzonego właśnie backendu. Po otrzymaniu odpowiedzi interfejs aplikacji wyświetla 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, zaktualizuj interfejs, aby wyświetlić listę polecanych filmów dla określonego użytkownika.
- Dodaj ten kod bezpośrednio pod powyższym kodem:
if (response.statusCode == 200) {
return List<String>.from(jsonDecode(response.body)['movies']);
} else {
throw Exception('Error response');
}
Uruchom
- Kliknij
Rozpocznij debugowanie, a następnie poczekaj na wczytanie aplikacji. - Wpisz identyfikator użytkownika (np. 42), a następnie kliknij Poleć.

9. Krok 4. Uruchom aplikację Flutter na platformach desktopowych
Oprócz Androida i iOS Flutter obsługuje też platformy desktopowe, takie jak Linux, Mac i Windows.
Linux
- Upewnij się, że na pasku stanu VSCode wybrane urządzenie docelowe to
. - Kliknij
Rozpocznij debugowanie, a następnie poczekaj na wczytanie aplikacji. - Wpisz identyfikator użytkownika (np. 42), a następnie kliknij Poleć.

Mac
- W przypadku komputerów Mac 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 do plików step4/frontend/macOS/Runner/DebugProfile.entitlements i step4/frontend/macOS/Runner/Release.entitlements:
<key>com.apple.security.network.client</key>
<true/>
- Upewnij się, że na pasku stanu VSCode wybrane urządzenie docelowe to
. - Kliknij
Rozpocznij debugowanie, a następnie poczekaj na wczytanie aplikacji. - Wpisz identyfikator użytkownika (np. 42), a następnie kliknij Poleć.

Windows
- Upewnij się, że na pasku stanu VSCode wybrane urządzenie docelowe to
. - Kliknij
Rozpocznij debugowanie, a następnie poczekaj na wczytanie aplikacji. - Wpisz identyfikator użytkownika (np. 42), a następnie kliknij Poleć.

10. Krok 5. Uruchom aplikację Flutter na platformie internetowej
Możesz też dodać obsługę internetu do aplikacji Flutter. Platforma internetowa jest domyślnie włączona w przypadku aplikacji Flutter, więc wystarczy ją uruchomić.
- Upewnij się, że na pasku stanu VSCode wybrane urządzenie docelowe to
. - Kliknij
Rozpocznij debugowanie, a następnie poczekaj, aż aplikacja wczyta się w przeglądarce Chrome. - Wpisz identyfikator użytkownika (np. 42), a następnie kliknij Poleć.

11. Gratulacje
Udało Ci się stworzyć aplikację fullstack, która rekomenduje filmy użytkownikom.
Chociaż aplikacja rekomenduje tylko filmy, poznałeś(-aś) ogólny przepływ pracy związany z tworzeniem zaawansowanego systemu rekomendacji i opanowałeś(-aś) umiejętność korzystania z rekomendacji w aplikacji Flutter. Możesz łatwo zastosować zdobytą wiedzę w innych scenariuszach (np. w e-commerce, w przypadku jedzenia i krótkich filmów).