1. Başlamadan önce
Film veya restoran önerme, eğlenceli videoları öne çıkarma gibi işlevleri olan öneri motorları (diğer adıyla önericiler), makine öğreniminin çok önemli bir uygulamasıdır. Önericiler, çok sayıda aday arasından seçtiğiniz ilgi çekici içerikleri kullanıcılarınıza göstermenize yardımcı olur. Örneğin, Google Play Store'da yüklenebilecek milyonlarca uygulama, YouTube'da ise izlenebilecek milyarlarca video vardır. Her gün daha fazla uygulama ve video eklenir.
Bu codelab'de, aşağıdakileri kullanarak tam yığınlı bir öneri sistemi oluşturmayı öğreneceksiniz:
- Film önerileri için bir alma ve sıralama modeli eğitmek üzere TensorFlow Recommenders
- Modellere hizmet vermek için TensorFlow Serving
- Önerilen filmleri göstermek için platformlar arası uygulama oluşturmak üzere Flutter
Ön koşullar
- Dart ile Flutter geliştirme konusunda temel bilgi
- Eğitim ve dağıtım gibi TensorFlow ile makine öğrenimi hakkında temel bilgiler
- Öneri sistemleri hakkında temel düzeyde bilgi sahibi olma
- Python, terminaller ve Docker hakkında temel bilgiler
Neler öğreneceksiniz?
- TensorFlow Recommenders kullanarak alma ve sıralama modellerini eğitme
- Eğitilmiş öneri modellerini TensorFlow Serving kullanarak sunma
- Önerilen öğeleri göstermek için platformlar arası Flutter uygulaması oluşturma
İhtiyacınız olanlar
- Flutter SDK'sı
- Flutter için Android ve iOS kurulumu
- Flutter için masaüstü kurulumu
- Flutter için web kurulumu
- Flutter ve Dart için Visual Studio Code (VS Code) kurulumu
- Docker
- Bash
- Python 3.7+
- Colab'e erişim
2. Flutter geliştirme ortamınızı kurma
Flutter geliştirme için bu codelab'i tamamlamak üzere iki yazılıma ihtiyacınız vardır: Flutter SDK ve bir düzenleyici.
Codelab'in ön ucunu aşağıdaki cihazlardan herhangi birini kullanarak çalıştırabilirsiniz:
- iOS simülatörü (Xcode araçlarının yüklenmesi gerekir).
- Android Emulator (Android Studio'da kurulum gerektirir).
- Tarayıcı (hata ayıklama için Chrome gereklidir).
- Windows, Linux veya macOS masaüstü uygulaması olarak. Dağıtmayı planladığınız platformda geliştirme yapmanız gerekir. Bu nedenle, bir Windows masaüstü uygulaması geliştirmek istiyorsanız uygun derleme zincirine erişmek için Windows'ta geliştirme yapmanız gerekir. docs.flutter.dev/desktop adresinde ayrıntılı olarak ele alınan işletim sistemine özgü gereksinimler vardır.
Arka uç için gerekenler:
- Linux makine veya Intel tabanlı Mac.
3. Hazırlanın
Bu codelab'in kodunu indirmek için:
- Bu codelab'in GitHub deposuna gidin.
- Bu codelab'in tüm kodunu indirmek için Code > Download zip'i (Kod > Zip dosyasını indir) tıklayın.

- İndirilen ZIP dosyasını açarak ihtiyacınız olan tüm kaynakları içeren bir
codelabs-mainkök klasörü oluşturun.
Bu codelab için depodaki tfrs-flutter/ alt dizinindeki dosyalar yeterlidir. Bu alt dizinde birden fazla klasör bulunur:
step0ilestep5klasörleri, bu codelab'deki her adımda temel alacağınız başlangıç kodunu içerir.finishedklasöründe, tamamlanmış örnek uygulamanın kodu yer alır.- Her klasörde, öneri motoru arka uç kodunu içeren bir
backendalt klasörü ve Flutter ön uç kodunu içeren birfrontendalt klasörü bulunur.
4. Projenin bağımlılıklarını indirme
Arka uç
Arka ucumuzu oluşturmak için Flask'ı kullanacağız. Terminalinizi açıp aşağıdakileri çalıştırın:
pip install Flask flask-cors requests numpy
Ön uç
- VS Code'da File > Open folder'ı (Dosya > Klasörü aç) tıklayın ve daha önce indirdiğiniz kaynak kodundan
step0klasörünü seçin. step0/frontend/lib/main.dartdosyasını açın. Başlangıç uygulaması için gerekli paketleri indirmenizi isteyen bir VS Code iletişim kutusu görürseniz Get packages (Paketleri al) seçeneğini tıklayın.- Bu iletişim kutusunu görmüyorsanız terminalinizi açın ve
flutter pub getkomutunustep0/frontendklasöründe çalıştırın.

5. 0. adım: Başlangıç uygulamasını çalıştırın
- VS Code'da
step0/frontend/lib/main.dartdosyasını açın, Android Emulator veya iOS Simulator'ın doğru şekilde ayarlandığından ve durum çubuğunda göründüğünden emin olun.
Örneğin, Pixel 5'i Android Emulator ile kullandığınızda gördüğünüz ekranı aşağıda bulabilirsiniz:

iOS Simülatörü ile iPhone 13'ü kullandığınızda gördüğünüz ekran:

Hata ayıklamayı başlat'ı tıklayın.
Uygulamayı çalıştırıp keşfetme
Uygulama, Android emülatörünüzde veya iOS simülatörünüzde başlatılmalıdır. Kullanıcı arayüzü oldukça basittir. Kullanıcının kullanıcı kimliği olarak metin yazmasına olanak tanıyan bir metin alanı vardır. Flutter uygulaması, sorgu isteğini arka uca gönderir. Arka uç, 2 öneri modelini çalıştırır ve film önerilerinin sıralanmış bir listesini döndürür. Ön uç, yanıtı aldıktan sonra sonucu kullanıcı arayüzünde gösterir.

Şu anda Öner'i tıklarsanız uygulama henüz arka uçla iletişim kuramadığı için hiçbir şey olmaz.
6. 1. adım: Öneri motoru için alma ve sıralama modellerini oluşturun
Gerçek dünyadaki öneri motorları genellikle birden fazla aşamadan oluşur:
- Alma aşaması, olası tüm adaylar arasından yüzlerce adaydan oluşan bir ilk grubu seçmekten sorumludur. Bu modelin temel amacı, kullanıcının ilgilenmediği tüm adayları verimli bir şekilde elemek. Alma modeli milyonlarca aday ile ilgilenebileceğinden hesaplama açısından verimli olması gerekir.
- Sıralama aşamasında, alma modelinin çıktıları alınır ve mümkün olan en iyi önerileri seçmek için ince ayar yapılır. Bu sistemin görevi, kullanıcının ilgilenebileceği öğeler grubunu yüzlerce öğeden oluşan kısa bir listeye indirmektir.
- Sıralama sonrası aşaması, çeşitliliği, güncelliği ve adilliği sağlamaya yardımcı olur ve aday öğeleri, düzinelerce faydalı öneri olacak şekilde yeniden düzenler.

Bu codelab'de, popüler MovieLens veri kümesini kullanarak bir alma modeli ve bir sıralama modeli eğiteceksiniz. Aşağıdaki eğitim kodunu Colab üzerinden açabilir ve talimatları uygulayabilirsiniz:
7. 2. adım: Öneri motoru arka ucunu oluşturun
Alma ve sıralama modellerini eğittiğinize göre artık bunları dağıtabilir ve bir arka uç oluşturabilirsiniz.
TensorFlow Serving'i başlatma
Önerilen filmler listesini oluşturmak için hem alma hem de sıralama modellerini kullanmanız gerektiğinden, her ikisini de TensorFlow Serving kullanarak aynı anda dağıtırsınız.
- Terminalinizde, bilgisayarınızdaki
step2/backendklasörüne gidin ve Docker ile TensorFlow Serving'i başlatın:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/:/models/" tensorflow/serving --model_config_file=/models/models.config
Docker, önce TensorFlow Serving görüntüsünü otomatik olarak indirir. Bu işlem bir dakika sürer. Ardından TensorFlow Serving başlatılmalıdır. Günlük, aşağıdaki kod snippet'i gibi görünmelidir:
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 ...
Yeni uç nokta oluşturma
TensorFlow Serving, birden fazla sıralı modelin "zincirlenmesini" desteklemediğinden, alma ve sıralama modellerini bağlayan yeni bir hizmet oluşturmanız gerekir.
step2/backend/recommendations.pydosyasındakiget_recommendations()işlevine aşağıdaki kodu ekleyin:
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 hizmetini başlatın
Artık Flask hizmetini başlatabilirsiniz.
- Terminalinizde
step2/backend/klasörüne gidin ve aşağıdakileri çalıştırın:
FLASK_APP=recommender.py FLASK_ENV=development flask run
Flask, http://localhost:5000/recommend adresinde yeni bir uç nokta oluşturur. Günlüğü aşağıdaki gibi görmeniz gerekir:
* 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 -
Beklendiği gibi çalıştığından emin olmak için uç noktaya örnek bir istek gönderebilirsiniz:
curl -X POST -H "Content-Type: application/json" -d '{"user_id":"42"}' http://localhost:5000/recommend
Uç nokta, 42 kullanıcısı için önerilen filmlerin listesini döndürür:
{
"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)"
]
}
İşte bu kadar. User-ID'ye göre film önermek için başarıyla bir arka uç oluşturdunuz.
8. 3. adım: Android ve iOS için Flutter uygulamasını oluşturun
Arka uç hazır. Flutter uygulamasından film önerileri sorgulamak için bu uygulamaya istek göndermeye başlayabilirsiniz.
Ön uç uygulaması oldukça basittir. Yalnızca kullanıcı kimliğini alan ve isteği (recommend() işlevinde) yeni oluşturduğunuz arka uca gönderen bir TextField'a sahiptir. Yanıt alındıktan sonra uygulama kullanıcı arayüzünde önerilen filmler bir ListView'da gösterilir.
step3/frontend/lib/main.dartdosyasındakirecommend()işlevine aşağıdaki kodu ekleyin:
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,
}),
);
Uygulama, arka uçtan yanıtı aldıktan sonra kullanıcı arayüzünü güncelleyerek belirtilen kullanıcı için önerilen filmlerin listesini gösterirsiniz.
- Bu kodu yukarıdaki kodun hemen altına ekleyin:
if (response.statusCode == 200) {
return List<String>.from(jsonDecode(response.body)['movies']);
} else {
throw Exception('Error response');
}
Uygulayın
Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.- Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

9. 4. adım: Flutter uygulamasını masaüstü platformlarında çalıştırın
Android ve iOS'e ek olarak Flutter; Linux, Mac ve Windows gibi masaüstü platformlarını da destekler.
Linux
- Hedef cihazın VSCode'un durum çubuğunda
olarak ayarlandığından emin olun.
Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.- Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

Mac
- Mac'te, uygulama arka uca HTTP istekleri göndereceğinden uygun yetkileri ayarlamanız gerekir. Daha fazla bilgi için lütfen Haklar ve Uygulama Korumalı Alanı başlıklı makaleyi inceleyin.
Bu kodu sırasıyla step4/frontend/macOS/Runner/DebugProfile.entitlements ve step4/frontend/macOS/Runner/Release.entitlements dosyalarına ekleyin:
<key>com.apple.security.network.client</key>
<true/>
- Hedef cihazın VSCode'un durum çubuğunda
olarak ayarlandığından emin olun.
Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.- Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

Windows
- VSCode'un durum çubuğunda hedef cihazın
olarak ayarlandığından emin olun.
Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.- Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

10. 5. adım: Flutter uygulamasını web platformunda çalıştırın
Yapabileceğiniz bir diğer işlem de Flutter uygulamasına web desteği eklemektir. Web platformu, varsayılan olarak Flutter uygulamaları için otomatik olarak etkinleştirilir. Bu nedenle, tek yapmanız gereken platformu başlatmaktır.
- Hedef cihazın VSCode'un durum çubuğunda
olarak ayarlandığından emin olun.
Hata ayıklamayı başlat'ı tıklayın ve uygulamanın Chrome tarayıcıda yüklenmesini bekleyin.- Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

11. Tebrikler
Kullanıcılarınıza film önermek için tam yığın bir uygulama geliştirdiniz.
Uygulama yalnızca film önerse de güçlü bir öneri motoru oluşturmanın genel iş akışını öğrendiniz ve önerileri bir Flutter uygulamasında kullanma becerisini kazandınız. Öğrendiklerinizi diğer senaryolara (ör. e-ticaret, yemek ve kısa videolar) kolayca uygulayabilirsiniz.