فیلم های پیشنهادی: بازیابی

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

سیستم های توصیه گر دنیای واقعی اغلب از دو مرحله تشکیل شده اند:

  1. مرحله بازیابی مسئولیت انتخاب مجموعه اولیه صدها نامزد از بین همه نامزدهای احتمالی است. هدف اصلی این مدل از بین بردن کارآمد همه نامزدهایی است که کاربر به آنها علاقه ای ندارد. از آنجایی که مدل بازیابی ممکن است با میلیون ها نامزد سر و کار داشته باشد، باید از نظر محاسباتی کارآمد باشد.
  2. مرحله رتبه‌بندی خروجی‌های مدل بازیابی را می‌گیرد و آنها را برای انتخاب بهترین توصیه‌های ممکن تنظیم می‌کند. وظیفه آن محدود کردن مجموعه مواردی است که کاربر ممکن است به آنها علاقه مند باشد به لیست کوتاهی از نامزدهای احتمالی.

در این آموزش، ما بر روی مرحله اول، بازیابی تمرکز می کنیم. اگر شما در مرحله رتبه بندی علاقه مند، یک نگاهی به ما رتبه بندی آموزش.

مدل های بازیابی اغلب از دو مدل فرعی تشکیل شده اند:

  1. یک مدل پرس و جو که نمایش پرس و جو را محاسبه می کند (معمولاً یک بردار تعبیه شده با ابعاد ثابت) با استفاده از ویژگی های پرس و جو.
  2. یک مدل کاندید که نمایش نامزد (بردار با اندازه یکسان) را با استفاده از ویژگی‌های کاندید محاسبه می‌کند

سپس خروجی‌های دو مدل با هم ضرب می‌شوند تا یک امتیاز وابستگی پرس و جو به کاندید ارائه شود، با نمرات بالاتر که تطابق بهتری را بین داوطلب و پرس و جو بیان می‌کند.

در این آموزش، ما قصد داریم چنین مدل دو برجی را با استفاده از مجموعه داده Movielens بسازیم و آموزش دهیم.

ما قصد داریم به:

  1. داده های ما را دریافت کنید و آن ها را به یک مجموعه آموزشی و آزمایشی تقسیم کنید.
  2. پیاده سازی یک مدل بازیابی
  3. مناسب و ارزیابی کنید.
  4. با ایجاد یک شاخص تقریبی نزدیکترین همسایگان (ANN) آن را برای ارائه خدمات کارآمد صادر کنید.

مجموعه داده

Movielens است مجموعه داده یک مجموعه داده های کلاسیک را از GroupLens گروه تحقیقاتی در دانشگاه مینه سوتا است. این شامل مجموعه‌ای از رتبه‌بندی‌هایی است که توسط مجموعه‌ای از کاربران به فیلم‌ها داده می‌شود و مجموعه‌ای از تحقیقات سیستم توصیه‌کننده است.

داده ها را می توان به دو روش درمان کرد:

  1. می توان آن را به عنوان بیانگر فیلم هایی که کاربران تماشا کرده اند (و رتبه بندی کرده اند) و کدام را تماشا نکرده اند تفسیر کرد. این نوعی بازخورد ضمنی است که در آن ساعت‌های کاربران به ما می‌گویند که چه چیزهایی را ترجیح می‌دهند ببینند و چه چیزهایی را ترجیح نمی‌دهند.
  2. همچنین می تواند به عنوان بیانگر میزان علاقه کاربران به فیلم هایی که تماشا کرده اند نیز دیده شود. این یک نوع بازخورد صریح است: با توجه به اینکه کاربر فیلمی را تماشا کرده است، با نگاه کردن به امتیازی که داده است، می‌توانیم به طور تقریبی بفهمیم که چقدر دوست داشته است.

در این آموزش، ما بر روی یک سیستم بازیابی تمرکز می‌کنیم: مدلی که مجموعه‌ای از فیلم‌ها را از کاتالوگ پیش‌بینی می‌کند که کاربر احتمالاً آن‌ها را تماشا خواهد کرد. اغلب، داده های ضمنی در اینجا مفیدتر هستند، بنابراین ما می خواهیم Movielens را به عنوان یک سیستم ضمنی در نظر بگیریم. این بدان معناست که هر فیلمی که کاربر تماشا کرده یک مثال مثبت است و هر فیلمی که ندیده است یک مثال منفی ضمنی است.

واردات

بیایید ابتدا واردات خود را از سر راه برداریم.

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

آماده سازی مجموعه داده

بیایید ابتدا نگاهی به داده ها بیندازیم.

ما با استفاده از مجموعه داده MovieLens از Tensorflow مجموعه داده . در حال بارگذاری movielens/100k_ratings بازده tf.data.Dataset شی حاوی اطلاعات رتبه بندی و بارگیری movielens/100k_movies بازده tf.data.Dataset شی که تنها حاوی داده فیلم.

توجه داشته باشید که پس از MovieLens مجموعه داده انشعابات از قبل تعریف نشده اند، تمام داده ها تحت train تقسیم می شود.

# Ratings data.
ratings = tfds.load("movielens/100k-ratings", split="train")
# Features of all the available movies.
movies = tfds.load("movielens/100k-movies", split="train")
2021-10-02 11:05:34.633747: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected

مجموعه داده رتبه‌بندی فرهنگ لغت شناسه فیلم، شناسه کاربر، رتبه‌بندی اختصاص داده شده، مهر زمانی، اطلاعات فیلم و اطلاعات کاربر را برمی‌گرداند:

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'}
2021-10-02 11:05:35.718641: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

مجموعه داده فیلم ها شامل شناسه فیلم، عنوان فیلم و داده هایی در مورد ژانرهایی است که به آن تعلق دارد. توجه داشته باشید که ژانرها با برچسب های عدد صحیح کدگذاری می شوند.

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)'}
2021-10-02 11:05:35.893098: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

در این مثال، ما بر روی داده های رتبه بندی تمرکز می کنیم. سایر آموزش ها نحوه استفاده از داده های اطلاعات فیلم را نیز برای بهبود کیفیت مدل بررسی می کنند.

ما فقط حفظ user_id و 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"])

برای تناسب و ارزیابی مدل، باید آن را به یک مجموعه آموزشی و ارزیابی تقسیم کنیم. در سیستم پیشنهاد صنعتی، این به احتمال زیاد توسط زمان انجام می شود: داده تا زمان \(T\) می توان برای پیش بینی فعل و انفعالات پس از \(T\).

با این حال، در این مثال ساده، اجازه دهید از یک تقسیم تصادفی استفاده کنیم و 80 درصد رتبه‌بندی‌ها را در مجموعه قطار و 20 درصد را در مجموعه آزمایشی قرار دهیم.

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)

بیایید همچنین شناسه های کاربری منحصر به فرد و عناوین فیلم موجود در داده ها را کشف کنیم.

این مهم است زیرا ما باید بتوانیم مقادیر خام ویژگی‌های طبقه‌بندی خود را به بردارهای تعبیه‌شده در مدل‌هایمان نگاشت کنیم. برای انجام این کار، به واژگانی نیاز داریم که یک مقدار ویژگی خام را به یک عدد صحیح در یک محدوده پیوسته ترسیم کند: این به ما امکان می‌دهد جاسازی‌های مربوطه را در جداول جاسازی خود جستجو کنیم.

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)

پیاده سازی یک مدل

انتخاب معماری مدل ما یک بخش کلیدی از مدل سازی است.

از آنجایی که ما در حال ساخت یک مدل بازیابی دو برج هستیم، می توانیم هر برج را جداگانه بسازیم و سپس آنها را در مدل نهایی ترکیب کنیم.

برج پرس و جو

بیایید با برج پرس و جو شروع کنیم.

اولین گام تصمیم گیری در مورد ابعاد پرس و جو و نمایش نامزد است:

embedding_dimension = 32

مقادیر بالاتر با مدل‌هایی مطابقت دارد که ممکن است دقیق‌تر باشند، اما در عین حال آهسته‌تر برازش می‌شوند و مستعد بیش از حد برازش هستند.

دوم این است که خود مدل را تعریف کنیم. در اینجا، ما قصد استفاده از Keras لایه از پیش پردازش به شناسه کاربری برای اولین بار تبدیل به اعداد صحیح، و سپس تبدیل آن به درونه گیریها کاربر از طریق Embedding لایه. توجه داشته باشید که ما از لیست شناسه های کاربری منحصر به فردی که قبلا محاسبه کرده بودیم به عنوان واژگان استفاده می کنیم:

user_model = tf.keras.Sequential([
  tf.keras.layers.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)
])

یک مدل ساده مثل این مربوط دقیقا به یک کلاسیک فاکتور ماتریس روش است. در حالی که تعریف یک زیر کلاس از tf.keras.Model برای این مدل ساده درد نمیخورد ممکن است، ما می توانیم به راحتی آن را به یک مدل خودسرانه پیچیده گسترش استفاده از تجهیزات Keras، تا زمانی که ما یک بازگشت embedding_dimension خروجی گسترده در پایان.

برج نامزد

ما می توانیم همین کار را با برج کاندید انجام دهیم.

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

معیارهای

در داده های آموزشی ما جفت های مثبت (کاربر، فیلم) داریم. برای اینکه بفهمیم مدل ما چقدر خوب است، باید امتیاز وابستگی را که مدل برای این جفت محاسبه می‌کند با نمرات همه نامزدهای احتمالی دیگر مقایسه کنیم: اگر امتیاز جفت مثبت بالاتر از همه نامزدهای دیگر باشد، مدل ما بسیار دقیق است

برای انجام این کار، ما می توانیم با استفاده از tfrs.metrics.FactorizedTopK متریک. این متریک یک آرگومان لازم دارد: مجموعه داده نامزدها که به عنوان منفی ضمنی برای ارزیابی استفاده می شود.

در مورد ما، که این movies مجموعه داده، تبدیل به درونه گیریها از مدل فیلم های ما:

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

ضرر - زیان

مؤلفه بعدی ضرری است که برای آموزش مدل ما استفاده می شود. TFRS چندین لایه از دست دادن و وظایف برای آسان کردن این کار دارد.

در این مثال، ما استفاده از را Retrieval راحتی لفاف بسته بندی است که بسته نرم افزاری با هم تابع زیان و محاسبات متریک: شی کار:

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

وظیفه خود یک لایه Keras است که پرس و جو و جاسازی های نامزد را به عنوان آرگومان می گیرد و ضرر محاسبه شده را برمی گرداند: ما از آن برای پیاده سازی حلقه آموزشی مدل استفاده خواهیم کرد.

مدل کامل

اکنون می‌توانیم همه آن‌ها را در یک مدل قرار دهیم. TFRS در معرض یک کلاس مدل پایه ( tfrs.models.Model ) که ساده مدل های ساخت و ساز: همه ما نیاز به انجام است به راه اندازی اجزای سازنده در __init__ روش و پیاده سازی compute_loss روش، مصرف در ویژگی های خام و بازگرداندن مقداری از دست دادن .

سپس مدل پایه از ایجاد حلقه آموزشی مناسب متناسب با مدل ما مراقبت خواهد کرد.

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 کلاس پایه یک کلاس به سادگی آسان است، آن را به ما امکان انجام هر دو آموزش و آزمون زیان استفاده از همان روش.

زیر کاپوت هنوز هم مدل کراس ساده است. شما می توانید از قابلیت های مشابه توسط وارث از رسیدن به tf.keras.Model و فارغ از train_step و test_step توابع (نگاه کنید به راهنمای برای جزئیات بیشتر):

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

در این آموزش، با این حال، ما به استفاده از چوب tfrs.Model کلاس پایه برای نگه داشتن تمرکز ما بر روی مدل سازی و انتزاعی دور برخی از تکیهکلامهای.

تناسب و ارزیابی

پس از تعریف مدل، می‌توانیم از روش‌های استاندارد برازش و ارزیابی کراس برای برازش و ارزیابی مدل استفاده کنیم.

بیایید ابتدا مدل را نمونه سازی کنیم.

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

سپس داده‌های آموزش و ارزیابی را به هم بزنید، دسته‌ای و کش کنید.

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

سپس مدل را آموزش دهید:

model.fit(cached_train, epochs=3)
Epoch 1/3
10/10 [==============================] - 6s 302ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0011 - factorized_top_k/top_5_categorical_accuracy: 0.0094 - factorized_top_k/top_10_categorical_accuracy: 0.0203 - factorized_top_k/top_50_categorical_accuracy: 0.1001 - factorized_top_k/top_100_categorical_accuracy: 0.1772 - loss: 69885.1129 - regularization_loss: 0.0000e+00 - total_loss: 69885.1129
Epoch 2/3
10/10 [==============================] - 3s 286ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0029 - factorized_top_k/top_5_categorical_accuracy: 0.0186 - factorized_top_k/top_10_categorical_accuracy: 0.0376 - factorized_top_k/top_50_categorical_accuracy: 0.1689 - factorized_top_k/top_100_categorical_accuracy: 0.2923 - loss: 67523.3707 - regularization_loss: 0.0000e+00 - total_loss: 67523.3707
Epoch 3/3
10/10 [==============================] - 3s 269ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0036 - factorized_top_k/top_5_categorical_accuracy: 0.0224 - factorized_top_k/top_10_categorical_accuracy: 0.0459 - factorized_top_k/top_50_categorical_accuracy: 0.1880 - factorized_top_k/top_100_categorical_accuracy: 0.3162 - loss: 66302.9609 - regularization_loss: 0.0000e+00 - total_loss: 66302.9609
<keras.callbacks.History at 0x7f560e5ea090>

اگر شما می خواهید برای نظارت بر روند آموزش با TensorBoard، شما می توانید مخاطبین TensorBoard به عملکرد مناسب () اضافه کنید و سپس شروع به TensorBoard با استفاده از %tensorboard --logdir logs/fit . لطفا به مستندات TensorBoard برای جزئیات بیشتر.

همانطور که مدل آموزش می بیند، ضرر کاهش می یابد و مجموعه ای از معیارهای بازیابی top-k به روز می شود. اینها به ما می گویند که آیا مثبت واقعی در آیتم های top-k بازیابی شده از کل مجموعه نامزد وجود دارد یا خیر. به عنوان مثال، یک متریک صحت طبقه بندی بالای 5 0.2 به ما می گوید که به طور متوسط، مثبت واقعی در 20٪ مواقع در 5 مورد برتر بازیابی شده است.

توجه داشته باشید که در این مثال، معیارها را در حین آموزش و همچنین ارزیابی ارزیابی می کنیم. از آنجایی که این می‌تواند با مجموعه‌های کاندیدای بزرگ بسیار کند باشد، ممکن است محتاطانه باشد که محاسبه متریک را در آموزش خاموش کنیم و آن را فقط در ارزیابی اجرا کنیم.

در نهایت، می‌توانیم مدل خود را روی مجموعه آزمایشی ارزیابی کنیم:

model.evaluate(cached_test, return_dict=True)
5/5 [==============================] - 2s 149ms/step - factorized_top_k/top_1_categorical_accuracy: 7.5000e-04 - factorized_top_k/top_5_categorical_accuracy: 0.0099 - factorized_top_k/top_10_categorical_accuracy: 0.0226 - factorized_top_k/top_50_categorical_accuracy: 0.1245 - factorized_top_k/top_100_categorical_accuracy: 0.2324 - loss: 31079.0635 - regularization_loss: 0.0000e+00 - total_loss: 31079.0635
{'factorized_top_k/top_1_categorical_accuracy': 0.000750000006519258,
 'factorized_top_k/top_5_categorical_accuracy': 0.009850000031292439,
 'factorized_top_k/top_10_categorical_accuracy': 0.02264999970793724,
 'factorized_top_k/top_50_categorical_accuracy': 0.12449999898672104,
 'factorized_top_k/top_100_categorical_accuracy': 0.23235000669956207,
 'loss': 28244.771484375,
 'regularization_loss': 0,
 'total_loss': 28244.771484375}

عملکرد مجموعه تست بسیار بدتر از عملکرد تمرینی است. این به دو عامل مربوط می شود:

  1. مدل ما احتمالاً روی داده‌هایی که دیده است بهتر عمل می‌کند، فقط به این دلیل که می‌تواند آن‌ها را به خاطر بسپارد. این پدیده اضافه برازش به ویژه زمانی قوی است که مدل ها پارامترهای زیادی داشته باشند. این می تواند با تنظیم مدل و استفاده از ویژگی های کاربر و فیلم که به تعمیم بهتر مدل به داده های دیده نشده کمک می کند، واسطه شود.
  2. این مدل برخی از فیلم‌هایی را که قبلاً تماشا کرده‌اند را مجدداً توصیه می‌کند. این ساعت‌های مثبت شناخته شده می‌توانند فیلم‌های آزمایشی را از بهترین توصیه‌های K حذف کنند.

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

پیشگویی

اکنون که یک مدل داریم، دوست داریم بتوانیم پیش‌بینی کنیم. ما می توانیم با استفاده از tfrs.layers.factorized_top_k.BruteForce لایه برای انجام این کار.

# 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_from_dataset(
  tf.data.Dataset.zip((movies.batch(100), movies.batch(100).map(model.movie_model)))
)

# 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)']

البته، BruteForce لایه است برای رفتن به خیلی آهسته به خدمت یک مدل با بسیاری از نامزدهای امکان پذیر است. بخش‌های زیر نشان می‌دهد که چگونه می‌توان این کار را با استفاده از یک شاخص بازیابی تقریبی سرعت بخشید.

سرویس مدل

پس از آموزش مدل، به راهی برای استقرار آن نیاز داریم.

در مدل بازیابی دو برج، سرویس دهی دارای دو جزء است:

  • یک مدل پرس و جو ارائه دهنده، با در نظر گرفتن ویژگی های پرس و جو و تبدیل آنها به یک جاسازی پرس و جو، و
  • یک مدل کاندیدای خدمت این اغلب به شکل یک شاخص تقریبی نزدیکترین همسایگان (ANN) است که امکان جستجوی تقریبی سریع کاندیداها را در پاسخ به پرس و جوی تولید شده توسط مدل پرس و جو می دهد.

در TFRS، هر دو مؤلفه را می توان در یک مدل واحد صادراتی بسته بندی کرد و مدلی به ما می دهد که شناسه کاربر خام را می گیرد و عناوین فیلم های برتر را برای آن کاربر برمی گرداند. این است از طریق صادرات مدل به انجام SavedModel فرمت، که باعث می شود این امکان را به خدمت با استفاده از TensorFlow خدمت .

به استقرار یک مدل شبیه به این، ما به سادگی صادرات BruteForce لایه که در بالا ایجاد شده:

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

  # Save the index.
  tf.saved_model.save(index, path)

  # Load it back; can also be done in TensorFlow Serving.
  loaded = tf.saved_model.load(path)

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

  print(f"Recommendations: {titles[0][:3]}")
2021-10-02 11:05:54.109254: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
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/tmp7otg6id7/model/assets
INFO:tensorflow:Assets written to: /tmp/tmp7otg6id7/model/assets
Recommendations: [b'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

ما همچنین می توانیم یک شاخص بازیابی تقریبی را برای سرعت بخشیدن به پیش بینی ها صادر کنیم. این امکان ارائه توصیه های کارآمد از مجموعه ده ها میلیون نامزد را فراهم می کند.

برای این کار، ما می توانیم با استفاده از scann بسته. این وابستگی اختیاری TFRS است، و ما آن را به طور جداگانه در ابتدای این آموزش با تماس نصب !pip install -q scann .

پس از نصب ما می توانیم TFRS استفاده ScaNN لایه:

scann_index = tfrs.layers.factorized_top_k.ScaNN(model.user_model)
scann_index.index_from_dataset(
  tf.data.Dataset.zip((movies.batch(100), movies.batch(100).map(model.movie_model)))
)
<tensorflow_recommenders.layers.factorized_top_k.ScaNN at 0x7f560caffc10>

این لایه متغیر تقریبی را انجام دهد: این باعث می شود بازیابی کمی کمتر دقیق است، اما سفارشات از قدر سریع تر در مجموعه های نامزد بزرگ است.

# 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)']

صادرات آن برای خدمت به آسانی به عنوان صادرات BruteForce لایه:

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

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

  # Load it back; can also be done in TensorFlow Serving.
  loaded = tf.saved_model.load(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.
INFO:tensorflow:Assets written to: /tmp/tmp_rde8grm/model/assets
INFO:tensorflow:Assets written to: /tmp/tmp_rde8grm/model/assets
Recommendations: [b'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

برای کسب اطلاعات بیشتر در مورد استفاده از و تنظیم مدل های بازیابی سریع تقریبی، یک نگاهی به ما وعده کارآمد آموزش.

توصیه مورد به مورد

در این مدل یک مدل فیلم کاربر ایجاد کردیم. با این حال، برای برخی از برنامه ها (به عنوان مثال، صفحات جزئیات محصول) انجام توصیه های مورد به مورد (به عنوان مثال، فیلم به فیلم یا محصول به محصول) معمول است.

مدل های آموزشی مانند این از همان الگوی نشان داده شده در این آموزش پیروی می کنند، اما با داده های آموزشی متفاوت. در اینجا ما یک کاربر و یک برج فیلم داشتیم و از جفت (کاربر، فیلم) برای آموزش آنها استفاده کردیم. در یک مدل آیتم به آیتم، ما دو برج آیتم (برای پرس و جو و آیتم کاندید) خواهیم داشت و مدل را با استفاده از جفت (آیتم پرس و جو، آیتم کاندید) آموزش می دهیم. اینها را می توان از کلیک روی صفحات جزئیات محصول ایجاد کرد.

مراحل بعدی

این آموزش بازیابی را به پایان می رساند.

برای گسترش آنچه در اینجا ارائه شده است، به موارد زیر نگاه کنید:

  1. یادگیری مدل های چند وظیفه ای: بهینه سازی مشترک برای رتبه بندی و کلیک ها.
  2. استفاده از ابرداده فیلم: ساخت یک مدل فیلم پیچیده تر برای کاهش شروع سرد.