tensorflow / tensorflow/recommenders

Please help! Can't get model together

Open
#392 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2k
Forks
300
PR merge metrics
No merged PRs in 30d

Description

I am new to TensorFlow, in fact, I started exploring this library 2-3 weeks ago, because I am doing an internship where my project is a Recommender System.

I could follow all the tutorials available from the TF team and adapt them to my dataset, although, when I try to adapt the models to what I need, I can't manage to do it. I am doing a retail recommender system with features for the users and for the products, I would like to apply the Deep & Cross Network so the model can best learn the influence of each variable on the customers' habits.

I have tried this for these last weeks and can't manage to get it, I am starting to become very desperate, because I have a couple of weeks to finish this project. I have tried to ask for help on several places but I can't get any answer.

I know this is not the type of questions you use to answer but I am really desperate, so I will try my luck.

Here is an example of a code I tried (mixing the DCN tutorial with the DNN):

`class UserModel(tf.keras.Model):

def __init__(self):
    super().__init__()
    
    self.embedding_dimension = 32
    
    self.user_embedding = tf.keras.Sequential([
        tf.keras.layers.StringLookup(
            vocabulary=unique_user_ids, mask_token=None),
        tf.keras.layers.Embedding(len(unique_user_ids) + 1, 32),
    ])
    
    str_features = [
                                        'user_gender'
                                        
    ]
    int_features = [
                                        'timestamp',
                                        'user_age',
                                        'user_lat',
                                        'user_long'
    ]
    
    self._all_features = str_features + int_features
    self._embeddings = {}
    
    # Compute embeddings for string features.
    for feature_name in str_features:
        vocabulary = vocabularies[feature_name]
        self._embeddings[feature_name] = tf.keras.Sequential(
          [tf.keras.layers.experimental.preprocessing.StringLookup(
              vocabulary=vocabulary, mask_token=None),
           tf.keras.layers.Embedding(len(vocabulary) + 1,
                                     self.embedding_dimension)
    ])

    # Compute embeddings for int features.
    for feature_name in int_features:
        vocabulary = vocabularies[feature_name]
        self._embeddings[feature_name] = tf.keras.Sequential(
          [tf.keras.layers.experimental.preprocessing.IntegerLookup(
              vocabulary=vocabulary, mask_token=None),
           tf.keras.layers.Embedding(len(vocabulary) + 1,
                                     self.embedding_dimension)
    ])
def call(self,features):
    # Concatenate embeddings
    embeddings = []
    for feature_name in self._all_features:
        embedding_fn = self._embeddings[feature_name]
        embeddings.append(embedding_fn(features[feature_name]))

    return tf.concat([
        self.user_embedding(features["user_id"]),
        tf.concat(embeddings, axis=1)
    ], axis=1)`

`class QueryModel(tf.keras.Model):
"""Model for encoding user queries."""

def __init__(self, deep_layer_sizes, projection_dim=None):
    """Model for encoding user queries.

    Args:
        layer_sizes:
            A list of integers where the i-th entry represents the number of units
            the i-th layer contains.
    """
    super().__init__()

    # We first use the user model for generating embeddings.
    self.embedding_model = UserModel()

    self._cross_layer = tfrs.layers.dcn.Cross(
        projection_dim=projection_dim,
        kernel_initializer="glorot_uniform")
    
    # Then construct the layers.
    self.dense_layers = tf.keras.Sequential()

    # Use the ReLU activation for all but the last layer.
    self._deep_layers = [tf.keras.layers.Dense(layer_size, activation="relu")
        for layer_size in deep_layer_sizes]

    self._logit_layer = tf.keras.layers.Dense(1)

def call(self, features):
    feature_embedding = self.embedding_model(features)
    return self.dense_layers(feature_embedding)`

`class ProductModel(tf.keras.Model):

def __init__(self):
    super().__init__()
    
    self.product_embedding = tf.keras.Sequential([
        tf.keras.layers.StringLookup(
            vocabulary=unique_product_names,mask_token=None),
    tf.keras.layers.Embedding(len(unique_product_names) + 1, 32)
    ])

    
    str_features = [
                                        'product_colour',
                                        'product_tear',
                                        'product_tonality',
                                        'product_gender',
                                        'product_age',
                                        'product_category',
                                        'product_fit',
                                        'product_rise',
                                        'product_neckline',
                                        'product_sleeve',
                                        'product_denim',
                                        'product_stretch',
                                        'product_wash'
    ]
    
    int_features = [
                                        'price'
    ]
    
    self._all_features = str_features + int_features
    
    self._embeddings = {}
    
    # Compute embeddings for string features.
    for feature_name in str_features:
        vocabulary = vocabularies[feature_name]
        self._embeddings[feature_name] = tf.keras.Sequential(
          [tf.keras.layers.experimental.preprocessing.StringLookup(
              vocabulary=vocabulary, mask_token=None),
           tf.keras.layers.Embedding(len(vocabulary) + 1, 32)
    ])

    # Compute embeddings for int features.
    for feature_name in int_features:
        vocabulary = vocabularies[feature_name]
        self._embeddings[feature_name] = tf.keras.Sequential(
          [tf.keras.layers.experimental.preprocessing.IntegerLookup(
              vocabulary=vocabulary, mask_token=None),
           tf.keras.layers.Embedding(len(vocabulary) + 1, 32)
    ])
def call(self,features):
    # Concatenate embeddings
    embeddings = []
    for feature_name in self._all_features:
        embedding_fn = self._embeddings[feature_name]
        embeddings.append(embedding_fn(features[feature_name]))

    return tf.concat([
        self.product_embedding(features["product_id"]),
        tf.concat(embeddings, axis=1)
    ], axis=1)`

`class CandidateModel(tf.keras.Model):
"""Model for encoding movies."""

def __init__(self, deep_layer_sizes):
    """Model for encoding movies.

    Args:
        layer_sizes:
            A list of integers where the i-th entry represents the number of units
            the i-th layer contains.
    """
    super().__init__()

    self.embedding_model = ProductModel()

    self._cross_layer = tfrs.layers.dcn.Cross(
        projection_dim=None,
        kernel_initializer="glorot_uniform")
    
    # Then construct the layers.
    self.dense_layers = tf.keras.Sequential()

    # Use the ReLU activation for all but the last layer.
    self._deep_layers = [tf.keras.layers.Dense(layer_size, activation="relu")
        for layer_size in deep_layer_sizes]

    self._logit_layer = tf.keras.layers.Dense(1)

def call(self, features):
    feature_embedding = self.embedding_model(features)
    return self.dense_layers(feature_embedding)`

`class MainModel(tfrs.models.Model):

def __init__(self, deep_layer_sizes):
    super().__init__()
    self.query_model = QueryModel(deep_layer_sizes)
    self.candidate_model = CandidateModel(deep_layer_sizes)
    self.task = tfrs.tasks.Retrieval(
        metrics=tfrs.metrics.FactorizedTopK(
            candidates=products.batch(128).map(self.candidate_model),
        ),
    )

def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:
    # We pick out the user features and pass them into the user model.
    user_embeddings = self.query_model(features["user_id"])
    # And pick out the movie features and pass them into the movie model,
    # getting embeddings back.
    product_embeddings = self.candidate_model(features["product_id"])

    # The task computes the loss and the metrics.
    return self.task(user_embeddings, product_embeddings)`

When I try to run this:
`num_epochs = 300

model = MainModel(deep_layer_sizes=[192, 192])
model.compile(optimizer=tf.keras.optimizers.Adagrad(0.1))

one_layer_history = model.fit(
cached_train,
validation_data=cached_test,
validation_freq=5,
epochs=num_epochs,
verbose=0)

accuracy = one_layer_history.history["val_factorized_top_k/top_100_categorical_accuracy"][-1]
print(f"Top-100 accuracy: {accuracy:.2f}.")`

I get this error:
TypeError: Only integers, slices (:), ellipsis (...), tf.newaxis (None) and scalar tf.int32/tf.int64 tensors are valid indices, got 'product_colour'

I don't know why the variables in the Candidate Model are not in the correct format, since I have done the same way on the Query Model. Even if I remove those features from the Product/Candidate Model I get different errors. I have been debuging code for the last 4 days, and every time I find something, I get another error.

And I also tried to embed every single feature manually and I get errors and errors without any sight of hope.

Basically all I want is a DCN Model that I can retrieve recommendations from.

I kindly ask for your help.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the reported training run from the code in the issue, beginning at MainModel.compute_loss and tracing the feature objects passed to QueryModel and CandidateModel. Use the reported product_colour indexing error as the first checkpoint; done would require a clearly specified, working DCN retrieval model, but the issue does not define a repository change or test.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, tensorflow
Domain
machine-learning
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.