Bir sorunuz mu var? TensorFlow Forum Ziyaret Forumunda toplulukla bağlantı kurun

Film önermek: geri çağırma

TensorFlow.org'da görüntüleyin Kaynağı GitHub'da görüntüleyin Defteri indirin

Gerçek dünya tavsiye sistemleri genellikle iki aşamadan oluşur:

  1. Geri alma aşaması, tüm olası adaylardan yüzlerce adayın ilk setini seçmekten sorumludur. Bu modelin temel amacı, kullanıcının ilgilenmediği tüm adayları verimli bir şekilde ayıklamaktır. Geri alma modeli milyonlarca adayla ilgileniyor olabileceğinden, hesaplama açısından verimli olmalıdır.
  2. Sıralama aşaması, geri alma modelinin çıktılarını alır ve bunlara mümkün olan en iyi bir avuç öneriyi seçmek için ince ayar yapar. Görevi, kullanıcının ilgilenebileceği öğeler kümesini olası adaylardan oluşan bir kısa listeye daraltmaktır.

Bu eğitimde, ilk aşama olan geri getirmeye odaklanacağız. Eğer sıralama aşamada ilgilenen varsa, bizim de bakabilirsiniz sıralama öğretici.

Erişim modelleri genellikle iki alt modelden oluşur:

  1. Sorgu özelliklerini kullanarak sorgu temsilini (normalde sabit boyutlu bir gömme vektörü) hesaplayan bir sorgu modeli.
  2. Aday özellikleri kullanarak aday gösterimini (eşit boyutlu bir vektör) hesaplayan bir aday model

İki modelin çıktıları daha sonra bir sorgu adayı yakınlık puanı vermek için birlikte çarpılır ve daha yüksek puanlar, aday ve sorgu arasında daha iyi bir eşleşme olduğunu ifade eder.

Bu eğitimde, Movielens veri kümesini kullanarak böyle iki kuleli bir model oluşturup eğiteceğiz.

Biz gidiyoruz:

  1. Verilerimizi alın ve bir eğitim ve test setine bölün.
  2. Bir geri alma modeli uygulayın.
  3. Sığdırın ve değerlendirin.
  4. Yaklaşık bir en yakın komşular (YSA) endeksi oluşturarak verimli hizmet için dışa aktarın.

Veri kümesi

Movielens veri kümesi, Minnesota Üniversitesi'ndeki GroupLens araştırma grubunun klasik bir veri kümesidir . Filmlere bir dizi kullanıcı tarafından verilen bir dizi derecelendirme içerir ve tavsiye eden sistem araştırmasının iş gücüdür.

Veriler iki şekilde ele alınabilir:

  1. Kullanıcıların hangi filmleri izlediklerini (ve derecelendirdiklerini) ve hangilerini izlemediklerini ifade ettiği şeklinde yorumlanabilir. Bu, kullanıcıların saatlerinin bize hangi şeyleri görmeyi tercih ettiklerini ve hangilerini görmeyi tercih etmediklerini söylediği bir tür örtük geri bildirimdir.
  2. Kullanıcıların izledikleri filmleri ne kadar sevdiklerini ifade etmesi olarak da görülebilir. Bu, açık bir geri bildirim biçimidir: Bir kullanıcının bir filmi izlediği düşünüldüğünde, verdikleri reytinge bakarak kabaca ne kadar beğendiklerini söyleyebiliriz.

Bu eğitimde, bir geri alma sistemine odaklanıyoruz: kullanıcının muhtemelen izleyeceği katalogdan bir dizi filmi tahmin eden bir model. Genellikle, örtük veriler burada daha kullanışlıdır ve bu nedenle Movielens'i örtük bir sistem olarak ele alacağız. Bu, bir kullanıcının izlediği her filmin olumlu bir örnek olduğu ve görmedikleri her filmin örtük bir olumsuz örnek olduğu anlamına gelir.

İthalat

Öncelikle ithalatımızı ortadan kaldıralım.

pip install -q tensorflow-recommenders
pip install -q --upgrade tensorflow-datasets
pip install -q scann
import os
import pprint
import tempfile

from typing import Dict, Text

import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
import tensorflow_recommenders as tfrs

Veri setinin hazırlanması

Önce verilere bir göz atalım.

Tensorflow Veri Kümelerinden MovieLens veri kümesini kullanıyoruz. movielens/100k_ratings tf.data.Dataset , derecelendirme verilerini içeren bir tf.data.Dataset nesnesi verir ve movielens/100k_movies tf.data.Dataset , yalnızca film verilerini içeren bir tf.data.Dataset nesnesi verir.

MovieLens veri kümesinde önceden tanımlanmış bölmeler bulunmadığından, tüm verilerin train bölme altında olduğunu unutmayın.

# Ratings data.
ratings = tfds.load("movielens/100k-ratings", split="train")
# Features of all the available movies.
movies = tfds.load("movielens/100k-movies", split="train")

Derecelendirme veri kümesi, film kimliği, kullanıcı kimliği, atanan derecelendirme, zaman damgası, film bilgileri ve kullanıcı bilgilerinin sözlüğünü döndürür:

for x in ratings.take(1).as_numpy_iterator():
  pprint.pprint(x)
{'bucketized_user_age': 45.0,
 'movie_genres': array([7]),
 'movie_id': b'357',
 'movie_title': b"One Flew Over the Cuckoo's Nest (1975)",
 'raw_user_age': 46.0,
 'timestamp': 879024327,
 'user_gender': True,
 'user_id': b'138',
 'user_occupation_label': 4,
 'user_occupation_text': b'doctor',
 'user_rating': 4.0,
 'user_zip_code': b'53211'}

Filmler veri kümesi, film kimliğini, film başlığını ve ait olduğu türlere ilişkin verileri içerir. Türlerin tamsayı etiketleriyle kodlandığını unutmayın.

for x in movies.take(1).as_numpy_iterator():
  pprint.pprint(x)
{'movie_genres': array([4]),
 'movie_id': b'1681',
 'movie_title': b'You So Crazy (1994)'}

Bu örnekte, derecelendirme verilerine odaklanacağız. Diğer eğitimler, model kalitesini iyileştirmenin yanı sıra film bilgisi verilerinin nasıl kullanılacağını araştırır.

Veri kümesinde yalnızca user_id ve movie_title alanlarını movie_title .

ratings = ratings.map(lambda x: {
    "movie_title": x["movie_title"],
    "user_id": x["user_id"],
})
movies = movies.map(lambda x: x["movie_title"])

Modeli uydurmak ve değerlendirmek için, onu bir eğitim ve değerlendirme setine bölmemiz gerekir. Bir endüstriyel tavsiye sisteminde, bu büyük olasılıkla zamana göre yapılır: $ T $ zamanına kadarki veriler, $ T $ sonrasındaki etkileşimleri tahmin etmek için kullanılır.

Ancak bu basit örnekte, puanların% 80'ini tren setine ve% 20'sini test setine koyarak rastgele bir bölme kullanalım.

tf.random.set_seed(42)
shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)

train = shuffled.take(80_000)
test = shuffled.skip(80_000).take(20_000)

Ayrıca verilerde bulunan benzersiz kullanıcı kimliklerini ve film başlıklarını da bulalım.

Bu önemlidir, çünkü kategorik özelliklerimizin ham değerlerini modellerimizdeki vektörleri gömmekle eşleştirebilmeliyiz. Bunu yapmak için, ham bir özellik değerini bitişik bir aralıktaki bir tam sayıya eşleyen bir sözlüğe ihtiyacımız var: bu, gömme tablolarımızdaki karşılık gelen yerleştirmeleri aramamıza olanak tanır.

movie_titles = movies.batch(1_000)
user_ids = ratings.batch(1_000_000).map(lambda x: x["user_id"])

unique_movie_titles = np.unique(np.concatenate(list(movie_titles)))
unique_user_ids = np.unique(np.concatenate(list(user_ids)))

unique_movie_titles[:10]
array([b"'Til There Was You (1997)", b'1-900 (1994)',
       b'101 Dalmatians (1996)', b'12 Angry Men (1957)', b'187 (1997)',
       b'2 Days in the Valley (1996)',
       b'20,000 Leagues Under the Sea (1954)',
       b'2001: A Space Odyssey (1968)',
       b'3 Ninjas: High Noon At Mega Mountain (1998)',
       b'39 Steps, The (1935)'], dtype=object)

Bir model uygulamak

Modelimizin mimarisini seçmek, modellemenin önemli bir parçasıdır.

İki kuleli bir geri alma modeli inşa ettiğimiz için, her kuleyi ayrı ayrı inşa edebilir ve ardından bunları son modelde birleştirebiliriz.

Sorgu kulesi

Sorgu kulesi ile başlayalım.

İlk adım, sorgunun boyutuna ve aday temsillerine karar vermektir:

embedding_dimension = 32

Daha yüksek değerler, daha doğru olabilecek modellere karşılık gelecektir, ancak aynı zamanda daha yavaş sığacak ve fazla uydurmaya daha yatkın olacaktır.

İkincisi, modelin kendisini tanımlamaktır. Burada, önce kullanıcı kimliklerini tam sayılara dönüştürmek için Keras ön işleme katmanlarını kullanacağız ve ardından bunları bir Embedding katmanı aracılığıyla kullanıcı yerleştirmelerine dönüştüreceğiz. Daha önce hesapladığımız benzersiz kullanıcı kimlikleri listesini bir sözlük olarak kullandığımıza dikkat edin:

user_model = tf.keras.Sequential([
  tf.keras.layers.experimental.preprocessing.StringLookup(
      vocabulary=unique_user_ids, mask_token=None),
  # We add an additional embedding to account for unknown tokens.
  tf.keras.layers.Embedding(len(unique_user_ids) + 1, embedding_dimension)
])

Bunun gibi basit bir model, klasik bir matris çarpanlara ayırma yaklaşımına tam olarak karşılık gelir. Bu basit model için bir tf.keras.Model alt sınıfını tanımlamak aşırı olabilir, sonunda bir embedding_dimension -wide çıktı döndürdüğümüz sürece, standart Keras bileşenlerini kullanarak onu rastgele karmaşık bir modele kolayca genişletebiliriz.

Aday kule

Aday kule için de aynısını yapabiliriz.

movie_model = tf.keras.Sequential([
  tf.keras.layers.experimental.preprocessing.StringLookup(
      vocabulary=unique_movie_titles, mask_token=None),
  tf.keras.layers.Embedding(len(unique_movie_titles) + 1, embedding_dimension)
])

Metrikler

Eğitim verilerimizde pozitif (kullanıcı, film) çiftlerimiz var. Modelimizin ne kadar iyi olduğunu bulmak için, modelin bu çift için hesapladığı yakınlık puanını diğer tüm olası adayların puanlarıyla karşılaştırmamız gerekir: pozitif çiftin puanı diğer tüm adaylardan daha yüksekse, modelimiz son derece doğru.

Bunu yapmak için tfrs.metrics.FactorizedTopK metriğini kullanabiliriz. Metriğin gerekli bir argümanı vardır: değerlendirme için örtük negatifler olarak kullanılan adayların veri kümesi.

Bizim durumumuzda, film modelimiz aracılığıyla düğünlere dönüştürülen movies veri kümesidir:

metrics = tfrs.metrics.FactorizedTopK(
  candidates=movies.batch(128).map(movie_model)
)

Zarar

Bir sonraki bileşen, modelimizi eğitmek için kullanılan kayıptır. TFRS'nin bunu kolaylaştırmak için birkaç kayıp katmanı ve görevi vardır.

Bu durumda, Retrieval görev nesnesini kullanacağız: kayıp fonksiyonunu ve metrik hesaplamayı bir araya getiren kullanışlı bir sarmalayıcı:

task = tfrs.tasks.Retrieval(
  metrics=metrics
)

Görevin kendisi, sorguyu ve aday yerleştirmelerini bağımsız değişken olarak alan ve hesaplanan kaybı döndüren bir Keras katmanıdır: bunu modelin eğitim döngüsünü uygulamak için kullanacağız.

Tam model

Artık hepsini bir model haline getirebiliriz. TFRS, model oluşturma sürecini kolaylaştıran bir temel model sınıfını ( tfrs.models.Model ) ortaya koyar: Yapmamız gereken tek şey, __init__ yönteminde bileşenleri ayarlamak ve ham özellikleri alarak ve bir kayıp değeri döndürerek compute_loss yöntemini uygulamaktır. .

Temel model daha sonra modelimize uyacak uygun eğitim döngüsünü oluşturmaya özen gösterecektir.

class MovielensModel(tfrs.Model):

  def __init__(self, user_model, movie_model):
    super().__init__()
    self.movie_model: tf.keras.Model = movie_model
    self.user_model: tf.keras.Model = user_model
    self.task: tf.keras.layers.Layer = task

  def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:
    # We pick out the user features and pass them into the user model.
    user_embeddings = self.user_model(features["user_id"])
    # And pick out the movie features and pass them into the movie model,
    # getting embeddings back.
    positive_movie_embeddings = self.movie_model(features["movie_title"])

    # The task computes the loss and the metrics.
    return self.task(user_embeddings, positive_movie_embeddings)

tfrs.Model temel sınıfı, basit bir kolaylık sınıfıdır: aynı yöntemi kullanarak hem eğitimi hem de test kayıplarını hesaplamamıza olanak tanır.

Kaputun altında, hala sade bir Keras modeli. tf.keras.Model miras tf.keras.Model ve train_step ve test_step işlevlerini geçersiz kılarak aynı işlevselliği elde edebilirsiniz (ayrıntılar için kılavuza bakın):

class NoBaseClassMovielensModel(tf.keras.Model):

  def __init__(self, user_model, movie_model):
    super().__init__()
    self.movie_model: tf.keras.Model = movie_model
    self.user_model: tf.keras.Model = user_model
    self.task: tf.keras.layers.Layer = task

  def train_step(self, features: Dict[Text, tf.Tensor]) -> tf.Tensor:

    # Set up a gradient tape to record gradients.
    with tf.GradientTape() as tape:

      # Loss computation.
      user_embeddings = self.user_model(features["user_id"])
      positive_movie_embeddings = self.movie_model(features["movie_title"])
      loss = self.task(user_embeddings, positive_movie_embeddings)

      # Handle regularization losses as well.
      regularization_loss = sum(self.losses)

      total_loss = loss + regularization_loss

    gradients = tape.gradient(total_loss, self.trainable_variables)
    self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))

    metrics = {metric.name: metric.result() for metric in self.metrics}
    metrics["loss"] = loss
    metrics["regularization_loss"] = regularization_loss
    metrics["total_loss"] = total_loss

    return metrics

  def test_step(self, features: Dict[Text, tf.Tensor]) -> tf.Tensor:

    # Loss computation.
    user_embeddings = self.user_model(features["user_id"])
    positive_movie_embeddings = self.movie_model(features["movie_title"])
    loss = self.task(user_embeddings, positive_movie_embeddings)

    # Handle regularization losses as well.
    regularization_loss = sum(self.losses)

    total_loss = loss + regularization_loss

    metrics = {metric.name: metric.result() for metric in self.metrics}
    metrics["loss"] = loss
    metrics["regularization_loss"] = regularization_loss
    metrics["total_loss"] = total_loss

    return metrics

Bununla birlikte, bu eğitimlerde, modellemeye odaklanmak ve tfrs.Model kısmını soyutlamak için tfrs.Model temel sınıfını kullanmaya devam ediyoruz.

Uydurma ve değerlendirme

Modeli tanımladıktan sonra, modeli uydurmak ve değerlendirmek için standart Keras uydurma ve değerlendirme rutinlerini kullanabiliriz.

İlk önce modeli somutlaştıralım.

model = MovielensModel(user_model, movie_model)
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))

Ardından eğitim ve değerlendirme verilerini karıştırın, toplu olarak işleyin ve önbelleğe alın.

cached_train = train.shuffle(100_000).batch(8192).cache()
cached_test = test.batch(4096).cache()

Ardından modeli eğitin:

model.fit(cached_train, epochs=3)
Epoch 1/3
10/10 [==============================] - 5s 298ms/step - factorized_top_k/top_1_categorical_accuracy: 1.6250e-04 - factorized_top_k/top_5_categorical_accuracy: 0.0029 - factorized_top_k/top_10_categorical_accuracy: 0.0082 - factorized_top_k/top_50_categorical_accuracy: 0.0680 - factorized_top_k/top_100_categorical_accuracy: 0.1419 - loss: 69885.1072 - regularization_loss: 0.0000e+00 - total_loss: 69885.1072
Epoch 2/3
10/10 [==============================] - 3s 289ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0020 - factorized_top_k/top_5_categorical_accuracy: 0.0150 - factorized_top_k/top_10_categorical_accuracy: 0.0315 - factorized_top_k/top_50_categorical_accuracy: 0.1565 - factorized_top_k/top_100_categorical_accuracy: 0.2807 - loss: 67523.3700 - regularization_loss: 0.0000e+00 - total_loss: 67523.3700
Epoch 3/3
10/10 [==============================] - 3s 278ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0029 - factorized_top_k/top_5_categorical_accuracy: 0.0211 - factorized_top_k/top_10_categorical_accuracy: 0.0437 - factorized_top_k/top_50_categorical_accuracy: 0.1842 - factorized_top_k/top_100_categorical_accuracy: 0.3126 - loss: 66302.9609 - regularization_loss: 0.0000e+00 - total_loss: 66302.9609
<tensorflow.python.keras.callbacks.History at 0x7f16a7780898>

Model eğitildikçe, kayıp azalıyor ve bir dizi ilk k geri alma ölçütü güncelleniyor. Bunlar bize gerçek pozitifin tüm aday kümesinden alınan ilk k öğelerde olup olmadığını söyler. Örneğin, 0.2'lik bir ilk 5 kategorik doğruluk ölçüsü bize ortalama olarak gerçek pozitifin, zamanın% 20'sinde alınan ilk 5 öğede olduğunu söyleyecektir.

Bu örnekte, ölçümlerin yanı sıra eğitim sırasında da değerlendirdiğimize dikkat edin. Bu, büyük aday kümelerde oldukça yavaş olabileceğinden, eğitimde metrik hesaplamayı kapatmak ve yalnızca değerlendirmede çalıştırmak akıllıca olabilir.

Son olarak modelimizi test seti üzerinde değerlendirebiliriz:

model.evaluate(cached_test, return_dict=True)
5/5 [==============================] - 1s 164ms/step - factorized_top_k/top_1_categorical_accuracy: 9.0000e-04 - factorized_top_k/top_5_categorical_accuracy: 0.0099 - factorized_top_k/top_10_categorical_accuracy: 0.0221 - factorized_top_k/top_50_categorical_accuracy: 0.1248 - factorized_top_k/top_100_categorical_accuracy: 0.2327 - loss: 31079.0628 - regularization_loss: 0.0000e+00 - total_loss: 31079.0628
{'factorized_top_k/top_1_categorical_accuracy': 0.0008999999845400453,
 'factorized_top_k/top_5_categorical_accuracy': 0.009850000031292439,
 'factorized_top_k/top_10_categorical_accuracy': 0.022050000727176666,
 'factorized_top_k/top_50_categorical_accuracy': 0.12475000321865082,
 'factorized_top_k/top_100_categorical_accuracy': 0.23274999856948853,
 'loss': 28244.76953125,
 'regularization_loss': 0,
 'total_loss': 28244.76953125}

Test seti performansı, eğitim performansından çok daha kötüdür. Bu, iki faktöre bağlıdır:

  1. Modelimiz, sırf ezberleyebildiği için gördüğü veriler üzerinde muhtemelen daha iyi performans gösterecektir. Bu aşırı uyum fenomeni, modellerin birçok parametresi olduğunda özellikle güçlüdür. Modelin görünmeyen verilere daha iyi genelleştirmesine yardımcı olan model düzenlenmesi ve kullanıcı ve film özelliklerinin kullanılmasıyla aracılık edilebilir.
  2. Model, bazı kullanıcıların halihazırda izlemiş olduğu filmleri yeniden tavsiye ediyor. Bilinen bu pozitif saatler, test filmlerini en iyi K önerilerinin dışında bırakabilir.

İkinci fenomen, daha önce görülen filmleri test önerilerinin dışında bırakarak çözülebilir. Bu yaklaşım, öneri sistemleri literatüründe nispeten yaygındır, ancak bu eğitimlerde onu takip etmiyoruz. Geçmiş saatleri önermemek önemliyse, uygun şekilde belirlenmiş modellerin bu davranışı geçmiş kullanıcı geçmişinden ve bağlamsal bilgilerden otomatik olarak öğrenmesini beklemeliyiz. Ek olarak, aynı öğeyi birden çok kez tavsiye etmek genellikle uygundur (örneğin, her zaman yeşil olan bir TV dizisi veya düzenli olarak satın alınan bir öğe).

Tahmin yapmak

Artık bir modelimiz olduğuna göre tahminlerde bulunmak istiyoruz. Bunu yapmak için tfrs.layers.factorized_top_k.BruteForce katmanını kullanabiliriz.

# Create a model that takes in raw query features, and
index = tfrs.layers.factorized_top_k.BruteForce(model.user_model)
# recommends movies out of the entire movies dataset.
index.index(movies.batch(100).map(model.movie_model), movies)

# Get recommendations.
_, titles = index(tf.constant(["42"]))
print(f"Recommendations for user 42: {titles[0, :3]}")
Recommendations for user 42: [b'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

Tabii ki, BruteForce katmanı, birçok olası adayı olan bir modele hizmet etmek için çok yavaş olacak. Aşağıdaki bölümler, yaklaşık bir geri alma indeksi kullanarak bunun nasıl hızlandırılacağını göstermektedir.

Model sunumu

Model eğitildikten sonra, onu konuşlandırmanın bir yoluna ihtiyacımız var.

İki kuleli bir geri alma modelinde, hizmetin iki bileşeni vardır:

  • Sorgunun özelliklerini alan ve bunları bir sorgu yerleştirmeye dönüştüren bir hizmet sorgu modeli ve
  • hizmet veren bir aday model. Bu, çoğunlukla, sorgu modeli tarafından üretilen bir sorguya yanıt olarak adayların hızlı yaklaşık aramasına izin veren yaklaşık bir en yakın komşular (YSA) indeksi biçimini alır.

TFRS'de, her iki bileşen de tek bir dışa aktarılabilir model halinde paketlenebilir, bu da bize ham kullanıcı kimliğini alan ve o kullanıcı için en iyi filmlerin başlıklarını döndüren bir model verir. Bu, modeli bir SavedModel biçimine dışa aktararak yapılır ve bu, TensorFlow Sunumu kullanılarak sunulmayı mümkün kılar.

Bunun gibi bir modeli dağıtmak için yukarıda oluşturduğumuz BruteForce katmanını dışa BruteForce :

# Export the query model.
with tempfile.TemporaryDirectory() as tmp:
  path = os.path.join(tmp, "model")

  # Save the index.
  index.save(path)

  # Load it back; can also be done in TensorFlow Serving.
  loaded = tf.keras.models.load_model(path)

  # Pass a user id in, get top predicted movie titles back.
  scores, titles = loaded(["42"])

  print(f"Recommendations: {titles[0][:3]}")
WARNING:absl:Found untraced functions such as query_with_exclusions while saving (showing 1 of 1). These functions will not be directly callable after loading.
WARNING:absl:Found untraced functions such as query_with_exclusions while saving (showing 1 of 1). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: /tmp/tmpedp1pofu/model/assets
INFO:tensorflow:Assets written to: /tmp/tmpedp1pofu/model/assets
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.
Recommendations: [b'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

Tahminleri hızlandırmak için yaklaşık bir geri alma endeksi de dışa aktarabiliriz. Bu, on milyonlarca adayın önerilerini verimli bir şekilde ortaya çıkarmayı mümkün kılacaktır.

Bunu yapmak için scann paketini kullanabiliriz. Bu, isteğe bağlı bir TFRS bağımlılığıdır ve bu öğreticinin başında !pip install -q scann çağırarak ayrı olarak !pip install -q scann .

Kurulduktan sonra TFRS ScaNN katmanını kullanabiliriz:

scann_index = tfrs.layers.factorized_top_k.ScaNN(model.user_model)
scann_index.index(movies.batch(100).map(model.movie_model), movies)
<tensorflow_recommenders.layers.factorized_top_k.ScaNN at 0x7f16c1480400>

Bu katman yaklaşık aramalar gerçekleştirecektir: bu, geri almayı biraz daha az doğru hale getirir, ancak büyük aday kümelerde büyüklük sıraları daha hızlıdır.

# Get recommendations.
_, titles = scann_index(tf.constant(["42"]))
print(f"Recommendations for user 42: {titles[0, :3]}")
Recommendations for user 42: [b'Sleepless in Seattle (1993)' b'Father of the Bride Part II (1995)'
 b'Hunchback of Notre Dame, The (1996)']

Sunum için dışa aktarmak, BruteForce katmanını dışa aktarmak kadar kolaydır:

# Export the query model.
with tempfile.TemporaryDirectory() as tmp:
  path = os.path.join(tmp, "model")

  # Save the index.
  scann_index.save(
      path,
      options=tf.saved_model.SaveOptions(namespace_whitelist=["Scann"])
  )

  # Load it back; can also be done in TensorFlow Serving.
  loaded = tf.keras.models.load_model(path)

  # Pass a user id in, get top predicted movie titles back.
  scores, titles = loaded(["42"])

  print(f"Recommendations: {titles[0][:3]}")
WARNING:absl:Found untraced functions such as query_with_exclusions while saving (showing 1 of 1). These functions will not be directly callable after loading.
WARNING:absl:Found untraced functions such as query_with_exclusions while saving (showing 1 of 1). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: /tmp/tmprglhaqg1/model/assets
INFO:tensorflow:Assets written to: /tmp/tmprglhaqg1/model/assets
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.
Recommendations: [b'Sleepless in Seattle (1993)' b'Father of the Bride Part II (1995)'
 b'Hunchback of Notre Dame, The (1996)']

Hızlı yaklaşık geri alma modellerini kullanma ve ayarlama hakkında daha fazla bilgi edinmek için verimli sunum eğitimimize bir göz atın.

Sonraki adımlar

Bu, geri alma öğreticisini sonlandırır.

Burada sunulanları genişletmek için şunlara bir göz atın:

  1. Çoklu görev modellerini öğrenme: derecelendirmeler ve tıklamalar için birlikte optimize etme.
  2. Film meta verilerini kullanma: Soğuk başlangıcı hafifletmek için daha karmaşık bir film modeli oluşturma.