tensorflow / recommenders

TensorFlow Recommenders is a library for building recommender system models using TensorFlow.
Apache License 2.0
1.82k stars 273 forks source link

[Re-opened][Question] Sequential Ranking Model #508

Open VladLujerdeanu opened 2 years ago

VladLujerdeanu commented 2 years ago

Hello! I am trying to build a recommendation system using tfrs. I managed to build a retrieval model using the Retrieval with Sequential Model tutorial, but I don't know where to go from here. I've tried to build the model ranking model based on the retrieval model but I failed. Now, sorry if it's a dumb question, I'm still learning but, can I build a model of Ranking using the same GRU layer? If yes, can you point me to an example of how should I build such a model or help me with a model that for the Movielens dataset like in the tutorial?

VladLujerdeanu commented 2 years ago

Never mind, I think I got it in the end. If anyone needs it:

class RankingModel(tfrs.Model):

    def __init__(self, query_model, candidate_model):
        super().__init__()
        self.query_model = query_model
        self.candidate_model = candidate_model

        self.ratings = 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)
        ])

        self.task = tfrs.tasks.Ranking(
            loss=tf.keras.losses.MeanSquaredError(),
            metrics=[
                tf.keras.metrics.RootMeanSquaredError()
            ]
        )

    def call(self, features):
        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.ratings(tf.concat([query_embedding, candidate_embedding], axis=1))

    def compute_loss(self, features, training=False):

        ratings = features.pop("context_movie_rating")
        rating_predictions = self(features)      

        return self.task(labels=ratings, predictions=rating_predictions)
patrickorlando commented 2 years ago

Great, @VladLujerdeanu! Thanks for sharing.

VladLujerdeanu commented 2 years ago

Ok. Apparently I was wrong (I think). The models works fine, but only if it uses the same candidate tower for retrieval and ranking, and it needs to be trained for retrieval first for it to work.

If I try to have individual models it prompts me with shape not matching error and I find it really strange.

Why is that and how can I fix it?

datasciyj commented 1 year ago

Hi @VladLujerdeanu,

Did you happen to solve this issue? I also have same error saying ValueError: Shape must be rank 3 but is rank 2 for '{{node multi_model_3/concat}} = ConcatV2[N=2, T=DT_FLOAT, Tidx=DT_INT32](multi_model_3/sequential_63/embedding_38/embedding_lookup/Identity_1, multi_model_3/sequential_62/embedding_37/embedding_lookup/Identity_1, multi_model_3/concat/axis)' with input shapes: [?,15,64], [?,64], [].

I didn't get this error for retrieval model and I'm curious how to solve this for the ranking model.

VladLujerdeanu commented 1 year ago

I didn't, I just used the same candidate and query towers from retrieval in the ranking phase. It worked but I don't think it's how it should be solved.