recommenders icon indicating copy to clipboard operation
recommenders copied to clipboard

[Question] Examples of Retrieval and Ranking Models in a Single Sequential Model?

Open rlcauvin opened this issue 1 year ago • 5 comments

Using TensorFlow Recommenders, we often employ a standard process:

  1. Retrieve candidates using a retrieval model.
  2. "Explode" the retrieval queries and retrieved candidates into query-candidate pairs to be ranked.
  3. Rank candidates using a ranking model.

The examples I've seen treat the retrieval and ranking models as separate and perform these steps in sequence, but "manually". Is it possible to combine the three steps into a single Keras sequential model with the retrieval model as the first layer, an "exploder" as the second layer, and a ranking model as the final layer?

If it is possible, are there examples of implementing it? In particular, I am not sure how we might implement the "exploder" layer.

rlcauvin avatar Jan 31 '24 20:01 rlcauvin

Yes, this should technically be possible. Usually it isn't done because the ranking model contains additional features, often features that required frequent updates.

In terms of cross joining your query and candidate tensors, check out tf.repeat and tf.tile functions.

patrickorlando avatar Jan 31 '24 23:01 patrickorlando

Yes, this should technically be possible. Usually it isn't done because the ranking model contains additional features, often features that required frequent updates.

In terms of cross joining your query and candidate tensors, check out tf.repeat and tf.tile functions.

Thanks. I would love to see an example of using those functions to cross join queries and candidates for ranking.

rlcauvin avatar Feb 09 '24 21:02 rlcauvin

This is the general idea @rlcauvin

import tensorflow as tf

# Define the tensors with shape (3, 1)
tensor1 = tf.constant([['a'], ['b'], ['c']])
tensor2 = tf.constant([['x'], ['y'], ['z']])

# Tile tensor1 to repeat for each element in tensor2
tensor1_tiled = tf.tile(tensor1, [1, 3])  # Now tensor1 is tiled horizontally

# Repeat tensor2 to match the length of tensor1 and reshape to interleave with tensor1
tensor2_repeated = tf.repeat(tensor2, repeats=[3], axis=0)

# Concatenate along the second axis to get the final cross-joined tensor
cross_joined = tf.concat([tensor1_tiled, tensor2_repeated], axis=1)

which would give you

[['a', 'x'],
 ['a', 'y'],
 ['a', 'z'],
 ['b', 'x'],
 ['b', 'y'],
 ['b', 'z'],
 ['c', 'x'],
 ['c', 'y'],
 ['c', 'z']]

Do this with your query and candidate embeddings, then pass to your ranking model.

patrickorlando avatar Feb 20 '24 05:02 patrickorlando

Thanks, @patrickorlando. It looks like there might be some copy-paste problems in that code snippet? Perhaps the reshaping of the two tensors before concatenating them?

rlcauvin avatar Feb 22 '24 16:02 rlcauvin

A small change in the code @patrickorlando provided yields the desired output.

Instead of:

cross_joined = tf.concat([tensor1_tiled, tensor2_repeated], axis=1)

reshape tensor1_tiled before concatenating:

cross_joined = tf.concat([tf.reshape(tensor1_tiled, [-1, 1]), tensor2_repeated], axis=1)

rlcauvin avatar May 06 '24 18:05 rlcauvin