ดูบน TensorFlow.org | ทำงานใน Google Colab | ดูแหล่งที่มาบน GitHub | ดาวน์โหลดโน๊ตบุ๊ค |
ในบทช่วยสอนนี้ เราจะสร้างแบบจำลองการดึงข้อมูลตามลำดับ คำแนะนำตามลำดับคือโมเดลยอดนิยมที่พิจารณาลำดับของรายการที่ผู้ใช้โต้ตอบกับก่อนหน้านี้ แล้วคาดการณ์รายการถัดไป ลำดับของรายการภายในแต่ละลำดับมีความสำคัญ เราจะใช้โครงข่ายประสาทเทียมที่เกิดซ้ำเพื่อสร้างแบบจำลองความสัมพันธ์ตามลำดับ สำหรับรายละเอียดเพิ่มเติมโปรดดูที่นี้ กระดาษ GRU4Rec
นำเข้า
ขั้นแรก ให้เอาการพึ่งพาและการนำเข้าของเราออกไปให้พ้นทาง
pip install -q tensorflow-recommenders
pip install -q --upgrade tensorflow-datasets
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
กำลังเตรียมชุดข้อมูล
ต่อไป เราต้องเตรียมชุดข้อมูลของเรา เราจะใช้ประโยชน์จาก ยูทิลิตี้รุ่นข้อมูล ในเรื่องนี้ บนอุปกรณ์ตรวจสอบการอ้างอิงคำแนะนำ TensorFlow Lite
ข้อมูล MovieLens 1M มี ratings.dat (คอลัมน์: UserID, MovieID, คะแนน, Timestamp) และ movies.dat (คอลัมน์: MovieID, ชื่อ, ประเภท) สคริปต์การสร้างตัวอย่างดาวน์โหลดชุดข้อมูล 1M นำทั้งสองไฟล์ รักษาเรตติ้งให้สูงกว่า 2 เท่านั้น สร้างไทม์ไลน์การโต้ตอบกับภาพยนตร์ของผู้ใช้ กิจกรรมตัวอย่างเป็นป้ายกำกับ และกิจกรรมของผู้ใช้ก่อนหน้า 10 รายการเป็นบริบทสำหรับการคาดคะเน
wget -nc https://raw.githubusercontent.com/tensorflow/examples/master/lite/examples/recommendation/ml/data/example_generation_movielens.py
python -m example_generation_movielens --data_dir=data/raw --output_dir=data/examples --min_timeline_length=3 --max_context_length=10 --max_context_movie_genre_length=10 --min_rating=2 --train_data_fraction=0.9 --build_vocabs=False
--2021-12-02 12:10:29-- https://raw.githubusercontent.com/tensorflow/examples/master/lite/examples/recommendation/ml/data/example_generation_movielens.py Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.111.133, ... Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 18040 (18K) [text/plain] Saving to: ‘example_generation_movielens.py’ example_generation_ 100%[===================>] 17.62K --.-KB/s in 0s 2021-12-02 12:10:29 (107 MB/s) - ‘example_generation_movielens.py’ saved [18040/18040] I1202 12:10:32.036267 140629273970496 example_generation_movielens.py:460] Downloading and extracting data. Downloading data from http://files.grouplens.org/datasets/movielens/ml-1m.zip 5922816/5917549 [==============================] - 1s 0us/step 5931008/5917549 [==============================] - 1s 0us/step I1202 12:10:33.549675 140629273970496 example_generation_movielens.py:406] Reading data to dataframes. /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/pandas/util/_decorators.py:311: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'. return func(*args, **kwargs) I1202 12:10:37.734699 140629273970496 example_generation_movielens.py:408] Generating movie rating user timelines. I1202 12:10:40.836473 140629273970496 example_generation_movielens.py:410] Generating train and test examples. 6040/6040 [==============================] - 76s 13ms/step I1202 12:11:57.162662 140629273970496 example_generation_movielens.py:421] Writing generated training examples. 844195/844195 [==============================] - 14s 17us/step I1202 12:12:11.266682 140629273970496 example_generation_movielens.py:424] Writing generated testing examples. 93799/93799 [==============================] - 2s 17us/step I1202 12:12:22.758407 140629273970496 example_generation_movielens.py:473] Generated dataset: {'train_size': 844195, 'test_size': 93799, 'train_file': 'data/examples/train_movielens_1m.tfrecord', 'test_file': 'data/examples/test_movielens_1m.tfrecord'}
นี่คือตัวอย่างชุดข้อมูลที่สร้างขึ้น
0 : {
features: {
feature: {
key : "context_movie_id"
value: { int64_list: { value: [ 1124, 2240, 3251, ..., 1268 ] } }
}
feature: {
key : "context_movie_rating"
value: { float_list: {value: [ 3.0, 3.0, 4.0, ..., 3.0 ] } }
}
feature: {
key : "context_movie_year"
value: { int64_list: { value: [ 1981, 1980, 1985, ..., 1990 ] } }
}
feature: {
key : "context_movie_genre"
value: { bytes_list: { value: [ "Drama", "Drama", "Mystery", ..., "UNK" ] } }
}
feature: {
key : "label_movie_id"
value: { int64_list: { value: [ 3252 ] } }
}
}
}
คุณจะเห็นว่ามีลำดับของรหัสภาพยนตร์ตามบริบท และรหัสภาพยนตร์ที่มีป้ายกำกับ (ภาพยนตร์ถัดไป) รวมถึงคุณลักษณะบริบท เช่น ปีของภาพยนตร์ การจัดเรต และประเภท
ในกรณีของเรา เราจะใช้เฉพาะลำดับของ ID ภาพยนตร์ตามบริบทและ ID ภาพยนตร์ที่มีป้ายกำกับเท่านั้น คุณสามารถอ้างถึง บริบทใช้ประโยชน์จากคุณสมบัติการกวดวิชา ที่จะเรียนรู้เพิ่มเติมเกี่ยวกับการเพิ่มคุณสมบัติบริบทเพิ่มเติม
train_filename = "./data/examples/train_movielens_1m.tfrecord"
train = tf.data.TFRecordDataset(train_filename)
test_filename = "./data/examples/test_movielens_1m.tfrecord"
test = tf.data.TFRecordDataset(test_filename)
feature_description = {
'context_movie_id': tf.io.FixedLenFeature([10], tf.int64, default_value=np.repeat(0, 10)),
'context_movie_rating': tf.io.FixedLenFeature([10], tf.float32, default_value=np.repeat(0, 10)),
'context_movie_year': tf.io.FixedLenFeature([10], tf.int64, default_value=np.repeat(1980, 10)),
'context_movie_genre': tf.io.FixedLenFeature([10], tf.string, default_value=np.repeat("Drama", 10)),
'label_movie_id': tf.io.FixedLenFeature([1], tf.int64, default_value=0),
}
def _parse_function(example_proto):
return tf.io.parse_single_example(example_proto, feature_description)
train_ds = train.map(_parse_function).map(lambda x: {
"context_movie_id": tf.strings.as_string(x["context_movie_id"]),
"label_movie_id": tf.strings.as_string(x["label_movie_id"])
})
test_ds = test.map(_parse_function).map(lambda x: {
"context_movie_id": tf.strings.as_string(x["context_movie_id"]),
"label_movie_id": tf.strings.as_string(x["label_movie_id"])
})
for x in train_ds.take(1).as_numpy_iterator():
pprint.pprint(x)
{'context_movie_id': array([b'2589', b'202', b'1038', b'1767', b'951', b'129', b'1256', b'955', b'3097', b'3462'], dtype=object), 'label_movie_id': array([b'3629'], dtype=object)}
ตอนนี้ชุดข้อมูลการฝึกอบรม/ทดสอบของเรารวมเฉพาะลำดับของ ID ภาพยนตร์ในอดีตและป้ายกำกับของ ID ภาพยนตร์ถัดไป โปรดทราบว่าเราจะใช้ [10]
เป็นรูปร่างของคุณลักษณะในช่วง tf.Example แยกเพราะเราระบุ 10 รวมความยาวของบริบทที่มีคุณสมบัติในขั้นตอนตัวอย่าง generateion
เราต้องการอีกสิ่งหนึ่งก่อนที่เราจะเริ่มสร้างแบบจำลอง - คำศัพท์สำหรับ ID ภาพยนตร์ของเรา
movies = tfds.load("movielens/1m-movies", split='train')
movies = movies.map(lambda x: x["movie_id"])
movie_ids = movies.batch(1_000)
unique_movie_ids = np.unique(np.concatenate(list(movie_ids)))
การใช้แบบจำลองตามลำดับ
ในบ้านเรา กวดวิชาดึงพื้นฐาน เราจะใช้หอแบบสอบถามหนึ่งสำหรับผู้ใช้และการดึงผู้สมัครสำหรับภาพยนตร์ผู้สมัคร อย่างไรก็ตาม สถาปัตยกรรมสองหอคอยมีลักษณะทั่วไปและไม่ จำกัด เฉพาะ
ที่นี่เราจะยังคงใช้สถาปัตยกรรมสองหอคอย specificially เราจะใช้หอแบบสอบถามที่มี รั้วรอบขอบชิดกำเริบ Unit (GRU) ชั้น การเข้ารหัสลำดับของภาพยนตร์ประวัติศาสตร์และให้หอผู้สมัครเหมือนกันสำหรับภาพยนตร์ผู้สมัคร
embedding_dimension = 32
query_model = tf.keras.Sequential([
tf.keras.layers.StringLookup(
vocabulary=unique_movie_ids, mask_token=None),
tf.keras.layers.Embedding(len(unique_movie_ids) + 1, embedding_dimension),
tf.keras.layers.GRU(embedding_dimension),
])
candidate_model = tf.keras.Sequential([
tf.keras.layers.StringLookup(
vocabulary=unique_movie_ids, mask_token=None),
tf.keras.layers.Embedding(len(unique_movie_ids) + 1, embedding_dimension)
])
ตัวชี้วัด งาน และแบบจำลองทั้งหมดถูกกำหนดให้คล้ายกับแบบจำลองการดึงข้อมูลพื้นฐาน
metrics = tfrs.metrics.FactorizedTopK(
candidates=movies.batch(128).map(candidate_model)
)
task = tfrs.tasks.Retrieval(
metrics=metrics
)
class Model(tfrs.Model):
def __init__(self, query_model, candidate_model):
super().__init__()
self._query_model = query_model
self._candidate_model = candidate_model
self._task = task
def compute_loss(self, features, training=False):
watch_history = features["context_movie_id"]
watch_next_label = features["label_movie_id"]
query_embedding = self._query_model(watch_history)
candidate_embedding = self._candidate_model(watch_next_label)
return self._task(query_embedding, candidate_embedding, compute_metrics=not training)
การติดตั้งและการประเมิน
ตอนนี้ เราสามารถคอมไพล์ ฝึกฝน และประเมินโมเดลการดึงข้อมูลตามลำดับของเราได้
model = Model(query_model, candidate_model)
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))
cached_train = train_ds.shuffle(10_000).batch(12800).cache()
cached_test = test_ds.batch(2560).cache()
model.fit(cached_train, epochs=3)
Epoch 1/3 67/67 [==============================] - 25s 291ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_5_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_10_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_50_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_100_categorical_accuracy: 0.0000e+00 - loss: 107448.4467 - regularization_loss: 0.0000e+00 - total_loss: 107448.4467 Epoch 2/3 67/67 [==============================] - 2s 25ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_5_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_10_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_50_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_100_categorical_accuracy: 0.0000e+00 - loss: 100932.0125 - regularization_loss: 0.0000e+00 - total_loss: 100932.0125 Epoch 3/3 67/67 [==============================] - 2s 25ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_5_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_10_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_50_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_100_categorical_accuracy: 0.0000e+00 - loss: 99336.2015 - regularization_loss: 0.0000e+00 - total_loss: 99336.2015 <keras.callbacks.History at 0x7f0904d5b410>
model.evaluate(cached_test, return_dict=True)
37/37 [==============================] - 10s 235ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0146 - factorized_top_k/top_5_categorical_accuracy: 0.0780 - factorized_top_k/top_10_categorical_accuracy: 0.1358 - factorized_top_k/top_50_categorical_accuracy: 0.3735 - factorized_top_k/top_100_categorical_accuracy: 0.5058 - loss: 15478.0652 - regularization_loss: 0.0000e+00 - total_loss: 15478.0652 {'factorized_top_k/top_1_categorical_accuracy': 0.014605699107050896, 'factorized_top_k/top_5_categorical_accuracy': 0.07804987579584122, 'factorized_top_k/top_10_categorical_accuracy': 0.1358330100774765, 'factorized_top_k/top_50_categorical_accuracy': 0.3735221028327942, 'factorized_top_k/top_100_categorical_accuracy': 0.5058262944221497, 'loss': 9413.1240234375, 'regularization_loss': 0, 'total_loss': 9413.1240234375}
นี้สรุปบทช่วยสอนการดึงข้อมูลตามลำดับ