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