diff --git a/Code/NeuralNet.py b/Code/NeuralNet.py index 094d436..8441c15 100644 --- a/Code/NeuralNet.py +++ b/Code/NeuralNet.py @@ -10,15 +10,18 @@ je vais avoir besoin de tester les méthodes train, predict et test de votre cod """ import numpy as np - +import time import NeuralNode +import metrics +import random + # le nom de votre classe # NeuralNet pour le modèle Réseaux de Neurones # DecisionTree le modèle des arbres de decision class NeuralNet: #nom de la class à changer - def __init__(self, layers_size, **kwargs): + def __init__(self, layers_size, all_labels, **kwargs): """ c'est un Initializer. Vous pouvez passer d'autre paramètres au besoin, @@ -28,6 +31,7 @@ class NeuralNet: #nom de la class à changer self.layers_size = layers_size self.n_hidden_layers = len(layers_size) - 2 self.layers = [[] for i in range(self.n_hidden_layers+1)] + self.all_labels = all_labels # Couches cachées for j in range(self.n_hidden_layers): @@ -38,6 +42,23 @@ class NeuralNet: #nom de la class à changer for i in range(layers_size[-1]): self.layers[-1].append(NeuralNode.NeuralNode(layers_size[-2])) + def __str__(self): + outstr = "" + for layer in self.layers: + for node in layer: + outstr+"\n"+str(node.input_weights) + return outstr + + def one_hot_encoder(self,labels): + nb_labels = len(self.all_labels) + one_hot_matrix = [] + for label in labels: + one_rank = np.where(np.array(self.all_labels)==label) + one_hot = np.zeros(nb_labels,dtype=np.int64) + one_hot[one_rank] = 1 + one_hot_matrix.append(one_hot) + return np.array(one_hot_matrix) + def feed_forward(self,input_values): all_input_values = [] current_input_values = input_values @@ -50,7 +71,7 @@ class NeuralNet: #nom de la class à changer all_input_values.append(current_input_values) return all_input_values - def train(self, train, train_labels, alpha): #vous pouvez rajouter d'autres attribus au besoin + def train(self, train, train_labels, alpha, nb_epoch): #vous pouvez rajouter d'autres attribus au besoin """ c'est la méthode qui va entrainer votre modèle, train est une matrice de taille nxm, avec @@ -67,40 +88,39 @@ class NeuralNet: #nom de la class à changer ------------ """ + train_labels_enc = self.one_hot_encoder(train_labels) - for i in range(len(train)): - deltas = [] - output = self.feed_forward(train[i]) - print("Les valeurs des sorties sont: "+str(output)) - output_layer_error = [] - output_layer_error.append(sum(np.power(output[-1]-train_labels[i],2))/2) - deltas.append(output_layer_error) - # On recule dans les couches cachées j - for j in reversed(range(self.n_hidden_layers)): - #print("la couche "+str(j)) - layerError = [] - # Pour chaque neurone k de la couche cachée courante - for k in range(len(self.layers[j])): - #print("le neurone "+str(k)+" de la couche "+str(j)) - average_error = 0 - # Pour chaque neurone l de la couche j+1 - for l in range(len(self.layers[j+1])): - #print("la "+str(l)+"e entrée dans le neurone "+str(k)+" de la couche "+str(j+1)) - current_delta = deltas[0][l] - average_error += current_delta * self.layers[j+1][l].input_weights[k+1] - layerError.append(average_error * self.layers[j][k].activation_derivative(output[j])) - # Vu qu'on recule, on insère au début au lieu de la fin - deltas.insert(0,layerError) - # Mise à jour des poids - print("Mise à jour des poids. Les deltas sont: "+str(deltas)) - for j in range(len(self.layers)): - # Pour chaque neurone k - for k in range(len(self.layers[j])): - self.layers[j][k].update_weights(output[j],alpha,deltas[j][k]) - - - - + for epoch in range(nb_epoch): + print("epoch"+str(epoch)) + for i in range(len(train)): + deltas = [] + output = self.feed_forward(train[i]) + print("Les valeurs des sorties sont: "+str(output)+"\nLabel:"+str(train_labels_enc[i])) + deltas.append(train_labels_enc[i]-output[-1]) + # On recule dans les couches cachées j + for j in reversed(range(self.n_hidden_layers)): + #print("la couche "+str(j)) + layerError = [] + # Pour chaque neurone k de la couche cachée courante + for k in range(len(self.layers[j])): + #print("le neurone "+str(k)+" de la couche "+str(j)) + average_error = 0 + # Pour chaque neurone l de la couche j+1 + for l in range(len(self.layers[j+1])): + #print("la "+str(l)+"e entrée dans le neurone "+str(k)+" de la couche "+str(j+1)) + current_delta = deltas[0][l] + average_error += current_delta * self.layers[j+1][l].input_weights[k+1] + layerError.append(average_error * self.layers[j][k].activation_derivative(output[j])) + # Vu qu'on recule, on insère au début au lieu de la fin + deltas.insert(0,layerError) + # Mise à jour des poids + print("Mise à jour des poids. Les deltas sont: "+str(deltas)) + for j in range(len(self.layers)): + # Pour chaque neurone k + for k in range(len(self.layers[j])): + self.layers[j][k].update_weights(output[j],alpha,deltas[j][k]) + return self.test(train, train_labels) + def predict(self, exemple, label): """ Prédire la classe d'un exemple donné en entrée @@ -110,8 +130,9 @@ class NeuralNet: #nom de la class à changer alors l'exemple est bien classifié, si non c'est une missclassification """ + return np.argmax(self.feed_forward(exemple)[-1]) - def test(self, test, test_labels): + def test(self, test, test_labels, verbose=True): """ c'est la méthode qui va tester votre modèle sur les données de test l'argument test est une matrice de taille nxm, avec @@ -130,6 +151,17 @@ class NeuralNet: #nom de la class à changer Bien entendu ces tests doivent etre faits sur les données de test seulement """ + + start_time = time.time() + prediction_test = [self.predict(exemple,label) for exemple,label in zip(test,test_labels)] + print(prediction_test) + cm = metrics.confusion_matrix(test_labels,prediction_test) + accuracy, precision, recall = metrics.prediction_metrics(cm,test_labels,prediction_test) + compute_time = time.time() - start_time + if (verbose): + metrics.print_prediction_metrics(cm,accuracy,precision,recall,compute_time) + + return cm,accuracy,precision,recall,compute_time # Vous pouvez rajouter d'autres méthodes et fonctions, diff --git a/Code/main.py b/Code/main.py index c13264c..8b6b4af 100644 --- a/Code/main.py +++ b/Code/main.py @@ -2,9 +2,10 @@ import numpy as np import matplotlib.pyplot as plt import sys -import load_datasets +import load_datasets as ld import NeuralNet # importer la classe du Réseau de Neurones import DecisionTree # importer la classe de l'Arbre de Décision +import NeuralNetUtils as nnu # importer d'autres fichiers et classes si vous en avez développés # importer d'autres bibliothèques au besoin, sauf celles qui font du machine learning @@ -43,6 +44,7 @@ dt5.train(train5, train_labels5) dt5.predict(test5[0],test_labels5[0]) dt5.test(test5, test_labels5) -nn1 = NeuralNet.NeuralNet(np.array([4,4,4,1])) -nn1.feed_forward(train1[0]) -nn1.train(train1, train_labels1, 0.1) +nn1 = NeuralNet.NeuralNet(np.array([4,4,3]),range(3)) +nn1.train(train1, train_labels1, 0.1, 100) +nn1.predict(test1[0],test_labels1[0]) +nn1.test(test1,test_labels1)