Cross Entropy Collab
from fastai.collab import *
from fastai.tabular.all import *
path = untar_data(URLs.ML_100k)
ratings = pd.read_csv(path/'u.data', delimiter='\t', header=None,
names=['user','movie','rating','timestamp'])
ratings.head()
dblock = DataBlock()
dsets = dblock.datasets(ratings)
x,y = dsets.train[0]
x,y
x['user'], x['movie']
This the data we want to feed
y['rating']
This is our label, the rating
def get_x(rating): return tensor([rating['user']-1, rating['movie']-1]) #Must sub 1 to avoid CUDA error: device-side assert triggered
def get_y(rating): return rating['rating']-1 #Must sub 1 to avoid CUDA error: device-side assert triggered
dblock = DataBlock(get_x=get_x,
get_y=get_y,
splitter=RandomSplitter())
dls = dblock.dataloaders(ratings) #path
class CollabClassification(Module):
def __init__(self, users_sz, movies_sz, n_factors = 100):
self.user_factors = Embedding(*users_sz)
self.movie_factors = Embedding(*movies_sz)
self.layers = nn.Sequential(
nn.Linear(users_sz[1] + movies_sz[1], n_factors),
nn.ReLU(),
nn.Linear(n_factors, 5) #5 output neurons
)
def forward(self, x):
users = self.user_factors(x[:,0])
movies = self.movie_factors(x[:,1])
return self.layers(torch.cat((users, movies), dim=1))
n_users = len(ratings.user.unique())
n_movies = len(ratings.movie.unique())
users_factors = 74 #random
movies_factors = 102 #random
model = CollabClassification((n_users, users_factors), (n_movies, movies_factors)) #our model
learn = Learner(dls, model, loss_func=CrossEntropyLossFlat())
learn.fit_one_cycle(5, 5e-3, wd=0.01)
It didn't perform that well in comparison to the MSE Loss model, but that is to be expected as this problem is not advised to be handled using cross entropy loss.