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

1. قبل از شروع

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

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

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

پیش نیازها

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

چیزی که یاد خواهید گرفت

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

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

2. محیط توسعه Flutter خود را تنظیم کنید

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

می‌توانید با استفاده از هر یک از این دستگاه‌ها، قسمت جلوی Codelab را اجرا کنید:

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

برای Backend، شما نیاز دارید:

  • یک ماشین لینوکس یا یک مک مبتنی بر اینتل.

3. راه اندازی شوید

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

  1. به مخزن GitHub برای این Codelab بروید.
  2. روی Code > Download zip کلیک کنید تا همه کدهای این کد لبه را دانلود کنید.

2cd45599f51fb8a2.png

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

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

  • پوشه های step0 تا step5 حاوی کد شروعی است که برای هر مرحله در این کد لبه ایجاد می کنید.
  • پوشه finished حاوی کد تکمیل شده برای برنامه نمونه تمام شده است.
  • هر پوشه حاوی یک زیرپوشه backend است که شامل کد باطن موتور پیشنهادی است و یک زیرپوشه frontend که شامل کد جلویی Flutter است.

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

Backend

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

pip install Flask flask-cors requests numpy

Frontend

  1. در VS Code، روی File > Open folder کلیک کنید و سپس پوشه 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 باز کنید، مطمئن شوید که شبیه ساز اندروید یا شبیه ساز iOS به درستی تنظیم شده و در نوار وضعیت ظاهر می شود.

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

9767649231898791.png

در اینجا چیزی است که هنگام استفاده از iPhone 13 با شبیه ساز iOS مشاهده می کنید:

95529e3a682268b2.png

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

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

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

d21427db9587560f.png73e8272a5ce8dfbc.png

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

6. مرحله 1: مدل های بازیابی و رتبه بندی را برای موتور توصیه ایجاد کنید

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

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

70dfc0d7e989164f.png

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

7. مرحله 2: باطن موتور توصیه را ایجاد کنید

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

سرویس TensorFlow را شروع کنید

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

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

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)"
  ]
}

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

8. مرحله 3: برنامه Flutter را برای اندروید و iOS ایجاد کنید

باطن آماده است. می‌توانید برای درخواست توصیه‌های فیلم از برنامه Flutter درخواست ارسال کنید.

برنامه frontend نسبتا ساده است. فقط یک 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) وارد کنید و سپس Recommend را انتخاب کنید.

badb59d8b96959ae.pnga0d2d4020aebfb0a.png

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

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

لینوکس

  1. مطمئن شوید که دستگاه مورد نظر روی تنظیم شده است 86cba523de82b4f9.png در نوار وضعیت VSCode.
  2. کلیک کنید a19a0c68bc4046e6.png اشکال زدایی را شروع کنید و سپس منتظر بمانید تا برنامه بارگیری شود.
  3. یک شناسه کاربری (یعنی 42) وارد کنید و سپس Recommend را انتخاب کنید.

2665514231033f1.png

مک

  1. برای مک، باید حقوق مناسب را تنظیم کنید زیرا برنامه درخواست‌های 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) وارد کنید و سپس Recommend را انتخاب کنید.

860d523a7ac537e0.png

ویندوز

  1. مطمئن شوید که دستگاه مورد نظر روی تنظیم شده است 9587be1bb375bc0f.png در نوار وضعیت VSCode.
  2. کلیک کنید a19a0c68bc4046e6.png اشکال زدایی را شروع کنید و سپس منتظر بمانید تا برنامه بارگیری شود.
  3. یک شناسه کاربری (یعنی 42) وارد کنید و سپس Recommend را انتخاب کنید.

7d77c1e52a5927fc.png

10. مرحله 5: برنامه Flutter را روی پلتفرم وب اجرا کنید

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

  1. مطمئن شوید که دستگاه مورد نظر روی تنظیم شده است 71db93efa928d15d.png در نوار وضعیت VSCode.
  2. کلیک کنید a19a0c68bc4046e6.png اشکال زدایی را شروع کنید و سپس منتظر بمانید تا برنامه در مرورگر کروم بارگیری شود.
  3. یک شناسه کاربری (یعنی 42) وارد کنید و سپس Recommend را انتخاب کنید.

9376e1e432c18bef.png

11. تبریک می گویم

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

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

بیشتر بدانید