Создание полнофункциональной системы рекомендаций фильмов

1. Прежде чем начать

От рекомендации фильмов или ресторанов до выделения развлекательных видеороликов — системы рекомендаций, также известные как рекомендатели, являются очень важным применением машинного обучения. Рекомендатели помогают вам предлагать вашим пользователям привлекательный контент от большого количества кандидатов. Например, Google Play Store предлагает для установки миллионы приложений, а YouTube — миллиарды видео для просмотра. И каждый день добавляется еще больше приложений и видео.

В этой лаборатории кода вы узнаете, как создать полнофункциональный рекомендатель, используя:

  • Рекомендации TensorFlow для обучения модели поиска и ранжирования рекомендаций фильмов.
  • TensorFlow Сервис для обслуживания моделей
  • Flutter для создания кроссплатформенного приложения для отображения рекомендуемых фильмов

Предварительные условия

  • Базовые знания разработки Flutter с помощью Dart.
  • Базовые знания машинного обучения с TensorFlow, например, обучение или развертывание.
  • Базовое знание рекомендательных систем.
  • Базовые знания Python, терминалов и Docker.

Что вы узнаете

  • Как обучать модели поиска и ранжирования с помощью рекомендателей TensorFlow
  • Как обслуживать обученные модели рекомендаций с помощью TensorFlow Serving
  • Как создать кроссплатформенное приложение Flutter для отображения рекомендуемых элементов

Что вам понадобится

2. Настройте среду разработки Flutter.

Для разработки Flutter вам понадобятся два программного обеспечения для выполнения этой лабораторной работы — Flutter SDK и редактор .

Вы можете запустить интерфейс кодовой лаборатории, используя любое из этих устройств:

  • Симулятор iOS (требуется установка инструментов Xcode).
  • Эмулятор Android (требуется установка в Android Studio).
  • Браузер (для отладки необходим Chrome).
  • В качестве настольного приложения для Windows , Linux или macOS . Вы должны разрабатывать на платформе, на которой планируете развернуть. Итак, если вы хотите разработать настольное приложение для Windows, вам необходимо разработать его в Windows, чтобы получить доступ к соответствующей цепочке сборки. Существуют требования, специфичные для операционной системы, которые подробно описаны на docs.flutter.dev/desktop .

Для бэкэнда вам понадобится:

  • Машина с Linux или Mac на базе Intel.

3. Настройте

Чтобы загрузить код для этой лаборатории кода:

  1. Перейдите в репозиторий GitHub для этой лаборатории кода.
  2. Нажмите «Код» > «Загрузить zip» , чтобы загрузить весь код для этой лаборатории кода.

2cd45599f51fb8a2.png

  1. Разархивируйте загруженный zip-файл, чтобы распаковать codelabs-main со всеми необходимыми ресурсами.

Для этой лаборатории кода вам понадобятся только файлы в подкаталоге tfrs-flutter/ репозитория, который содержит несколько папок:

  • Папки step0 до step5 содержат начальный код, который вы используете для каждого шага этой лаборатории кода.
  • finished папка содержит готовый код готового примера приложения.
  • Каждая папка содержит backend подпапку, которая включает внутренний код механизма рекомендаций, и frontend подпапку, которая включает внешний код Flutter.

4. Загрузите зависимости для проекта.

Бэкэнд

Мы собираемся использовать Flask для создания нашего бэкэнда. Откройте терминал и выполните следующее:

pip install Flask flask-cors requests numpy

Внешний интерфейс

  1. В VS Code нажмите «Файл» > «Открыть папку» , а затем выберите папку step0 из исходного кода, который вы скачали ранее.
  2. Откройте файл step0/frontend/lib/main.dart . Если вы увидите диалоговое окно VS Code, предлагающее загрузить необходимые пакеты для начального приложения, нажмите « Получить пакеты» .
  3. Если вы не видите это диалоговое окно, откройте терминал и затем запустите команду flutter pub get в папке step0/frontend .

7ada07c300f166a6.png

5. Шаг 0. Запустите стартовое приложение.

  1. Откройте файл step0/frontend/lib/main.dart в VS Code, убедитесь, что эмулятор Android или симулятор iOS правильно настроен и отображается в строке состояния.

Например, вот что вы видите при использовании Pixel 5 с эмулятором Android:

9767649231898791.png

Вот что вы видите, когда используете iPhone 13 с симулятором iOS:

95529e3a682268b2.png

  1. Нажмите a19a0c68bc4046e6.png Запустите отладку .

Запустите и изучите приложение

Приложение должно запуститься на вашем эмуляторе Android или симуляторе iOS. Пользовательский интерфейс довольно прост. Существует текстовое поле, которое позволяет пользователю вводить текст в качестве идентификатора пользователя. Приложение Flutter отправит запрос на серверную часть, которая запускает две модели рекомендаций и возвращает ранжированный список рекомендаций по фильмам. Интерфейс отобразит результат в пользовательском интерфейсе после получения ответа.

d21427db9587560f.png73e8272a5ce8dfbc.png

Если вы нажмете «Рекомендовать сейчас», ничего не произойдет, поскольку приложение еще не может взаимодействовать с серверной частью.

6. Шаг 1. Создайте модели поиска и ранжирования для системы рекомендаций.

Реальные системы рекомендаций часто состоят из нескольких этапов:

  1. Этап поиска отвечает за выбор начального набора из сотен кандидатов из всех возможных кандидатов. Основная цель этой модели — эффективно отсеять всех кандидатов, которые не интересуют пользователя. Поскольку модель поиска может иметь дело с миллионами кандидатов, она должна быть эффективной в вычислительном отношении.
  2. На этапе ранжирования результаты модели поиска анализируются и настраиваются для выбора наилучшего набора рекомендаций. Его задача — сузить набор элементов, которые могут заинтересовать пользователя, до короткого списка вероятных кандидатов, насчитывающего порядка сотен.
  3. Этап пост-рейтинга помогает обеспечить разнообразие, свежесть и справедливость и реорганизует элементы-кандидаты в набор полезных рекомендаций, насчитывающих порядка десятков.

70dfc0d7e989164f.png

В этой кодовой лаборатории вы обучаете модель поиска и модель ранжирования с использованием популярного набора данных 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');
}

Запусти это

  1. Нажмите a19a0c68bc4046e6.png Запустите отладку и дождитесь загрузки приложения.
  2. Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .

badb59d8b96959ae.pnga0d2d4020aebfb0a.png

9. Шаг 4. Запустите приложение Flutter на настольных платформах.

Помимо Android и iOS, Flutter также поддерживает настольные платформы, включая Linux, Mac и Windows.

Линукс

  1. Убедитесь, что на целевом устройстве установлено значение 86cba523de82b4f9.png в строке состояния VSCode.
  2. Нажмите a19a0c68bc4046e6.png Запустите отладку и дождитесь загрузки приложения.
  3. Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .

2665514231033f1.png

Мак

  1. Для Mac вам необходимо настроить соответствующие права, поскольку приложение будет отправлять HTTP-запросы на серверную часть. Дополнительную информацию см. в разделах «Права» и «Песочница приложения» .

Добавьте этот код в step4/frontend/macOS/Runner/DebugProfile.entitlements и step4/frontend/macOS/Runner/Release.entitlements соответственно:

<key>com.apple.security.network.client</key>
<true/>
  1. Убедитесь, что на целевом устройстве установлено значение eb4b0b5563824138.png в строке состояния VSCode.
  2. Нажмите a19a0c68bc4046e6.png Запустите отладку и дождитесь загрузки приложения.
  3. Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .

860d523a7ac537e0.png

Окна

  1. Убедитесь, что на целевом устройстве установлено значение 9587be1bb375bc0f.png в строке состояния VSCode.
  2. Нажмите a19a0c68bc4046e6.png Запустите отладку и дождитесь загрузки приложения.
  3. Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .

7d77c1e52a5927fc.png

10. Шаг 5. Запустите приложение Flutter на веб-платформе.

Еще одна вещь, которую вы можете сделать, — это добавить веб-поддержку в приложение Flutter. По умолчанию веб-платформа автоматически включается для приложений Flutter, поэтому все, что вам нужно сделать, это запустить ее.

  1. Убедитесь, что на целевом устройстве установлено 71db93efa928d15d.png в строке состояния VSCode.
  2. Нажмите a19a0c68bc4046e6.png Запустите отладку и дождитесь загрузки приложения в браузере Chrome.
  3. Введите идентификатор пользователя (например, 42), а затем выберите «Рекомендовать» .

9376e1e432c18bef.png

11. Поздравления

Вы создали полнофункциональное приложение, чтобы рекомендовать своим пользователям фильмы!

Хотя приложение рекомендует только фильмы, вы изучили общий рабочий процесс создания мощного механизма рекомендаций и овладели навыками использования рекомендаций в приложении Flutter. Вы можете легко применить полученные знания в других сценариях (например, электронная коммерция, еда и короткие видеоролики).

Узнать больше