Fullstack film öneri sistemi oluşturma

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

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:

  1. Bu codelab'in GitHub deposuna gidin.
  2. Bu codelab'in tüm kodunu indirmek için Code > Download zip'i (Kod > Zip dosyasını indir) tıklayın.

2cd45599f51fb8a2.png

  1. İndirilen ZIP dosyasını açarak ihtiyacınız olan tüm kaynakları içeren bir codelabs-main kök klasörü oluşturun.

Bu codelab için depodaki tfrs-flutter/ alt dizinindeki dosyalar yeterlidir. Bu alt dizinde birden fazla klasör bulunur:

  • step0 ile step5 klasörleri, bu codelab'deki her adımda temel alacağınız başlangıç kodunu içerir.
  • finished klasöründe, tamamlanmış örnek uygulamanın kodu yer alır.
  • Her klasörde, öneri motoru arka uç kodunu içeren bir backend alt klasörü ve Flutter ön uç kodunu içeren bir frontend alt 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ç

  1. VS Code'da File > Open folder'ı (Dosya > Klasörü aç) tıklayın ve daha önce indirdiğiniz kaynak kodundan step0 klasörünü seçin.
  2. step0/frontend/lib/main.dart dosyası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.
  3. Bu iletişim kutusunu görmüyorsanız terminalinizi açın ve flutter pub get komutunu step0/frontend klasöründe çalıştırın.

7ada07c300f166a6.png

5. 0. adım: Başlangıç uygulamasını çalıştırın

  1. VS Code'da step0/frontend/lib/main.dart dosyası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:

9767649231898791.png

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

95529e3a682268b2.png

  1. a19a0c68bc4046e6.png 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.

d21427db9587560f.png 73e8272a5ce8dfbc.png

Ş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:

  1. 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.
  2. 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.
  3. 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.

70dfc0d7e989164f.png

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/backend klasö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.py dosyasındaki get_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.dart dosyasındaki recommend() 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

  1. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.
  2. Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

badb59d8b96959ae.png a0d2d4020aebfb0a.png

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

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

2665514231033f1.png

Mac

  1. 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/>
  1. Hedef cihazın VSCode'un durum çubuğunda eb4b0b5563824138.png olarak ayarlandığından emin olun.
  2. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.
  3. Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

860d523a7ac537e0.png

Windows

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

7d77c1e52a5927fc.png

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.

  1. Hedef cihazın VSCode'un durum çubuğunda 71db93efa928d15d.png olarak ayarlandığından emin olun.
  2. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın ve uygulamanın Chrome tarayıcıda yüklenmesini bekleyin.
  3. Kullanıcı kimliği girin (ör. 42) ve ardından Öner'i seçin.

9376e1e432c18bef.png

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.

Daha fazla bilgi