Exemplo n.º 1
0
        /// <summary>
        /// Initialiser le réseau
        /// </summary>
        /// <param name="transfert">Fonction de transfert</param>
        /// <param name="nbEntrees">Nb d'entrées des neurones de la couche d'entrée</param>
        /// <param name="transfertDerivee">Null ou dérivée de la fonction de transfert</param>
        /// <param name="seuil">Seuil de la fonction de transfert de la couche</param>
        /// <param name="topologie">Topologie du réseau</param>
        protected override void Initialiser(Func <double, double> transfert, double seuil, Func <double, double> transfertDerivee, int nbEntrees, int[] topologie)
        {
            Couches = new Couche[topologie.Length];

            // couche d'entrée
            Couches[0] = new Couche(topologie[0], nbEntrees, FonctionsTransfert.Identite, 0);
            foreach (Neurone neurone in Couches[0].Neurones)
            {
                for (int i = 0; i < neurone.Poids.Length; i++)
                {
                    neurone.Poids[i] = 1;
                }
            }

            // couches cachées
            for (int c = 1; c < Couches.Length - 1; c++)
            {
                //Couches[c] = new Couche(topologie[c], Couches[c - 1].Neurones.Length, FonctionsTransfert.HyperTan, 0, FonctionsTransfert.HyperTanDerivee);
                Couches[c]          = new Couche(topologie[c], Couches[c - 1].Neurones.Length, FonctionsTransfert.Sigmoide, 0.5, FonctionsTransfert.SigmoideDerivee);
                Couches[c].Position = c;
            }

            // couche de sortie
            Couches[Couches.Length - 1]          = new Couche(topologie[Couches.Length - 1], Couches[Couches.Length - 2].Neurones.Length, FonctionsTransfert.Sigmoide, 0.5, FonctionsTransfert.SigmoideDerivee);
            Couches[Couches.Length - 1].Position = Couches.Length - 1;
        }
Exemplo 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);
        }
Exemplo n.º 3
0
        public ReseauNeural(int nbEntree, int nbSortie, int nbCouche)
        {
            Entree        = new float[nbEntree];
            Sortie        = new float[nbSortie];
            NeuroneSortie = new Neurone[nbSortie];
            for (int i = 0; i < nbSortie; i++)
            {
                NeuroneSortie[i] = new Neurone(nbEntree);
            }
            if (nbCouche < 0)
            {
                nbCouche = 1;
            }
            NbNeuronneMax = nbEntree > nbSortie ? nbEntree : nbSortie;

            LesCoucheNeural = new Couche[nbCouche];
            for (int i = 0; i < nbCouche; i++)
            {
                if (i == 0)
                {
                    LesCoucheNeural[i] = new Couche(nbEntree, NbNeuronneMax);
                }
                else
                {
                    LesCoucheNeural[i] = new Couche(NbNeuronneMax, NbNeuronneMax);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Propagation des erreurs entre couche1 et couche2 sur les poids et les biais
        /// </summary>
        /// <param name="pas">Pas d'apprentissage</param>
        /// <param name="couche1"></param>
        /// <param name="couche2"></param>
        /// <remarks>
        /// couche1 => couche2
        /// </remarks>
        private void Propager(Couche couche1, Couche couche2, double pas)
        {
            for (int c2 = 0; c2 < couche2.Neurones.Length; c2++)
            {
                Neurone neurone2 = couche2.Neurones[c2];
                for (int c1 = 0; c1 < couche1.Neurones.Length; c1++)
                {
                    neurone2.Poids[c1] += pas * neurone2.Erreur * couche1.Neurones[c1].Sortie;
                }

                neurone2.Biais += pas * neurone2.Erreur;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Calcule des erreurs (gradiant local) des neurones de la couche de sortie
        /// </summary>
        /// <param name="tests">Jeu de tests</param>
        /// <param name="cible">Cible (valeur désirée) pour chaque jeu de test</param>
        private void CalculerDeltaO(double[] cible)
        {
            Couche coucheSortie = Couches[Couches.Length - 1];

            for (int k = 0; k < coucheSortie.Neurones.Length; k++)
            {
                Neurone neuroneO = coucheSortie.Neurones[k];
                double  ecart    = 0.0;

                ecart           = cible[k] - neuroneO.Sortie;
                neuroneO.Erreur = neuroneO.TransfertDerivee(neuroneO.Somme + neuroneO.Biais) * ecart;
                //Debug.WriteLine("Gradiant O: " + neuroneO.Erreur.ToString());
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Calcule de l'erreur (gradiant local) des neurones des couches cachées
        /// </summary>
        /// <param name="couche1">Couche cachée N</param>
        /// <param name="couche2">Couche N + 1</param>
        /// <returns></returns>
        private void CalculerDeltaH(Couche couche1, Couche couche2)
        {
            for (int k = 0; k < couche1.Neurones.Length; k++)
            {
                Neurone neuroneH = couche1.Neurones[k];

                double somme = 0.0;
                for (int i = 0; i < couche2.Neurones.Length; i++)
                {
                    Neurone neurone2 = couche2.Neurones[i];
                    somme += neurone2.Poids[k] * neurone2.Erreur;
                }

                neuroneH.Erreur = neuroneH.TransfertDerivee(neuroneH.Somme + neuroneH.Biais) * somme;
                //Debug.WriteLine("Gradiant H: " + neuroneH.Erreur.ToString());
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Initialise la couche
 /// </summary>
 /// <param name="transfert">Fonction de transfert</param>
 /// <param name="transfertDerivee">Nom utilisé</param>
 /// <param name="topologie">Topologie du réseau</param>
 /// <param name="seuil">Seuil de la fonction de transfert</param>
 /// <param name="nbEntrees">Nb d'entrées des neurones de la couche d'entrée</param>
 protected override void Initialiser(Func <double, double> transfert, double seuil, Func <double, double> transfertDerivee, int nbEntrees, int[] topologie)
 {
     Couches    = new Couche[1];
     Couches[0] = new Couche(topologie[0], nbEntrees, transfert, seuil);
 }
Exemplo n.º 8
0
        static void Main(string[] args)
        {
            string selection = null;

            while (selection != "1" && selection != "2")
            {
                Console.Clear();
                Console.WriteLine("1) Cartographie");
                Console.WriteLine("2) Fleurs d'iris");
                Console.WriteLine("Quel jeu de test?");

                selection = Console.ReadLine();
                selection = selection.Trim();
            }

            #region Création
            Console.Clear();
            Console.WriteLine("Création du réseau");
            int[] topologie;
            if (selection == "1")
            {
                topologie = new int[] { 2, 2, 1 };
            }
            else
            {
                topologie = new int[] { 4, 7, 3 };
            }
            DeepNetwork deepNetwork = new DeepNetwork(1, topologie);

            Console.WriteLine("Nb de couches: {0}", deepNetwork.Couches.Length);
            Console.WriteLine("Topologie du réseau: {0}", string.Join("x", topologie));
            int nbPoids = 0;
            for (int i = 1; i < topologie.Length; i++)
            {
                nbPoids += topologie[i] * topologie[i - 1];
            }
            Console.WriteLine("Nombre de poids: {0}", nbPoids);
            Console.WriteLine("Nombre de biais/neurones: {0}", topologie[1] + topologie[topologie.Length - 1]);
            Console.WriteLine("---------------------------------------------");
            Console.WriteLine();
            #endregion

            Helper.PoidsAleatoires(deepNetwork, false);

            // vitesse d'apprentissage
            double pas          = 0.5;
            double maxErreur    = 0.03;
            int    maxIteration = 5000;
            if (selection == "1")
            {
                Cartographie();
            }
            else
            {
                // iris
                pas          = 0.05;
                maxErreur    = 0.001;
                maxIteration = 500;
                Iris();
            }

            deepNetwork.Calculer(entrainement[0]);
            Helper.AfficherReseau(deepNetwork);

            // entraînement
            Console.WriteLine("Entraînement du réseau sur {0} tests et {1} itérations max", entrainement.Length, maxIteration);
            Console.WriteLine("Pas: {0}", pas);
            double erreur = deepNetwork.Entrainer(entrainement, cibleEntrainement, maxIteration, pas, maxErreur);
            Console.WriteLine("Erreur en fin d'apprentissage: {0}", erreur);
            Helper.AfficherReseau(deepNetwork);

            // jeu de test
            Couche coucheSortie = deepNetwork.Couches[2];
            for (int i = 0; i < tests.Length; i++)
            {
                deepNetwork.Calculer(tests[i]);

                Console.WriteLine("Test {0}", i);
                Helper.AfficherVecteur(tests[i], "Entrées:");

                Helper.AfficherSorties(coucheSortie.Neurones, "Calculé: ");
                Helper.AfficherVecteur(cibleTest[i], "Cible:");
                Console.WriteLine();
            }

            Console.WriteLine("Terminé");
            Console.ReadLine();
        }
Exemplo n.º 9
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="jeuEssai">Jeu d'essai pour entraîner le réseau. Il contient la valeur à appliquer à chaque neurone de la couche d'entrée</param>
        /// <param name="biais">Biais initial</param>
        /// <returns>L'erreur du réseau à la fin de son entraînement</returns>
        public double Entrainer(double[][] tests, double[][] cibles, int maxIteration, double pas, double maxErreur)
        {
            // Note: pour la suite on supposera qu'il n'y a qu'une seule couche cachée

            // inspiré de:
            // https://www4.rgu.ac.uk/files/chapter3%20-%20bp.pdf
            // https://www.youtube.com/watch?v=I2I5ztVfUSE

            Couche coucheSortie = Couches[Couches.Length - 1];
            Couche coucheCachee = Couches[Couches.Length - 2];
            Couche coucheEntree = Couches[0];
            // erreur faite par le réseau
            double erreurReseau = 0;

            // important: ne pas inverser les deux boucles for
            // sinon on aura au final entraîné le réseau uniquement pour le dernier jeu de test et non pas le jeu complet
            for (int m = 0; m < maxIteration; m++)
            {
                Debug.WriteLine("Itération: " + m.ToString());

                erreurReseau = 0;
                for (int t = 0; t < tests.Length; t++)
                {
                    #region Passe avant
                    // calcul d'un état du réseau (Somme et Sortie)
                    Calculer(tests[t]);
                    //Helper.AfficherReseau(this);
                    #endregion

                    #region Passe rétro
                    // calcul des gradiants de la couche de sortie
                    CalculerDeltaO(cibles[t]);
                    //CalculerDeltaO(cibles[c]);
                    // calculer des radiants de la couche cachée
                    CalculerDeltaH(coucheCachee, coucheSortie);

                    // recalculer les poids et les biais de la couche de sortie
                    Propager(coucheCachee, coucheSortie, pas);
                    // recalculer les poids et les biais de la couche cachée
                    Propager(coucheEntree, coucheCachee, pas);
                    #endregion

                    //Helper.AfficherReseau(this);
                } // pour chaque test

                // le réseau a t'il convergé?
                for (int t = 0; t < tests.Length; t++)
                {
                    Calculer(tests[t]);

                    // calcule l'erreur qui doit converger vers la valeur cible 'maxErreur'
                    double erreur = 0.0;
                    for (int i = 0; i < coucheSortie.Neurones.Length; i++)
                    {
                        // TODO: en l'état Cibles n'est pas adapté au cas de réseau avec une couche de sortie à plusieurs neurones
                        //double ecart = cibles[c][i] - coucheSortie.Neurones[i].Sortie;
                        double ecart = cibles[t][i] - coucheSortie.Neurones[i].Sortie;
                        erreur += ecart * ecart;
                    }
                    erreurReseau += erreur;
                }
                erreurReseau = 0.5 * Math.Sqrt(erreurReseau / tests.Length);
                //Console.WriteLine("Erreur réseau: {0}", erreurReseau);
                if (erreurReseau <= maxErreur)
                {
                    break;
                }
            } // pour chaque itération

            return(erreurReseau);
        }