ساخت یک سیستم توصیه فیلم کامل

۱. قبل از شروع

از پیشنهاد فیلم یا رستوران گرفته تا برجسته کردن ویدیوهای سرگرم‌کننده، موتورهای پیشنهاد که به عنوان توصیه‌گر نیز شناخته می‌شوند، کاربرد بسیار مهمی از یادگیری ماشینی هستند. توصیه‌گرها به شما کمک می‌کنند تا محتوای جذابی را از میان انبوهی از کاندیداها به کاربران خود ارائه دهید. به عنوان مثال، فروشگاه گوگل پلی میلیون‌ها برنامه برای نصب ارائه می‌دهد، در حالی که یوتیوب میلیاردها ویدیو برای تماشا ارائه می‌دهد. و هر روز برنامه‌ها و ویدیوهای بیشتری نیز اضافه می‌شوند.

در این آزمایشگاه کد، شما یاد می‌گیرید که چگونه با استفاده از موارد زیر یک توصیه‌گر فول‌استک بسازید:

  • توصیه‌گرهای TensorFlow برای آموزش بازیابی و مدل رتبه‌بندی برای توصیه‌های فیلم
  • TensorFlow برای خدمت به مدل‌ها خدمت می‌کند
  • فلاتر برای ایجاد یک برنامه چند پلتفرمی برای نمایش فیلم‌های پیشنهادی

پیش‌نیازها

  • دانش پایه توسعه Flutter با Dart
  • دانش پایه در مورد یادگیری ماشین با TensorFlow، مانند آموزش در مقابل استقرار
  • آشنایی اولیه با سیستم‌های توصیه‌گر
  • آشنایی اولیه با پایتون، ترمینال‌ها و داکر

آنچه یاد خواهید گرفت

  • نحوه آموزش مدل‌های بازیابی و رتبه‌بندی با استفاده از TensorFlow Recommenders
  • نحوه ارائه مدل‌های توصیه آموزش‌دیده با استفاده از TensorFlow Serving
  • نحوه ساخت یک برنامه چند پلتفرمی Flutter برای نمایش موارد پیشنهادی

آنچه نیاز دارید

۲. محیط توسعه فلاتر خود را تنظیم کنید

برای توسعه فلاتر، به دو نرم‌افزار برای تکمیل این آزمایشگاه کد نیاز دارید - SDK فلاتر و یک ویرایشگر .

شما می‌توانید رابط کاربری codelab را با استفاده از هر یک از این دستگاه‌ها اجرا کنید:

  • شبیه‌ساز iOS (نیاز به نصب ابزارهای Xcode دارد).
  • شبیه‌ساز اندروید (نیاز به راه‌اندازی در اندروید استودیو دارد).
  • یک مرورگر (برای اشکال‌زدایی، کروم مورد نیاز است).
  • به عنوان یک برنامه دسکتاپ ویندوز ، لینوکس یا macOS . شما باید روی پلتفرمی که قصد استقرار آن را دارید، توسعه دهید. بنابراین، اگر می‌خواهید یک برنامه دسکتاپ ویندوز توسعه دهید، باید روی ویندوز توسعه دهید تا به زنجیره ساخت مناسب دسترسی داشته باشید. الزامات خاص سیستم عامل وجود دارد که به تفصیل در docs.flutter.dev/desktop پوشش داده شده است.

برای بک‌اند، به موارد زیر نیاز خواهید داشت:

  • یک دستگاه لینوکس یا یک مک مبتنی بر اینتل.

۳. آماده شوید

برای دانلود کد این codelab:

  1. برای این آزمایشگاه کد به مخزن گیت‌هاب بروید.
  2. برای دانلود تمام کدهای این codelab، روی Code > Download zip کلیک کنید.

2cd45599f51fb8a2.png

  1. فایل زیپ دانلود شده را از حالت فشرده خارج کنید تا پوشه ریشه codelabs-main حاوی تمام منابع مورد نیاز شما باز شود.

برای این آزمایشگاه کد، شما فقط به فایل‌های موجود در زیرشاخه tfrs-flutter/ در مخزن نیاز دارید که شامل چندین پوشه است:

  • پوشه‌های step0 تا step5 حاوی کد آغازینی هستند که برای هر مرحله در این آزمایشگاه کد، بر اساس آن کدنویسی می‌کنید.
  • پوشه‌ی finished حاوی کد تکمیل‌شده برای برنامه‌ی نمونه‌ی نهایی است.
  • هر پوشه شامل یک زیرپوشه backend است که شامل کد backend موتور توصیه‌گر و یک زیرپوشه frontend است که شامل کد frontend فلاتر می‌شود.

۴. وابستگی‌های پروژه را دانلود کنید

بک‌اند

ما قصد داریم از Flask برای ایجاد backend خود استفاده کنیم. ترمینال خود را باز کنید و دستور زیر را اجرا کنید:

pip install Flask flask-cors requests numpy

ظاهر (فرانت‌اند)

  1. در VS Code، روی File > Open folder کلیک کنید و سپس پوشه step0 را از کد منبعی که قبلاً دانلود کرده‌اید، انتخاب کنید.
  2. فایل step0/frontend/lib/main.dart را باز کنید. اگر پنجره‌ی VS Code ظاهر شد و از شما خواست بسته‌های مورد نیاز برای برنامه‌ی آغازین را دانلود کنید، روی Get packages کلیک کنید.
  3. اگر این پنجره را نمی‌بینید، ترمینال خود را باز کنید و سپس دستور flutter pub get را در پوشه step0/frontend اجرا کنید.

7ada07c300f166a6.png

۵. مرحله ۰: اجرای برنامه اولیه

  1. فایل step0/frontend/lib/main.dart را در VS Code باز کنید، مطمئن شوید که شبیه‌ساز اندروید یا شبیه‌ساز iOS به درستی تنظیم شده و در نوار وضعیت نمایش داده می‌شود.

برای مثال، وقتی از Pixel 5 با شبیه‌ساز اندروید استفاده می‌کنید، این چیزی است که می‌بینید:

۹۷۶۷۶۴۹۲۳۱۸۹۸۷۹۱.png

این چیزی است که هنگام استفاده از آیفون ۱۳ با شبیه‌ساز iOS می‌بینید:

۹۵۵۲۹e۳a۶۸۲۲۶۸b۲.png

  1. کلیک a19a0c68bc4046e6.png اشکال‌زدایی را شروع کنید .

برنامه را اجرا و بررسی کنید

برنامه باید روی شبیه‌ساز اندروید یا شبیه‌ساز iOS شما اجرا شود. رابط کاربری بسیار سرراست است. یک فیلد متنی وجود دارد که به کاربر اجازه می‌دهد متن را به عنوان شناسه کاربری تایپ کند. برنامه Flutter درخواست پرس‌وجو را به backend ارسال می‌کند که 2 مدل توصیه را اجرا می‌کند و یک لیست رتبه‌بندی شده از توصیه‌های فیلم را برمی‌گرداند. frontend پس از دریافت پاسخ، نتیجه را در UI نمایش می‌دهد.

d21427db9587560f.png73e8272a5ce8dfbc.png

اگر روی «اکنون توصیه کنید» کلیک کنید، هیچ اتفاقی نمی‌افتد زیرا برنامه هنوز نمی‌تواند با backend ارتباط برقرار کند.

۶. مرحله ۱: ایجاد مدل‌های بازیابی و رتبه‌بندی برای موتور پیشنهاد

موتورهای پیشنهاد دهنده در دنیای واقعی اغلب از چندین مرحله تشکیل شده‌اند:

  1. مرحله بازیابی مسئول انتخاب مجموعه‌ای اولیه از صدها نامزد از بین تمام نامزدهای ممکن است. هدف اصلی این مدل، حذف کارآمد تمام نامزدهایی است که کاربر به آنها علاقه‌ای ندارد. از آنجا که مدل بازیابی ممکن است با میلیون‌ها نامزد سروکار داشته باشد، باید از نظر محاسباتی کارآمد باشد.
  2. مرحله رتبه‌بندی، خروجی‌های مدل بازیابی را دریافت کرده و آنها را به گونه‌ای تنظیم می‌کند که بهترین تعداد ممکن از توصیه‌ها را انتخاب کند. وظیفه آن محدود کردن مجموعه مواردی است که کاربر ممکن است به آنها علاقه‌مند باشد و آنها را به فهرستی کوتاه از نامزدهای احتمالی در مرتبه صدها مورد محدود می‌کند.
  3. مرحله پس از رتبه‌بندی به تضمین تنوع، تازگی و انصاف کمک می‌کند و موارد کاندید را در مجموعه‌ای از توصیه‌های مفید در حدود ده‌ها مورد سازماندهی مجدد می‌کند.

70dfc0d7e989164f.png

برای این آزمایشگاه کد، شما یک مدل بازیابی و یک مدل رتبه‌بندی را با استفاده از مجموعه داده محبوب MovieLens آموزش می‌دهید. می‌توانید کد آموزشی زیر را از طریق Colab باز کنید و دستورالعمل‌ها را دنبال کنید:

۷. مرحله ۲: ایجاد بک‌اند موتور توصیه

اکنون که مدل‌های بازیابی و رتبه‌بندی را آموزش داده‌اید، می‌توانید آنها را مستقر کرده و یک backend ایجاد کنید.

شروع سرویس‌دهی TensorFlow

از آنجایی که برای تولید لیست فیلم‌های پیشنهادی باید از هر دو مدل بازیابی و رتبه‌بندی استفاده کنید، هر دوی آنها را همزمان با استفاده از TensorFlow Serving مستقر می‌کنید.

  • در ترمینال خود، به پوشه step2/backend در رایانه خود بروید و 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

داکر ابتدا به طور خودکار تصویر TensorFlow Serving را دانلود می‌کند که یک دقیقه طول می‌کشد. پس از آن، TensorFlow Serving باید شروع شود. گزارش باید مانند این قطعه کد باشد:

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

فلسک یک نقطه پایانی جدید در 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)"
  ]
}

همین! شما با موفقیت یک backend برای پیشنهاد فیلم بر اساس شناسه کاربری ساختید.

۸. مرحله ۳: ایجاد اپلیکیشن Flutter برای اندروید و iOS

بخش مدیریت (backend) آماده است. می‌توانید درخواست‌هایی را برای دریافت پیشنهاد فیلم از برنامه فلاتر به آن ارسال کنید.

برنامه frontend نسبتاً ساده است. فقط یک TextField دارد که شناسه کاربر را دریافت کرده و درخواست را (در تابع recommend() ) به backend که اخیراً ساخته‌اید ارسال می‌کند. پس از دریافت پاسخ، رابط کاربری برنامه، فیلم‌های پیشنهادی را در یک 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,
  }),
);

زمانی که برنامه پاسخ را از backend دریافت کرد، شما رابط کاربری را به‌روزرسانی می‌کنید تا فهرست فیلم‌های پیشنهادی را برای کاربر مشخص‌شده نمایش دهد.

  • این کد را درست زیر کد بالا اضافه کنید:
if (response.statusCode == 200) {
  return List<String>.from(jsonDecode(response.body)['movies']);
} else {
  throw Exception('Error response');
}

اجراش کن

  1. کلیک a19a0c68bc4046e6.png اشکال‌زدایی را شروع کنید و سپس منتظر بارگذاری برنامه باشید.
  2. یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

badb59d8b96959ae.pnga0d2d4020aebfb0a.png

۹. مرحله ۴: اجرای برنامه Flutter روی پلتفرم‌های دسکتاپ

علاوه بر اندروید و iOS، فلاتر از پلتفرم‌های دسکتاپ از جمله لینوکس، مک و ویندوز نیز پشتیبانی می‌کند.

لینوکس

  1. مطمئن شوید که دستگاه هدف روی آن تنظیم شده است 86cba523de82b4f9.png در نوار وضعیت VSCode.
  2. کلیک a19a0c68bc4046e6.png اشکال‌زدایی را شروع کنید و سپس منتظر بارگذاری برنامه باشید.
  3. یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

۲۶۶۵۵۱۴۲۳۱۰۳۳f۱.png

مک

  1. برای مک، باید مجوزهای مناسب را تنظیم کنید زیرا برنامه درخواست‌های HTTP را به backend ارسال می‌کند. برای جزئیات بیشتر، لطفاً به Entitlements و App Sandbox مراجعه کنید.

این کد را به ترتیب به 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. یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

860d523a7ac537e0.png

ویندوز

  1. مطمئن شوید که دستگاه هدف روی آن تنظیم شده است ۹۵۸۷be1bb375bc0f.png در نوار وضعیت VSCode.
  2. کلیک a19a0c68bc4046e6.png اشکال‌زدایی را شروع کنید و سپس منتظر بارگذاری برنامه باشید.
  3. یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

7d77c1e52a5927fc.png

۱۰. مرحله ۵: اجرای برنامه Flutter روی پلتفرم وب

کار دیگری که می‌توانید انجام دهید، اضافه کردن پشتیبانی وب به برنامه Flutter است. به طور پیش‌فرض، پلتفرم وب به طور خودکار برای برنامه‌های Flutter فعال است، بنابراین تنها کاری که باید انجام دهید این است که آن را اجرا کنید.

  1. مطمئن شوید که دستگاه هدف روی آن تنظیم شده است 71db93efa928d15d.png در نوار وضعیت VSCode.
  2. کلیک a19a0c68bc4046e6.png اشکال‌زدایی را شروع کنید و سپس منتظر بمانید تا برنامه در مرورگر کروم بارگذاری شود.
  3. یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

۹۳۷۶e۱e۴۳۲c۱۸bef.png

۱۱. تبریک

شما یک اپلیکیشن فول‌استک برای پیشنهاد فیلم به کاربرانتان ساختید!

اگرچه این برنامه فقط فیلم پیشنهاد می‌دهد، شما گردش کار کلی ساخت یک موتور پیشنهاد قدرتمند را یاد گرفته‌اید و مهارت استفاده از پیشنهادها در یک برنامه Flutter را به دست آورده‌اید. می‌توانید به راحتی آموخته‌های خود را در سناریوهای دیگر (مثلاً تجارت الکترونیک، غذا و ویدیوهای کوتاه) به کار ببرید.

بیشتر بدانید