Tensorflow tf.keras.layers.Embedding |类型错误:元组索引必须是整数或切片,而不是 str

问题描述 投票:0回答:1

我正在尝试按照本指南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)')

我一直在调试代码。我需要找出我的代码中有什么问题。

python tensorflow embedding
1个回答
0
投票

您遇到的错误表明将功能传递给 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)

请尝试上面的代码更改。

© www.soinside.com 2019 - 2024. All rights reserved.