Open kingjosephm opened 1 year ago
You've got a couple of errors in your implementation.
Not indexing the model correctly. index_from_dataset
expects a tuple of (item_id, item_embedding)
.
From the tutorial:
brute_force = tfrs.layers.factorized_top_k.BruteForce(model.user_model)
brute_force.index_from_dataset(
movies.batch(128).map(lambda title: (title, model.movie_model(title)))
)
Applying the query model twice. You passed the query model to the BruteForce layer's init method. https://github.com/tensorflow/recommenders/blob/2ac1483671dc33c0ff1800a4a5f70f7dd20c7471/tensorflow_recommenders/layers/factorized_top_k.py#L504-L517
_, titles = index(model.query_model(user_details)) # <---------
_, titles = index(user_details) # <------ should be this
hope this helps!
Thanks, yeah that was a dumb error on my part. After considerable trial and error I managed to figure out a solution to my problem, but public documentation and helpful examples are really in short supply. For anyone else that struggles to get predictions from the BruteForce
methods with any side features in the candidate tower, here's what I discovered:
Take as input, e.g.:
user_details = {'user': array([b'1'], dtype='|S9'), 'timestamp': array([-58722])}
The following will work, but as explained in the BruteForce
documentation, it returns the indices of the candidate dataset, i.e. the rows in the candidate dataset to which the query user_data
maps to item/product:
index = tfrs.layers.factorized_top_k.BruteForce(model.query_model)
index.index_from_dataset(train_b.map(model.candidate_model))
_, title = index(user_details) # <-- Returns: Tuple(top candidate scores, top candidate identifiers)
The output of title
is, for example:
<tf.Tensor: shape=(1, 10), dtype=int32, numpy=
array([[ 393, 1236, 1998, 2482, 6178, 6649, 6993, 7085, 7195, 9089]],
dtype=int32)>
A better solution is to provide the candidate identifier, not just the candidate embedding:
index = tfrs.layers.factorized_top_k.BruteForce(model.query_model)
index.index_from_dataset(
tf.data.Dataset.zip((train.map(lambda x: x['product']).batch(128), train.batch(128).map(model.candidate_model)))
)
_, title = index(user_details)
Which yields:
<tf.Tensor: shape=(1, 10), dtype=string, numpy=
array([[b'A', b'A', b'A', b'C', b'C', b'A', b'A', b'A', b'C', b'D']], dtype=object)>
You'll notice that many of the predictions are duplicated. This is because train
was fed to construct the BruteForce index, which contains many duplicate instances of each item/product. Unduplicate the data will solve this problem:
# Note - to unduplicate on multiple features in the candidate tower you may be best doing this in Pandas
uniq_products = np.unique(np.concatenate(list(train.batch(1_000).map(lambda x: x['product'])))).astype(str)
uniq_products = tf.data.Dataset.from_tensor_slices({'product': uniq_products})
index = tfrs.layers.factorized_top_k.BruteForce(model.query_model)
index.index_from_dataset(
tf.data.Dataset.zip((uniq_products.map(lambda x: x['product']).batch(128), uniq_products.batch(128).map(model.candidate_model)))
)
_, title = index(user_details)
Which yields:
<tf.Tensor: shape=(1, 10), dtype=string, numpy=
array([[b'A', b'B', b'C', b'D', ...]], dtype=object)>
@kingjosephm Hello, thanks for your sharing I got following error when I run your last code block. Do you know why ?
----> 1 uniq_products = np.unique(np.concatenate(list(user.batch(1_000).map(lambda x: x['product'])))).astype(str) 2 uniq_products = tf.data.Dataset.from_tensor_slices({'product': uniq_products}) 4 index = tfrs.layers.factorized_top_k.BruteForce(model.query_model)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)
Hi,
I'm following the tutorial "Building deep retrieval models" and seem to have encountered a slightly different, though related issue than either this post or this other one on this same tutorial. I'm running into similar issues as this post, though his solution doesn't seem to work for for some reason. Thanks for your help in advance!
The data I'm using are click data from a website, organized like this:
Training data (see below) look like this:
The architecture of the model follows the tutorial, though with some modifications (some portions are omitted for simplification):
This is what
user_details
looks like:Note: both of these commands work
How exactly to implement
factorized_top_k.BruteForce
?Option 1:
Option 2: Seemingly a better approach, builds on this other issue