1. Прежде чем начать
От рекомендации фильмов или ресторанов до выделения развлекательных видеороликов — системы рекомендаций, также известные как рекомендатели, являются очень важным применением машинного обучения. Рекомендатели помогают вам предлагать вашим пользователям привлекательный контент от большого количества кандидатов. Например, Google Play Store предлагает для установки миллионы приложений, а YouTube — миллиарды видео для просмотра. И каждый день добавляется еще больше приложений и видео.
В этой лаборатории кода вы узнаете, как создать полнофункциональный рекомендатель, используя:
- Рекомендации TensorFlow для обучения модели поиска и ранжирования рекомендаций фильмов.
- TensorFlow Сервис для обслуживания моделей
- Flutter для создания кроссплатформенного приложения для отображения рекомендуемых фильмов
Предварительные условия
- Базовые знания разработки Flutter с помощью Dart.
- Базовые знания машинного обучения с TensorFlow, например, обучение или развертывание.
- Базовое знание рекомендательных систем.
- Базовые знания Python, терминалов и Docker.
Что вы узнаете
- Как обучать модели поиска и ранжирования с помощью рекомендателей TensorFlow
- Как обслуживать обученные модели рекомендаций с помощью TensorFlow Serving
- Как создать кроссплатформенное приложение Flutter для отображения рекомендуемых элементов
Что вам понадобится
- Флаттер SDK
- Настройка Android и iOS для Flutter
- Настройка рабочего стола для Flutter
- Веб -настройка для Flutter
- Настройка кода Visual Studio (VS Code) для Flutter и Dart
- Докер
- Баш
- Питон 3.7+
- Доступ к Колабу
2. Настройте среду разработки Flutter.
Для разработки Flutter вам понадобятся два программного обеспечения для выполнения этой лабораторной работы — Flutter SDK и редактор .
Вы можете запустить интерфейс кодовой лаборатории, используя любое из этих устройств:
- Симулятор iOS (требуется установка инструментов Xcode).
- Эмулятор Android (требуется установка в Android Studio).
- Браузер (для отладки необходим Chrome).
- В качестве настольного приложения для Windows , Linux или macOS . Вы должны разрабатывать на платформе, на которой планируете развернуть. Итак, если вы хотите разработать настольное приложение для Windows, вам необходимо разработать его в Windows, чтобы получить доступ к соответствующей цепочке сборки. Существуют требования, специфичные для операционной системы, которые подробно описаны на docs.flutter.dev/desktop .
Для бэкэнда вам понадобится:
- Машина с Linux или Mac на базе Intel.
3. Настройте
Чтобы загрузить код для этой лаборатории кода:
- Перейдите в репозиторий GitHub для этой лаборатории кода.
- Нажмите «Код» > «Загрузить zip» , чтобы загрузить весь код для этой лаборатории кода.
- Разархивируйте загруженный zip-файл, чтобы распаковать
codelabs-main
со всеми необходимыми ресурсами.
Для этой лаборатории кода вам понадобятся только файлы в подкаталоге tfrs-flutter/
репозитория, который содержит несколько папок:
- Папки
step0
доstep5
содержат начальный код, который вы используете для каждого шага этой лаборатории кода. -
finished
папка содержит готовый код готового примера приложения. - Каждая папка содержит
backend
подпапку, которая включает внутренний код механизма рекомендаций, иfrontend
подпапку, которая включает внешний код Flutter.
4. Загрузите зависимости для проекта.
Бэкэнд
Мы собираемся использовать Flask для создания нашего бэкэнда. Откройте терминал и выполните следующее:
pip install Flask flask-cors requests numpy
Внешний интерфейс
- В VS Code нажмите «Файл» > «Открыть папку» , а затем выберите папку
step0
из исходного кода, который вы скачали ранее. - Откройте файл
step0/frontend/lib/main.dart
. Если вы увидите диалоговое окно VS Code, предлагающее загрузить необходимые пакеты для начального приложения, нажмите « Получить пакеты» . - Если вы не видите это диалоговое окно, откройте терминал и затем запустите команду
flutter pub get
в папкеstep0/frontend
.
5. Шаг 0. Запустите стартовое приложение.
- Откройте файл
step0/frontend/lib/main.dart
в VS Code, убедитесь, что эмулятор Android или симулятор iOS правильно настроен и отображается в строке состояния.
Например, вот что вы видите при использовании Pixel 5 с эмулятором Android:
Вот что вы видите, когда используете iPhone 13 с симулятором iOS:
- Нажмите Запустите отладку .
Запустите и изучите приложение
Приложение должно запуститься на вашем эмуляторе Android или симуляторе iOS. Пользовательский интерфейс довольно прост. Существует текстовое поле, которое позволяет пользователю вводить текст в качестве идентификатора пользователя. Приложение Flutter отправит запрос на серверную часть, которая запускает две модели рекомендаций и возвращает ранжированный список рекомендаций по фильмам. Интерфейс отобразит результат в пользовательском интерфейсе после получения ответа.
Если вы нажмете «Рекомендовать сейчас», ничего не произойдет, поскольку приложение еще не может взаимодействовать с серверной частью.
6. Шаг 1. Создайте модели поиска и ранжирования для системы рекомендаций.
Реальные системы рекомендаций часто состоят из нескольких этапов:
- Этап поиска отвечает за выбор начального набора из сотен кандидатов из всех возможных кандидатов. Основная цель этой модели — эффективно отсеять всех кандидатов, которые не интересуют пользователя. Поскольку модель поиска может иметь дело с миллионами кандидатов, она должна быть эффективной в вычислительном отношении.
- На этапе ранжирования результаты модели поиска анализируются и настраиваются для выбора наилучшего набора рекомендаций. Его задача — сузить набор элементов, которые могут заинтересовать пользователя, до короткого списка вероятных кандидатов, насчитывающего порядка сотен.
- Этап пост-рейтинга помогает обеспечить разнообразие, свежесть и справедливость и реорганизует элементы-кандидаты в набор полезных рекомендаций, насчитывающих порядка десятков.
В этой кодовой лаборатории вы обучаете модель поиска и модель ранжирования с использованием популярного набора данных MovieLens. Вы можете открыть приведенный ниже обучающий код через Colab и следовать инструкциям:
7. Шаг 2. Создайте серверную часть механизма рекомендаций.
Теперь, когда вы обучили модели поиска и ранжирования, вы можете развернуть их и создать серверную часть.
Начать обслуживание TensorFlow
Поскольку для создания списка рекомендуемых фильмов вам необходимо использовать как модели поиска, так и модели ранжирования, вы развертываете их обе одновременно с помощью TensorFlow Serving.
- В своем терминале перейдите в папку
step2/backend
на своем компьютере и запустите TensorFlow Serving с Docker:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/:/models/" tensorflow/serving --model_config_file=/models/models.config
Docker сначала автоматически загружает образ TensorFlow Serving, что занимает минуту. После этого должно начаться обслуживание TensorFlow. Журнал должен выглядеть следующим образом:
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 ...
Создать новую конечную точку
Поскольку TensorFlow Serving не поддерживает «связывание» нескольких последовательных моделей, вам необходимо создать новый сервис, который соединяет модели поиска и ранжирования.
- Добавьте этот код в функцию
get_recommendations()
в файлеstep2/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)
Запустите службу Flask
Теперь вы можете запустить службу Flask.
- В терминале перейдите в папку
step2/backend/
и выполните следующее:
FLASK_APP=recommender.py FLASK_ENV=development flask run
Flask установит новую конечную точку по адресу http://localhost:5000/recommend
. Вы должны увидеть журнал, как показано ниже:
* 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 -
Вы можете отправить образец запроса на конечную точку, чтобы убедиться, что он работает должным образом:
curl -X POST -H "Content-Type: application/json" -d '{"user_id":"42"}' http://localhost:5000/recommend
Конечная точка вернет список рекомендуемых фильмов для пользователя 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)" ] }
Вот и все! Вы успешно создали серверную часть, позволяющую рекомендовать фильмы на основе идентификатора пользователя.
8. Шаг 3. Создайте приложение Flutter для Android и iOS.
Бэкэнд готов. Вы можете начать отправлять ему запросы для получения рекомендаций по фильмам из приложения Flutter.
Интерфейсное приложение довольно простое. У него есть только TextField, который принимает идентификатор пользователя и отправляет запрос (в функции recommend()
) на только что созданный бэкэнд. После получения ответа пользовательский интерфейс приложения отображает рекомендуемые фильмы в ListView.
- Добавьте этот код в функцию
recommend()
в файлеstep3/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, }), );
Как только приложение получит ответ от серверной части, вы обновите пользовательский интерфейс, чтобы отобразить список рекомендуемых фильмов для указанного пользователя.
- Добавьте этот код прямо под приведенным выше кодом:
if (response.statusCode == 200) { return List<String>.from(jsonDecode(response.body)['movies']); } else { throw Exception('Error response'); }
Запусти это
- Нажмите Запустите отладку и дождитесь загрузки приложения.
- Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .
9. Шаг 4. Запустите приложение Flutter на настольных платформах.
Помимо Android и iOS, Flutter также поддерживает настольные платформы, включая Linux, Mac и Windows.
Линукс
- Убедитесь, что на целевом устройстве установлено значение в строке состояния VSCode.
- Нажмите Запустите отладку и дождитесь загрузки приложения.
- Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .
Мак
- Для Mac вам необходимо настроить соответствующие права, поскольку приложение будет отправлять HTTP-запросы на серверную часть. Дополнительную информацию см. в разделах «Права» и «Песочница приложения» .
Добавьте этот код в step4/frontend/macOS/Runner/DebugProfile.entitlements
и step4/frontend/macOS/Runner/Release.entitlements
соответственно:
<key>com.apple.security.network.client</key>
<true/>
- Убедитесь, что на целевом устройстве установлено значение в строке состояния VSCode.
- Нажмите Запустите отладку и дождитесь загрузки приложения.
- Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .
Окна
- Убедитесь, что на целевом устройстве установлено значение в строке состояния VSCode.
- Нажмите Запустите отладку и дождитесь загрузки приложения.
- Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .
10. Шаг 5. Запустите приложение Flutter на веб-платформе.
Еще одна вещь, которую вы можете сделать, — это добавить веб-поддержку в приложение Flutter. По умолчанию веб-платформа автоматически включается для приложений Flutter, поэтому все, что вам нужно сделать, это запустить ее.
- Убедитесь, что на целевом устройстве установлено в строке состояния VSCode.
- Нажмите Запустите отладку и дождитесь загрузки приложения в браузере Chrome.
- Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .
11. Поздравления
Вы создали полнофункциональное приложение, чтобы рекомендовать своим пользователям фильмы!
Хотя приложение рекомендует только фильмы, вы изучили общий рабочий процесс создания мощного механизма рекомендаций и овладели навыками использования рекомендаций в приложении Flutter. Вы можете легко применить полученные знания в других сценариях (например, электронная коммерция, еда и короткие видеоролики).