我正在尝试按照本指南https://www.tensorflow.org/recommenders/examples/listwise_ranking在形状(userId:str,game_title:str, rating:int)的数据集上应用tensorflow_recommenders。
dataset = tf.data.Dataset.from_tensor_slices( {"userId":tf.cast(df_reviews['variable'], dtype=tf.string),
"game_title":tf.cast(df_reviews['Game'], dtype=tf.string),
"rating":tf.cast(df_reviews['value'], dtype=tf.int32) } )
#breakpoint()
# Mapeo los valores
ratings = dataset.map(lambda x: {
"game_title": x["game_title"],
"user_id": x["userId"],
"user_rating": x["rating"]
})
games = games.map(lambda x: x["Game"])
games = games.map(lambda x: x["Game"])
unique_game_titles = np.unique(np.concatenate(list(games.batch(1000))))
unique_user_ids = np.unique(np.concatenate(list(ratings.batch(1_000).map(
lambda x: x["user_id"]))))
#breakpoint()
# Split between train and tests sets, as before.
shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)
train = shuffled.take(80_000)
test = shuffled.skip(80_000).take(20_000)
class RankingModel(tfrs.Model):
def __init__(self):
super().__init__()
embedding_dimension = 32
# Compute embeddings for users.
self.user_embeddings = tf.keras.Sequential([
tf.keras.layers.StringLookup(
vocabulary=unique_user_ids),
tf.keras.layers.Embedding(len(unique_user_ids) + 1, embedding_dimension)
])
# Compute embeddings for games.
self.game_embeddings = tf.keras.Sequential([
tf.keras.layers.StringLookup(
vocabulary=unique_game_titles),
tf.keras.layers.Embedding(len(unique_game_titles) + 1, embedding_dimension)
])
# Compute predictions.
self.score_model = tf.keras.Sequential([
# Learn multiple dense layers.
tf.keras.layers.Dense(256, activation="relu"),
tf.keras.layers.Dense(64, activation="relu"),
# Make rating predictions in the final layer.
tf.keras.layers.Dense(1)
])
def call(self, features):
# We first convert the id features into embeddings.
# User embeddings are a [batch_size, embedding_dim] tensor.
user_embeddings = self.user_embeddings(features["user_id"])
# tensor.
game_embeddings = self.game_embeddings(features["game_title"])
concatenated_embeddings = tf.concat(
[user_embeddings, game_embeddings], axis=1)
return self.score_model(concatenated_embeddings)
class RetailModel(tfrs.models.Model):
def __init__(self):
super().__init__()
self.ranking_model: tf.keras.Model = RankingModel()
self.task: tf.keras.layers.Layer = tfrs.tasks.Ranking(
loss = tf.keras.losses.MeanSquaredError(),
metrics=[tf.keras.metrics.RootMeanSquaredError()]
)
def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:
rating_predictions = self.ranking_model(
(features["user_id"], features["game_title"]))
# The task computes the loss and the metrics.
return self.task(labels=features["user_rating"], predictions=rating_predictions)
然后我调用类 RetailModel() 并像这样安装cached_train:
epochs = 10
model = RetailModel()
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.5))
cached_train = train.shuffle(100_000).batch(8192).cache()
cached_test = test.batch(4096).cache()
model.fit(cached_train, epochs=epochs)
model.evaluate(cached_test, return_dict=True)
这将返回以下错误:
Traceback (most recent call last):
File "...\SistemasRecomendacion\recsys.py", line 173, in <module>
model.fit(cached_train, epochs=epochs)
File "...\venv\Lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "...\Temp\__autograph_generated_filelfxb7pdg.py", line 15, in tf__train_function
retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
^^^^^
File "...\venv\Lib\site-packages\tensorflow_recommenders\models\base.py", line 68, in train_step
loss = self.compute_loss(inputs, training=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\SistemasRecomendacion\recsys.py", line 154, in compute_loss
rating_predictions = self.ranking_model(
^^^^^^^^^^^^^^^^^^^
File "...\Temp\__autograph_generated_file67974ek5.py", line 10, in tf__call
user_embeddings = ag__.converted_call(ag__.ld(self).user_embeddings, (ag__.ld(features)['user_id'],), None, fscope)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^
TypeError: in user code:
File "...\venv\Lib\site-packages\keras\src\engine\training.py", line 1401, in train_function *
return step_function(self, iterator)
File "...\venv\Lib\site-packages\keras\src\engine\training.py", line 1384, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "...\venv\Lib\site-packages\keras\src\engine\training.py", line 1373, in run_step **
outputs = model.train_step(data)
File "...\venv\Lib\site-packages\tensorflow_recommenders\models\base.py", line
68, in train_step
loss = self.compute_loss(inputs, training=True)
File "...\SistemasRecomendacion\recsys.py", line 154, in compute_loss
rating_predictions = self.ranking_model(
File "...\venv\Lib\site-packages\keras\src\utils\traceback_utils.py", line 70,
in error_handler
raise e.with_traceback(filtered_tb) from None
File "...\Temp\__autograph_generated_file67974ek5.py", line 10, in tf__call
user_embeddings = ag__.converted_call(ag__.ld(self).user_embeddings, (ag__.ld(features)['user_id'],), None, fscope)
TypeError: Exception encountered when calling layer 'ranking_model' (type RankingModel).
in user code:
File "...\SistemasRecomendacion\recsys.py", line 123, in call *
user_embeddings = self.user_embeddings(features["user_id"])
TypeError: tuple indices must be integers or slices, not str
Call arguments received by layer 'ranking_model' (type RankingModel):
• features=('tf.Tensor(shape=(None,), dtype=string)', 'tf.Tensor(shape=(None,), dtype=string)')
我一直在调试代码。我需要找出我的代码中有什么问题。
您遇到的错误表明将功能传递给 RankingModel 时出现问题。当您尝试将 user_id 和 game_title 功能作为元组传递,但您的模型需要字典时,就会发生错误。 这是将特征作为字典传递给 RankingModel 的正确方法。
更新了 RetailModel 中的compute_loss方法
def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:
rating_predictions = self.ranking_model({
"user_id": features["user_id"],
"game_title": features["game_title"]
})
# The task computes the loss and the metrics
return self.task(labels=features["user_rating"], predictions=rating_predictions)
请尝试上面的代码更改。