۱. قبل از شروع
از پیشنهاد فیلم یا رستوران گرفته تا برجسته کردن ویدیوهای سرگرمکننده، موتورهای پیشنهاد که به عنوان توصیهگر نیز شناخته میشوند، کاربرد بسیار مهمی از یادگیری ماشینی هستند. توصیهگرها به شما کمک میکنند تا محتوای جذابی را از میان انبوهی از کاندیداها به کاربران خود ارائه دهید. به عنوان مثال، فروشگاه گوگل پلی میلیونها برنامه برای نصب ارائه میدهد، در حالی که یوتیوب میلیاردها ویدیو برای تماشا ارائه میدهد. و هر روز برنامهها و ویدیوهای بیشتری نیز اضافه میشوند.
در این آزمایشگاه کد، شما یاد میگیرید که چگونه با استفاده از موارد زیر یک توصیهگر فولاستک بسازید:
- توصیهگرهای TensorFlow برای آموزش بازیابی و مدل رتبهبندی برای توصیههای فیلم
- TensorFlow برای خدمت به مدلها خدمت میکند
- فلاتر برای ایجاد یک برنامه چند پلتفرمی برای نمایش فیلمهای پیشنهادی
پیشنیازها
- دانش پایه توسعه Flutter با Dart
- دانش پایه در مورد یادگیری ماشین با TensorFlow، مانند آموزش در مقابل استقرار
- آشنایی اولیه با سیستمهای توصیهگر
- آشنایی اولیه با پایتون، ترمینالها و داکر
آنچه یاد خواهید گرفت
- نحوه آموزش مدلهای بازیابی و رتبهبندی با استفاده از TensorFlow Recommenders
- نحوه ارائه مدلهای توصیه آموزشدیده با استفاده از TensorFlow Serving
- نحوه ساخت یک برنامه چند پلتفرمی Flutter برای نمایش موارد پیشنهادی
آنچه نیاز دارید
- کیت توسعه نرمافزار فلاتر
- تنظیمات اندروید و iOS برای Flutter
- تنظیمات دسکتاپ برای فلاتر
- راهاندازی وب برای فلاتر
- تنظیمات ویژوال استودیو کد (VS Code) برای فلاتر و دارت
- داکر
- ضربه شدید
- پایتون ۳.۷+
- دسترسی به کولاب
۲. محیط توسعه فلاتر خود را تنظیم کنید
برای توسعه فلاتر، به دو نرمافزار برای تکمیل این آزمایشگاه کد نیاز دارید - SDK فلاتر و یک ویرایشگر .
شما میتوانید رابط کاربری codelab را با استفاده از هر یک از این دستگاهها اجرا کنید:
- شبیهساز iOS (نیاز به نصب ابزارهای Xcode دارد).
- شبیهساز اندروید (نیاز به راهاندازی در اندروید استودیو دارد).
- یک مرورگر (برای اشکالزدایی، کروم مورد نیاز است).
- به عنوان یک برنامه دسکتاپ ویندوز ، لینوکس یا macOS . شما باید روی پلتفرمی که قصد استقرار آن را دارید، توسعه دهید. بنابراین، اگر میخواهید یک برنامه دسکتاپ ویندوز توسعه دهید، باید روی ویندوز توسعه دهید تا به زنجیره ساخت مناسب دسترسی داشته باشید. الزامات خاص سیستم عامل وجود دارد که به تفصیل در docs.flutter.dev/desktop پوشش داده شده است.
برای بکاند، به موارد زیر نیاز خواهید داشت:
- یک دستگاه لینوکس یا یک مک مبتنی بر اینتل.
۳. آماده شوید
برای دانلود کد این codelab:
- برای این آزمایشگاه کد به مخزن گیتهاب بروید.
- برای دانلود تمام کدهای این codelab، روی Code > Download zip کلیک کنید.

- فایل زیپ دانلود شده را از حالت فشرده خارج کنید تا پوشه ریشه
codelabs-mainحاوی تمام منابع مورد نیاز شما باز شود.
برای این آزمایشگاه کد، شما فقط به فایلهای موجود در زیرشاخه tfrs-flutter/ در مخزن نیاز دارید که شامل چندین پوشه است:
- پوشههای
step0تاstep5حاوی کد آغازینی هستند که برای هر مرحله در این آزمایشگاه کد، بر اساس آن کدنویسی میکنید. - پوشهی
finishedحاوی کد تکمیلشده برای برنامهی نمونهی نهایی است. - هر پوشه شامل یک زیرپوشه
backendاست که شامل کد backend موتور توصیهگر و یک زیرپوشهfrontendاست که شامل کد frontend فلاتر میشود.
۴. وابستگیهای پروژه را دانلود کنید
بکاند
ما قصد داریم از Flask برای ایجاد backend خود استفاده کنیم. ترمینال خود را باز کنید و دستور زیر را اجرا کنید:
pip install Flask flask-cors requests numpy
ظاهر (فرانتاند)
- در VS Code، روی File > Open folder کلیک کنید و سپس پوشه
step0را از کد منبعی که قبلاً دانلود کردهاید، انتخاب کنید. - فایل
step0/frontend/lib/main.dartرا باز کنید. اگر پنجرهی VS Code ظاهر شد و از شما خواست بستههای مورد نیاز برای برنامهی آغازین را دانلود کنید، روی Get packages کلیک کنید. - اگر این پنجره را نمیبینید، ترمینال خود را باز کنید و سپس دستور
flutter pub getرا در پوشهstep0/frontendاجرا کنید.

۵. مرحله ۰: اجرای برنامه اولیه
- فایل
step0/frontend/lib/main.dartرا در VS Code باز کنید، مطمئن شوید که شبیهساز اندروید یا شبیهساز iOS به درستی تنظیم شده و در نوار وضعیت نمایش داده میشود.
برای مثال، وقتی از Pixel 5 با شبیهساز اندروید استفاده میکنید، این چیزی است که میبینید:

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

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


اگر روی «اکنون توصیه کنید» کلیک کنید، هیچ اتفاقی نمیافتد زیرا برنامه هنوز نمیتواند با backend ارتباط برقرار کند.
۶. مرحله ۱: ایجاد مدلهای بازیابی و رتبهبندی برای موتور پیشنهاد
موتورهای پیشنهاد دهنده در دنیای واقعی اغلب از چندین مرحله تشکیل شدهاند:
- مرحله بازیابی مسئول انتخاب مجموعهای اولیه از صدها نامزد از بین تمام نامزدهای ممکن است. هدف اصلی این مدل، حذف کارآمد تمام نامزدهایی است که کاربر به آنها علاقهای ندارد. از آنجا که مدل بازیابی ممکن است با میلیونها نامزد سروکار داشته باشد، باید از نظر محاسباتی کارآمد باشد.
- مرحله رتبهبندی، خروجیهای مدل بازیابی را دریافت کرده و آنها را به گونهای تنظیم میکند که بهترین تعداد ممکن از توصیهها را انتخاب کند. وظیفه آن محدود کردن مجموعه مواردی است که کاربر ممکن است به آنها علاقهمند باشد و آنها را به فهرستی کوتاه از نامزدهای احتمالی در مرتبه صدها مورد محدود میکند.
- مرحله پس از رتبهبندی به تضمین تنوع، تازگی و انصاف کمک میکند و موارد کاندید را در مجموعهای از توصیههای مفید در حدود دهها مورد سازماندهی مجدد میکند.

برای این آزمایشگاه کد، شما یک مدل بازیابی و یک مدل رتبهبندی را با استفاده از مجموعه داده محبوب 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');
}
اجراش کن
- کلیک
اشکالزدایی را شروع کنید و سپس منتظر بارگذاری برنامه باشید. - یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.


۹. مرحله ۴: اجرای برنامه Flutter روی پلتفرمهای دسکتاپ
علاوه بر اندروید و iOS، فلاتر از پلتفرمهای دسکتاپ از جمله لینوکس، مک و ویندوز نیز پشتیبانی میکند.
لینوکس
- مطمئن شوید که دستگاه هدف روی آن تنظیم شده است
در نوار وضعیت VSCode. - کلیک
اشکالزدایی را شروع کنید و سپس منتظر بارگذاری برنامه باشید. - یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

مک
- برای مک، باید مجوزهای مناسب را تنظیم کنید زیرا برنامه درخواستهای 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/>
- مطمئن شوید که دستگاه هدف روی آن تنظیم شده است
در نوار وضعیت VSCode. - کلیک
اشکالزدایی را شروع کنید و سپس منتظر بارگذاری برنامه باشید. - یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

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

۱۰. مرحله ۵: اجرای برنامه Flutter روی پلتفرم وب
کار دیگری که میتوانید انجام دهید، اضافه کردن پشتیبانی وب به برنامه Flutter است. به طور پیشفرض، پلتفرم وب به طور خودکار برای برنامههای Flutter فعال است، بنابراین تنها کاری که باید انجام دهید این است که آن را اجرا کنید.
- مطمئن شوید که دستگاه هدف روی آن تنظیم شده است
در نوار وضعیت VSCode. - کلیک
اشکالزدایی را شروع کنید و سپس منتظر بمانید تا برنامه در مرورگر کروم بارگذاری شود. - یک شناسه کاربری (مثلاً ۴۲) وارد کنید و سپس گزینه «توصیه» را انتخاب کنید.

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