From 1f6f9abe8caa6114b160b481555350d9ce0561e4 Mon Sep 17 00:00:00 2001
From: "thibault.capt" <thibault.capt@hes-so.ch>
Date: Wed, 15 Nov 2023 19:16:52 +0100
Subject: [PATCH] update

---
 perceptron-tp3.py | 48 ++++++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/perceptron-tp3.py b/perceptron-tp3.py
index eeb7303..f276749 100644
--- a/perceptron-tp3.py
+++ b/perceptron-tp3.py
@@ -1,23 +1,31 @@
 # Author : Capt Thibault, Souza Luz Juliano
 # Date : 31.10.2023
 # Project : Perceptron multicouche
-# Description : Ce fichier représente notre travail pour le tp du perceptron multicouche
+# Description : Ce fichier représente notre
+# travail pour le tp du perceptron multicouche
+#
+##############################################
+#
+# Réponse à la question :
+# Comme notre modèle d'apprentissage est assez simple, moins il y a de neurones dans la couche cachée, plus c'est
+
 import numpy as np
 import pandas as pd
 from matplotlib import pyplot as plt
 
+# Fonction pour mettre à jour les poids de la couche cachée
 def upd_weights_hidden(wi_old, learning, delta, xi):
     return wi_old + learning * np.outer(xi, delta)
 
-
+# Fonction pour mettre à jour les poids de la couche de sortie
 def upd_weights_output(wi_old, learning, delta, y):
     return wi_old + learning * delta * y
 
-
+# Fonction d'activation sigmoïde
 def sigmoide(x):
     return 1 / (1 + np.exp(-x))
 
-
+# Fonction de prédiction
 def predict(poids_input_hidden, poids_hidden_output, input_data):
     hidden_input = np.dot(input_data, poids_input_hidden)
     hidden_output = sigmoide(hidden_input)
@@ -26,25 +34,31 @@ def predict(poids_input_hidden, poids_hidden_output, input_data):
 
 
 if __name__ == '__main__':
+    # Chargement des données depuis le fichier CSV
     dataset = pd.read_csv("Data/student-data-train.csv", header=0)
     dataset['norm_grade_1'] = (dataset['grade_1'] - dataset['grade_1'].mean()) / dataset['grade_1'].std()
     dataset['norm_grade_2'] = (dataset['grade_2'] - dataset['grade_2'].mean()) / dataset['grade_2'].std()
 
+    # Normalisation des grades
     X = dataset[['norm_grade_1', 'norm_grade_2']].values
     y = dataset.iloc[:, 0].values
     num_features = X.shape[1]
 
-    learning_rate = 1e-3
+    # Paramètres d'apprentissage
+    learning_rate = 0.034
     max_iterations = 2000
-    num_hidden = 10
+    num_hidden = 200
 
     # Initialiser les poids pour l'entrée dans la couche cachée et masqués dans la couche de sortie
     weights_input_hidden = np.random.rand(num_features + 1, num_hidden) - 0.5
     weights_hidden_output = np.random.rand(num_hidden + 1) - 0.5
+    errors_x = []
+    errors_y = []
 
     print("Weights input to hidden:", weights_input_hidden)
     print("Weights hidden to output:", weights_hidden_output)
 
+    # Entraînement du modèle
     for iteration in range(max_iterations):
         total_error = 0
 
@@ -65,6 +79,12 @@ if __name__ == '__main__':
 
             total_error += (target - output) ** 2 / 2
 
+            # Ajouter les coordonnées des erreurs à la liste
+            if target != round(output):
+                errors_x.append(X[i, 0])
+                errors_y.append(X[i, 1])
+
+
         if (iteration % 10 == 0) or iteration == 0: # print tous les 5 iterations
             print(f"Iteration {iteration + 1}: Error = {total_error}")
 
@@ -81,23 +101,13 @@ if __name__ == '__main__':
     accuracy = correct_classifications / len(X)
     print(f"Taux de classifications correctes: {accuracy * 100}%")
 
-    # Extraction des poids de la couche cachée vers la couche d'entrée
-    w1, w2, b = weights_input_hidden[1, 1], weights_input_hidden[2, 1], weights_input_hidden[0, 1]
-
-    # Calcul de la pente et de l'ordonnée à l'origine de la droite de séparation
-    pente = -w1 / w2
-    intercept = -b / w2
-
-    print(f"Droite de séparation: y = {pente}x + {intercept}")
-
     # Tracer la droite de séparation
     plt.figure()
-    plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='red', label='Classe 0')
+    plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='green', label='Classe 0')
     plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='blue', label='Classe 1')
-    plt.plot([-2, 2], [-2 * pente + intercept, 2 * pente + intercept], color='green', label='Droite de séparation')
-    plt.title('Données avec la droite de séparation')
+    plt.scatter(errors_x, errors_y, color='red', marker='x', label='Erreurs')
+    plt.title('Données')
     plt.xlabel('Norm_Grade_1')
     plt.ylabel('Norm_Grade_2')
     plt.legend()
     plt.show()
-
-- 
GitLab