### Part 1 : Archirecture of the AutoEncoder #nn.Module is a parent class # SAE is a child class of the parent class nn.ModuleclassSAE(nn.Module):
# self is the object of the SAE class # Archirecture def__init__(self, ):
# self can use alll the methods of the class nn.Modulesuper(SAE,self).__init__()
# Full connected layer n°1, input and 20 neurons-nodes of the first layer# one neuron can be the genre of the movie# Encode step self.fc1=nn.Linear(nb_movies,20)
# Full connected layer n°2 self.fc2=nn.Linear(20,10)
# Decode step # Full connected layer n°3self.fc3=nn.Linear(10,20)
# Full connected layer n°4self.fc4=nn.Linear(20,nb_movies)
# Sigmoid activation function self.activation=nn.Sigmoid()
# Action : activation of the neuronsdefforward(self, x) :
x=self.activation(self.fc1(x))
x=self.activation(self.fc2(x))
x=self.activation(self.fc3(x))
# dont's use the activation function # use the linear function only x=self.fc4(x)
# x is th evector of predicted ratingsreturnx# Create the AutoEncoder object sae=SAE()
#MSE Loss : imported from torch.nn criterion=nn.MSELoss()
# RMSProp optimizer (update the weights) imported from torch.optim #sea.parameters() are weights and bias adjusted during the trainingoptimizer=optim.RMSProp(sae.parameters(),lr=0.01, weight_decay=0.5)
### Part 2 : Training of the SAE # number of epochs nb_epochs=200# Epoch forloop forepochinrange(1, nb_epoch+1):
# at the beginning the loss is at zeros=0.train_loss=0#Users forloop forid_userinrange(nb_users)
# add one dimension to make a two dimension vector.# create a new dimension and put it the first position .unsqueeze[0]input=Variable(training_set[id_user].unsqueeze[0])
# clone the input to obtain the target target=input.clone()
# target.data are all the ratings # ratings > 0iftorch.sum(target.data>0) >0output=sae(input)
# don't compute the gradients regarding the targettarget.require_grad=False# only deal with true ratings output[target==0]=0# Loss Criterion loss=criterion(output,target)
# Average the error of the movies that don't have zero ratingsmean_corrector=nb_movies/float(torch.sum(target.data>0)+1e-10)
# Direction of the backpropagation loss.backward()
train_loss+=np.sqrt(loss.data[0]*mean_corrector)
s+=1.# Intensity of the backpropagation optimizer.step()
print('epoch:'+str (epoch)+'loss:'+str(train_loss/s))