public Matrice Feed(double[] entree) { Matrice val = new Matrice(entree.Length, 1).FromArrayVector(entree); input = val.Copy(); Matrice buffer = couches[0].Feed(input); // Première couche if (DEBUG) { Console.WriteLine("Couche 1 "); Console.WriteLine("-----------------------------------------------------"); couches[0].inputs.Debug("ENTREE"); couches[0].weights.Debug("POIDS"); } for (int i = 1; i < couches.Length; i++) { buffer = couches[i].Feed(buffer); if (DEBUG) { Console.WriteLine("Couche " + Convert.ToString(i + 1)); // On donne la sortie des couches aux couches suivantes Console.WriteLine("-----------------------------------------------------"); couches[i].output.Debug(""); } } output = buffer.Copy(); return(buffer); }
public Matrice Feed(Matrice i) // i est le vecteur d'entrées { inputs = i.Copy(); if (DEBUG) { inputs.Debug("Entrées"); } Matrice buffer = weights.Multiply(inputs); // On multiplie les entrées par les poids if (DEBUG) { buffer.Debug("Sortie Nette"); } buffer = buffer.Sum(); // On en fait la somme if (DEBUG) { buffer.Debug("Sortie sommée"); } buffer = buffer.Function(Sigmoid); // On fait passer le buffer dans la fonction d'activation (sigmoid) if (DEBUG) { buffer.Debug("Sortie sigmoid"); } output = buffer.Copy(); return(buffer); }
public Matrice FromArrayVector(double[] val) { Matrice sortie = new Matrice(val.Length, 1); for (int i = 0; i < lignes; i++) { sortie.valeurs[i, 0] = val[i]; // On exécute cette méthode sur chaque case } return(sortie); }
public Couche(int n, int i) // i définit le nombre d'entrées par neurone // n définit le nombre de neurones { inputs = new Matrice(n, i); weights = new Matrice(n, i); weights.Randomize(); output = new Matrice(1, n); nombre_neurones = n; buffer = weights; }
public Matrice Power(double p) { Matrice sortie = this.Copy(); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { Math.Pow(sortie.valeurs[i, n], p); // On multiplie chaque case } } return(sortie); }
public Matrice Multiply(Matrice autre) { Matrice sortie = this.Copy(); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] *= autre.valeurs[n, 0]; // On multiplie chaque case par la même case de l'autre matrice } } return(sortie); }
public Matrice Function(Func <double, double> val) // On prend une méthode en paramètre { Matrice sortie = this.Copy(); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] = val(sortie.valeurs[i, n]); // On exécute cette méthode sur chaque case } } return(sortie); }
public Matrice Sum() { Matrice sortie = new Matrice(lignes, 1); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, 0] += valeurs[i, n]; // On multiplie chaque case par la même case de l'autre matrice } } return(sortie); }
public Matrice Add(Matrice val) { Matrice sortie = this.Copy(); // On copie cette matrice for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] += val.valeurs[i, n]; // On ajoute la case de l'autre matrice à la case ici } } return(sortie); }
public Matrice MultiplyExact(Matrice val) { Matrice sortie = this.Copy(); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] *= val.valeurs[i, n]; // On exécute cette méthode sur chaque case } } return(sortie); }
public Matrice Scalar(double val) { Matrice sortie = this.Copy(); // On copie cette matrice for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] *= val; // On multiplie une valeur à toutes les cases } } return(sortie); }
public Matrice Inverse() { Matrice sortie = this.Copy(); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] *= -1; } } return(sortie); }
public Matrice Val_Add(double val) { Matrice sortie = this.Copy(); // On copie cette matrice for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] += val; // On ajoute une valeur à toutes les cases } } return(sortie); }
public Matrice Vector(Matrice val) { Matrice sortie = this.Copy(); Matrice autre = val.Copy().Transpose(); // On transpose le vecteur (Plus simple) for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] *= autre.valeurs[0, n]; // On multiplie par le vecteur } } return(sortie); }
public Matrice Copy() { Matrice sortie = new Matrice(lignes, colonnes); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] = valeurs[i, n]; // On copie les valeurs } } return(sortie); }
public Matrice Transpose() { Matrice sortie = new Matrice(colonnes, lignes); // On crée la matrice de sortie for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[n, i] = valeurs[i, n]; // On tourne la matrice (inversion des lignes et colonnes) } } return(sortie); // On retourne la matrice }
public Reseau(int nb_i, int[] nb_c, int nb_o) //nb_i : Nombre d'entrées //nb_c : Nombre de neurones cachés //nb_o : Nombre de sorties { input = new Matrice(nb_i, 1); // On initialise la matrice d'entrée couches = new Couche[nb_c.Length + 1]; // On initialise le tableau de couches couches[0] = new Couche(nb_c[0], nb_i); // La première couche a autant d'entrées que la matrice input for (int i = 1; i < nb_c.Length; i++) // Pour chaque autre couche spécifiée, la remplir de neurones { couches[i] = new Couche(nb_c[i], nb_c[i - 1]); // Autant d'entrées que le nombre de neurones précédents } couches[couches.Length - 1] = new Couche(nb_o, nb_c[nb_c.Length - 1]); // Couche de sortie }
public Matrice MultiplyHorizontalVector(Matrice val) { // Multiplie de droite à gauche plutot que de haut en bas Matrice sortie = this.Copy(); Matrice autre = val.Copy(); // On ne transpose pas le vecteur (Plus simple) for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { sortie.valeurs[i, n] *= autre.valeurs[i, 0]; // On multiplie par le vecteur } } return(sortie); }
public Matrice MultiplyVectors(Matrice val) { // Nouvelle matrice carré Matrice sortie = new Matrice(this.lignes, val.colonnes); Matrice ceci = this.Copy(); Matrice autre = val.Copy(); for (int i = 0; i < sortie.lignes; i++) { for (int n = 0; n < sortie.colonnes; n++) { sortie.valeurs[i, n] = ceci.valeurs[i, 0] * autre.valeurs[0, n]; // On utilise le vecteur pour vaincre le vecteur } } return(sortie); }
public Matrice Activate() { Matrice sortie = this.Copy(); for (int i = 0; i < lignes; i++) { for (int n = 0; n < colonnes; n++) { if (sortie.valeurs[i, n] >= 0) { sortie.valeurs[i, n] = 1; } if (sortie.valeurs[i, n] < 0) { sortie.valeurs[i, n] = -1; } } } return(sortie); }
public void UpdateWeights() { this.weights = this.weights.Add(buffer); }
public void Train(double[] entree, double[] attendu) { Matrice val = new Matrice(entree.Length, 1).FromArrayVector(entree); Matrice Yattendu = new Matrice(attendu.Length, 1).FromArrayVector(attendu); this.input = val; Matrice Ysortie = Feed(entree); int nombre_h = this.couches.Length - 1; // Nombre de couches cachées (donc, sans compter la couche de sortie) // Selon la formule E = Yattendu - Ysortie : // Calculons l'erreur Matrice erreur_sortie = Yattendu.Substract(Ysortie); double[] buffer = erreur_sortie.ToArrayVector(); this.mean_error = buffer.Average(); // Calcul du gradient Matrice gradient = Ysortie.Copy(); gradient = gradient.Function(DeSigmoid); gradient = gradient.MultiplyExact(erreur_sortie); gradient = gradient.Scalar(this.learning_rate); // Sortie de la couche précédente : // this.couches[this.couches.Length - 2].output // Calcul du Delta Matrice buff = this.couches[this.couches.Length - 2].output.Copy().Transpose(); Matrice deltas = gradient.MultiplyVectors(buff); this.couches[this.couches.Length - 1].buffer = deltas.Copy(); this.couches[this.couches.Length - 1].UpdateWeights(); // ------------------------------ COUCHE MILIEU --------------------- // ------------------------------ LA BOUCLE COMMENCE ---------------- Matrice erreur_prec = erreur_sortie.Copy(); for (int i = 1; i <= nombre_h - 1; i++) { int index = this.couches.Length - 1 - i; // Poids de la couche suivante : // this.couches[index + 1].weights (espérons) Matrice poids_T = this.couches[index + 1].weights.Transpose(); erreur_prec = poids_T.Vector(erreur_prec); // Erreur de cette couche gradient = this.couches[index].output.Copy(); gradient = gradient.Function(DeSigmoid); gradient = gradient.MultiplyExact(erreur_prec); gradient = gradient.Scalar(this.learning_rate); buff = this.couches[index - 1].output.Copy().Transpose(); deltas = gradient.MultiplyVectors(buff); this.couches[index].buffer = deltas.Copy(); this.couches[index].UpdateWeights(); } // ------------------------------ PREMIERE COUCHE ---------------- // Poids de la couche suivante : // this.couches[index + 1].weights (espérons) Matrice poids_T_ = this.couches[1].weights.Transpose(); erreur_prec = poids_T_.Vector(erreur_prec); // Erreur de cette couche gradient = this.couches[0].output.Copy(); gradient = gradient.Function(DeSigmoid); gradient = gradient.MultiplyExact(erreur_prec); gradient = gradient.Scalar(this.learning_rate); buff = this.input.Copy().Transpose(); deltas = gradient.MultiplyVectors(buff); this.couches[0].buffer = deltas.Copy(); this.couches[0].UpdateWeights(); }
public Matrice Calculate_Error(double[] entree, double[] voulu) { Matrice Yattendu = new Matrice(voulu.Length, 1).FromArrayVector(voulu); return(Feed(entree).Substract(Yattendu).Transpose().Sum()); }