Fullstack film öneri sistemi oluşturma

1. Başlamadan önce

Öneri motorları, yani öneri motorları, film veya restoran önermekten eğlenceli videoları öne çıkarmaya kadar makine öğreniminin çok önemli bir uygulamasıdır. Öneri araçları, geniş bir aday havuzundan kullanıcılarınıza ilgi çekici içerikler göstermenize yardımcı olur. Örneğin, Google Play Store yükleyebileceğiniz milyonlarca uygulama sunarken YouTube, izlemeniz için milyarlarca video sunar. Ayrıca her gün daha da fazla uygulama ve video ekleniyor.

Bu codelab'de, aşağıdakileri kullanarak fullstack öneri aracı oluşturmayı öğreneceksiniz:

  • Film önerileri almak için veri alma ve sıralama modelini eğitmek üzere TensorFlow Öneri Araçları
  • Modelleri sunmak için TensorFlow Sunumu
  • Flutter ile platformlar arası uygulama geliştirerek önerilen filmleri göster

Ön koşullar

  • Dart ile Flutter geliştirmeyle ilgili temel bilgiler
  • TensorFlow ile eğitim ve dağıtım gibi temel makine öğrenimi bilgileri
  • Öneri sistemleriyle ilgili temel düzeyde bilgi
  • Python, terminaller ve Docker hakkında temel bilgiler

Neler öğreneceksiniz?

  • TensorFlow Öneri Araçları'nı kullanarak alma ve sıralama modellerini eğitme
  • TensorFlow Sunumu kullanarak eğitilen öneri modellerini sunma
  • Önerilen öğeleri görüntülemek için platformlar arası Flutter uygulaması oluşturma

Gerekenler

2. Flutter geliştirme ortamınızı kurma

Flutter ile geliştirme yaparken bu codelab'i tamamlamak için iki parça yazılıma ihtiyacınız vardır: Flutter SDK'sı ve düzenleyici.

Aşağıdaki cihazlardan birini kullanarak codelab'in ön ucunu çalıştırabilirsiniz:

  • iOS simülatörü (Xcode araçlarının yüklenmesini gerektirir).
  • Android Emülatör (Android Studio'da kurulum gerektirir).
  • Tarayıcı (hata ayıklama için Chrome gereklidir).
  • Windows, Linux veya macOS masaüstü uygulaması olarak Uygulamayı dağıtmayı planladığınız platformda gerçekleştirmeniz gerekir. Bu nedenle, bir Windows masaüstü uygulaması geliştirmek istiyorsanız uygun derleme zincirine erişmek için Windows'da geliştirme yapmanız gerekir. İşletim sistemine özgü gereksinimler docs.flutter.dev/desktop sayfasında ayrıntılı olarak açıklanmıştır.

Arka uç için gerekenler:

  • Linux makinesi veya Intel tabanlı Mac.

3. Hazırlanın

Bu codelab'in kodunu indirmek için:

  1. Bu codelab için GitHub deposuna gidin.
  2. Kod > ZIP dosyasını indir seçeneğini tıklayın.

2cd45599f51fb8a2.png

  1. İhtiyacınız olan tüm kaynakların yer aldığı bir codelabs-main kök klasörünü açmak için, indirilen zip dosyasını açın.

Bu codelab'de yalnızca deponun birden fazla klasör içeren tfrs-flutter/ alt dizininde yer alan dosyalara ihtiyacınız vardır:

  • step0-step5 klasörleri, bu codelab'deki her adımda temel aldığınız başlangıç kodunu içerir.
  • finished klasörü, tamamlanmış örnek uygulama için tamamlanmış kodu içerir.
  • 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. Proje için bağımlılıkları indirme

Arka uç

Arka ucumuzu oluşturmak için Flask'ı kullanacağız. Terminalinizi açıp aşağıdaki komutu çalıştırın:

pip install Flask flask-cors requests numpy

Ön uç

  1. VS Code'da File > (Dosya >) seçeneğini tıklayın. Klasörü aç'ı tıklayın ve ardından daha önce indirdiğiniz kaynak kodundan step0 klasörünü seçin.
  2. step0/frontend/lib/main.dart dosyasını aç. Başlangıç uygulaması için gerekli paketleri indirmenizi isteyen bir VS Kodu iletişim kutusu görürseniz Paketleri al'ı tıklayın.
  3. Bu iletişim kutusunu görmüyorsanız terminalinizi açın ve step0/frontend klasöründe flutter pub get komutunu çalıştırın.

7ada07c300f166a6.png

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

  1. step0/frontend/lib/main.dart dosyasını VS Code'da açın, Android Emülatör veya iOS Simülatörü'nün düzgün şekilde ayarlandığından ve durum çubuğunda göründüğünden emin olun.

Örneğin, Pixel 5'i Android Emülatör ile kullandığınızda şunları görürsünüz:

9767649231898791.png

iPhone 13'ü iOS Simülatörü ile kullandığınızda aşağıdakileri görürsünüz:

95529e3a682268b2.png

  1. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın.

Uygulamayı çalıştırma ve 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 basit. Kullanıcının metni kullanıcı kimliği olarak yazabileceği bir metin alanı vardır. Flutter uygulaması, sorgu isteğini arka uca gönderir. Bu arka uç, 2 öneri modeli çalıştırır ve film önerilerinin sıralı listesini döndürür. Ön uç, yanıtı aldıktan sonra sonucu kullanıcı arayüzünde görüntüler.

d21427db9587560f.png 73e8272a5ce8dfbc.png

Şimdi Öner'i tıklarsanız uygulama henüz arka uçla iletişim kuramadığından hiçbir şey olmaz.

6. 1. Adım: Öneri motoru için alma ve sıralama modelleri oluşturma

Gerçek öneri motorları genellikle birden fazla aşamadan oluşur:

  1. Alma aşamasında, olası tüm adaylar arasından yüzlerce adaydan oluşan ilk kümenin seçilmesi gerekir. Bu modelin temel amacı, kullanıcının ilgilenmediği tüm adayları etkili bir şekilde elemektir. Alma modeli milyonlarca adayla ilgilenebilecek olabileceğinden, hesaplama açısından verimli olması gerekir.
  2. Sıralama aşaması, alma modelinin çıktılarını alır ve olası en iyi birkaç öneriyi seçmek için bu sonuçlara ince ayar yapar. Sistemin görevi, kullanıcının ilgisini çekebilecek öğeleri, yüzlerce olası adaydan oluşan bir kısa liste olacak şekilde daraltmak.
  3. Sıralama sonrası aşaması; çeşitlilik, yenilik ve adalet sağlamaya yardımcı olur ve aday öğeleri onlarca öğeden oluşan bir dizi faydalı öneride yeniden düzenler.

70dfc0d7e989164f.png

Bu codelab'de, popüler MovieLens veri kümesini kullanarak bir alma ve sıralama modeli eğiteceksiniz. Aşağıdaki eğitim kodunu Colab aracılığıyla açıp talimatları uygulayabilirsiniz:

7. 2. Adım: Öneri motoru arka ucunu oluşturun

Alma ve sıralama modellerini eğittiğinize göre bunları dağıtıp arka uç oluşturabilirsiniz.

TensorFlow Sunumunu Başlat

Önerilen film listesini oluşturmak için hem alma hem de sıralama modellerini kullanmanız gerektiğinden TensorFlow Sunumu kullanarak her ikisini de aynı anda dağıtırsınız.

  • Terminalinizde, bilgisayarınızdaki step2/backend klasörüne gidin ve Docker ile TensorFlow Sunumu'nu 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 Sunum görüntüsünü otomatik olarak indirir. Bu işlem bir dakika sürer. Ardından, TensorFlow Sunumu başlar. Günlük, şu 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 Sunumu 'zincirleme'yi desteklemediği için alma ve sıralama modellerini birbirine bağlayan yeni bir hizmet oluşturmanız gerekir.

  • Bu kodu step2/backend/recommendations.py dosyasındaki get_recommendations() işlevine 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şlatma

Artık Flask hizmetini başlatabilirsiniz.

  • Terminalinizde step2/backend/ klasörüne gidip aşağıdaki komutu çalıştırın:
FLASK_APP=recommender.py FLASK_ENV=development flask run

Flask, http://localhost:5000/recommend itibarıyla yeni bir uç nokta üzerinde duracak. Günlük aşağıdaki gibi görünecektir:

 * 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 bir örnek 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 bir 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. Kullanıcı kimliğine dayalı film önerecek bir arka ucu başarıyla oluşturdunuz.

8. 3. adım: Android ve iOS için Flutter uygulamasını oluşturun

Arka uç hazır. Flutter uygulamasından film önerilerini sorgulamak için bu araca istek göndermeye başlayabilirsiniz.

Ön uç uygulaması oldukça basittir. Yalnızca kullanıcı kimliğini alan ve isteği (recommend() işlevinde) az önce oluşturduğunuz arka uca gönderen bir TextField'e sahiptir. Yanıtı aldıktan sonra, uygulamanın kullanıcı arayüzü, önerilen filmleri bir ListView'da görüntüler.

  • Bu kodu step3/frontend/lib/main.dart dosyasındaki recommend() işlevine 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ü, belirtilen kullanıcı için önerilen filmlerin listesini gösterecek şekilde güncellersiniz.

  • 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');
}

Çalıştır

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

badb59d8b96959ae.png a0d2d4020aebfb0a.png

9. 4. Adım: Flutter uygulamasını masaüstü platformlarda çalıştırın

Flutter, Android ve iOS'in yanı sıra Linux, Mac ve Windows gibi masaüstü platformlarını da destekler.

Linux

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

2665514231033f1.png

Mac

  1. Uygulama, HTTP isteklerini arka uca göndereceğinden Mac için uygun yararlanma haklarını ayarlamanız gerekir. Daha fazla bilgi için lütfen Yararlanma Hakları ve Uygulama Korumalı Alanı'nı inceleyin.

Bu kodu sırasıyla step4/frontend/macOS/Runner/DebugProfile.entitlements ve step4/frontend/macOS/Runner/Release.entitlements için ekleyin:

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

7d77c1e52a5927fc.png

10. 5. Adım: Web platformunda Flutter uygulamasını çalıştırın

Yapabileceğiniz bir diğer şey de Flutter uygulamasına web desteği eklemektir. Web platformu varsayılan olarak Flutter uygulamaları için otomatik olarak etkinleştirilir. Dolayısıyla tüm yapmanız gereken bu uygulamayı başlatmaktır.

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

9376e1e432c18bef.png

11. Tebrikler

Kullanıcılarınıza film önermek için bir fullstack uygulaması oluşturdunuz.

Uygulama yalnızca film önerisinde bulunuyor olsa da, güçlü bir öneri motoru oluşturmanın genel iş akışını öğrendiniz ve Flutter uygulamasındaki önerileri kullanmak için gereken beceride uzmanlaştınız. Öğrendiklerinizi başka senaryolara (ör. e-ticaret, yemek ve kısa videolar) kolayca uygulayabilirsiniz.

Daha fazla bilgi