Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
301 views
in Technique[技术] by (71.8m points)

python - InvalidArgumentError: 2 root error(s) found. (0) Invalid argument: indices[10,0] = 101102 is not in [0, 101102)

I am trying to create a movie recommendation system by training the neural collaborative filtering (NCF) network on the MovieLens dataset. My implementation of NCF is

def NCF(num_users, num_items, gmf_embedding_dim, mlp_embedding_dim):
    # Define input vectors for embedding
    u_input = Input(shape = [1,])
    i_input = Input(shape = [1,])

    # GMF embedding
    u_embedding_gmf = Embedding(input_dim = num_users, output_dim = gmf_embedding_dim(u_input)
    u_vec_gmf = Flatten()(u_embedding_gmf)

    i_embedding_gmf = Embedding(input_dim = num_items, output_dim = gmf_embedding_dim(i_input)
    i_vec_gmf = Flatten()(i_embedding_gmf)

    # MLP embedding
    u_embedding_mlp = Embedding(input_dim = num_users, output_dim = mlp_embedding_dim(u_input)
    u_vec_mlp = Flatten()(u_embedding_mlp)

    i_embedding_mlp = Embedding(input_dim = num_items, output_dim = mlp_embedding_dim(i_input)
    i_vec_mlp = Flatten()(i_embedding_mlp)

    # GMF path
    gmf_output = Dot(axes = 1)([u_vec_gmf, i_vec_gmf])

    # MLP path
    mlp_input_concat = Concatenate()([u_vec_mlp, i_vec_mlp])

    mlp_dense_1 = Dense(units = 128, activation = "relu")(mlp_input_concat)
    mlp_bn_1 = BatchNormalization()(mlp_dense_1)
    mlp_drop_1 = Dropout(0.3)(mlp_bn_1)

    mlp_dense_2 = Dense(units = 64, activation = "relu")(mlp_drop_1)
    mlp_bn_2 = BatchNormalization()(mlp_dense_2)
    mlp_output = Dropout(0.3)(mlp_bn_2)

    # Concatenate GMF and MLP pathways
    paths_concat = Concatenate()([gmf_output, mlp_output])

    # Prediction
    output = Dense(units = 1, activation = "sigmoid")(paths_concat)

    # Create model 

    return Model(inputs = [u_input, i_input], outputs = output)

I created a function to handle my training

def train(model, x_train, y_train, x_valid, y_valid, batch_size, epochs, save_name,
         checkpoint_path, history_path, lr = 0.001, lr_decay = True):

    if isfile(join(history_path, save_name)):
        return

    model.compile(loss = BinaryCrossentropy(), optimizer = Adam(learning_rate = lr), 
                 metrics["accuracy"])

    best_checkpoint = ModelCheckpoint(filepath = join(checkpoint_path, save_name),
                                     monitor = "val_loss",
                                     save_best_only = True)

    history_csv = CSVLogger(join(history_path, save_name))

    early_stop = EarlyStopping(monitor = "val_loss",
                              patience = 30,
                              restore_best_weights = True)

    lr_decay_callback = ReduceLROnPlateau(monitor = "val_loss",
                                 patience = 10,
                                 factor = 0.5,
                                 min_lr = 0.000001)

    callback_list = [best_checkpoint, history_csv, early_stop]

    if lr_decay:
        callback_list.append(lr_decay_callback)
    
    model.fit(x = x_train, y = y_train, validation_data = (x_valid, y_valid),
           epochs = epochs, callbacks = callback_list, batch_size = batch_size)

Encoded the user_ID and movie_ID values ready for the embedding layers with

enc = LabelEncoder()
train_set["user_ID"] = enc.fit_transform(train_set["user_ID"].values)
enc = LabelEncoder()
train_set["movie_ID"] = enc.fit_transform(train_set["movie_ID"].values)

enc = LabelEncoder()
valid_set["user_ID"] = enc.fit_transform(valid_set["user_ID"].values)
enc = LabelEncoder()
valid_set["movie_ID"] = enc.fit_transform(valid_set["movie_ID"].values)

enc = LabelEncoder()
test_set["user_ID"] = enc.fit_transform(test_set["user_ID"].values)
enc = LabelEncoder()
test_set["movie_ID"] = enc.fit_transform(test_set["movie_ID"].values)

Then initiated the training with

train(model = NCF(num_users = train_set["user_ID"].nunique() + 1, num_items = 
     train_set["movie_ID"].nunique() + 1, gmf_embedding_dim = 10, mlp_embedding_dim = 10),
     x_train = [train_set["user_ID"], train_set["movie_ID"]], y_train =
     train_set["interaction"],
     x_valid = [valid_set["user_ID"], valid_set["movie_ID"]], y_valid = 
     valid_set["interaction"],
     batch_size = (train_set.shape[0])/10, epochs = 50, save_name = "NCF_1",
     checkpoint_path = "D:/Movie Recommendation System Project/model data/checkpoints",
     history_path = "D:/Movie Recommendation System Project/model data/training history")

The training appeared to go fine until the very last batch of the first epoch, where I received the error:

InvalidArgumentError: 2 root error(s) found.

(0) Invalid argument: indices[10,0] = 101102 is not in [0, 101102) [[node functional_9/embedding_16/embedding_lookup (defined at D:/Movie Recommendation System Project/architecture and training raining_and_evaluation.py:38) ]] [[functional_9/embedding_18/embedding_lookup/_16]]

(1) Invalid argument: indices[10,0] = 101102 is not in [0, 101102) [[node functional_9/embedding_16/embedding_lookup (defined at D:/Movie Recommendation System Project/architecture and training raining_and_evaluation.py:38) ]]

0 successful operations.

0 derived errors ignored. [Op:__inference_test_function_529078]

This was a very similar error to that which I received at the end of my previous attempt, where the value was 101101 instead of 101102. As a naive solution, I tried adding 1 to my values for num_users and num_movies, but now the values in the error message appear to have simply increased by 1. I feel like I am missing something obvious or fundamental about embedding layers here. Could anyone help?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I believe this error occurred as a result of the embedding layer encountering a value that it did not expect. When you are calling the NCF function you are passing the unique number of users of the train set. Instead calculate the unique number of users in the full data set and send it to the NCF function.

For example:

total_num_users = train_set["user_ID"].nunique() + valid_set["user_ID"].nunique() + test_set["user_ID"]..]nunique()

train(model = NCF(num_users = total_num_users, num_items = 
     train_set["movie_ID"].nunique() + 1, gmf_embedding_dim = 10, mlp_embedding_dim = 10),
     x_train = [train_set["user_ID"], train_set["movie_ID"]], y_train =
     train_set["interaction"],
     x_valid = [valid_set["user_ID"], valid_set["movie_ID"]], y_valid = 
     valid_set["interaction"],
     batch_size = (train_set.shape[0])/10, epochs = 50, save_name = "NCF_1",
     checkpoint_path = "D:/Movie Recommendation System Project/model data/checkpoints",
     history_path = "D:/Movie Recommendation System Project/model data/training history")

Make sure to follow the same approach to other categorical variables that you are embedding.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...