Ejemplo n.º 1
0
        /// <summary>
        /// Effectue une prédiction sur un modèle
        /// </summary>
        /// <param name="dataVector"></param>
        /// <returns>true si le vecteur d'entrée correspond au modèle pour lequel le réseau a été entraîné</returns>
        public override bool Predire(double[] dataVector)
        {
            Neurone neurone = Couches[0].Neurones[0];
            double  sortie  = neurone.CalculerSortie(dataVector);

            return(sortie > Couches[0].Seuil);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Cacule la matrice des erreurs effectuées par le réseau sur le jeu de tests fournis
        /// </summary>
        /// <param name="tests">Jeu de tests</param>
        /// <param name="cibles">Cible pour chaque jeu de test</param>
        /// <returns>
        /// Matrice des erreurs contenant l'erreur commise par chaque neurone de la couche de sortie
        /// </returns>
        private double[] CalculerErreur(double[][] tests, double[] cibles)
        {
            Couche coucheSortie = Couches[Couches.Length - 1];

            double[] erreurs = new double[coucheSortie.Neurones.Length];

            for (int n = 0; n < coucheSortie.Neurones.Length; n++)
            {
                Neurone neurone = coucheSortie.Neurones[n];
                double  somme   = 0.0;

                for (int i = 0; i < tests.Length; i++)
                {
                    double sortie = neurone.CalculerSortie(tests[i]);
                    double ecart  = cibles[i] - sortie;
                    // calcule l'erreur faite par le réseau lors de l'estimation de la cible
                    // sur le neurone en cours de la dernière couche
                    somme += ecart * ecart;
                }

                erreurs[n] = 0.5 * somme;
            }

            return(erreurs);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Entraine le réseau
        /// </summary>
        /// <param name="maxIteration">Nombre d'itérations max</param>
        /// <param name="pas">Pas d'apprentissage</param>
        /// <param name="lettreCible">Lettre pour laquelle on entraîne le réseau</param>
        /// <param name="jeuEssai">Jeu d'essai pour entraîner le réseau</param>
        /// <param name="biais">Biais initial</param>
        /// <returns>L'erreur du réseau à la fin de son entraînement</returns>
        public double[] Entrainer(Dictionary <string, double[]> jeuEssai, string lettreCible, int maxIteration, double pas, double biais)
        {
            // on entraîne le réseau
            Neurone neurone = Couches[0].Neurones[0]; // un seul neurone dans le Perceptron

            double erreurCible = 0;

            double[] erreurCourante = new double[] { double.MaxValue };
            int      iteration      = 0;

            // valeurs initiales
            neurone.Poids = new double[neurone.NbEntrees];
            neurone.Biais = biais;

            while (iteration < maxIteration && erreurCourante[0] > erreurCible)
            {
                // pour chaque élément de test
                foreach (string lettre in jeuEssai.Keys)
                {
                    // récupère le jeu d'entraînement courant
                    double[] entraineur = jeuEssai[lettre];
                    // détermine si c'est la valeur cible (1) ou pas (-1)
                    int valeurCible = (lettre == lettreCible) ? 1 : 0; // la fonction de transfert doit donc produire des -1 ou des 1

                    double sortie = neurone.CalculerSortie(entraineur);
                    // de combien la sortie s'écarte de la cible
                    double ecart = valeurCible - sortie;

                    if (ecart != 0)
                    {
                        // réévalue le poids de chaque entrée (règle de RosenBlatt)
                        for (int p = 0; p < neurone.NbEntrees; p++)
                        {
                            neurone.Poids[p] = neurone.Poids[p] + (pas * ecart * entraineur[p]);
                        }
                        // réévalue le biais
                        // le biais est considéré comme une entrée supplémentaire avec un coefficient toujours égal à 1
                        neurone.Biais = neurone.Biais + (pas * ecart);
                    }
                }

                ++iteration;
                Debug.WriteLine("Itération: " + iteration.ToString());

                // on a un biais et un jeu de poids candidat
                // calcule l'erreur faite par le réseau dans l'estimation de notre jeu d'essai avec notre candidat
                double[][] tests  = jeuEssai.Select(jeu => jeu.Value).ToArray();
                double[]   cibles = jeuEssai.Select(jeu => (jeu.Key == lettreCible) ? 1.0 : 0.0).ToArray();
                double[][] c      = jeuEssai.Select(jeu => cibles).ToArray();
                erreurCourante = CalculerErreur(tests, cibles);
            }

            return(erreurCourante);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Evaluer une entrée fournie par le réseau
        /// </summary>
        /// <param name="jeuEssai"></param>
        public void Calculer(double[] jeuEssai)
        {
            // on en fait une copie locale
            double[] entraineur = new double[jeuEssai.Length];
            Array.Copy(jeuEssai, entraineur, jeuEssai.Length);

            // première dimension: une valeur par neurone de la couche
            // deuxième dimension: le vecteur des entrées appliquée au neurone
            double[][] testeurs = new double[Couches[0].Neurones.Length][];
            for (int i = 0; i < Couches[0].Neurones.Length; i++)
            {
                testeurs[i] = new double[] { entraineur[i] };
            }

            foreach (Couche couche in Couches)
            {
                if (testeurs == null)
                {
                    // on réamorce la boucle de calcul
                    testeurs = new double[couche.Neurones.Length][];
                    for (int i = 0; i < couche.Neurones.Length; i++)
                    {
                        // les neurones de chaque couche interne reçoivent le même jeu d'entrée contrairement aux neurones de la couche d'entrée
                        testeurs[i] = entraineur;
                    }
                }

                for (int n = 0; n < couche.Neurones.Length; n++)
                {
                    Neurone neurone = couche.Neurones[n];
                    neurone.CalculerSortie(testeurs[n]);
                }

                // on récupère les sorties des neurones de la couche courante
                entraineur = new double[couche.Neurones.Length];
                for (int i = 0; i < couche.Neurones.Length; i++)
                {
                    Neurone neurone = couche.Neurones[i];
                    entraineur[i] = neurone.Sortie;
                }

                testeurs = null;
            }
        }