Example #1
0
        //  double[] BackpropagateNeuralNet(double[] inputVector, double[] CibleVector, NeuroneSortieListe pMemorizedNeuronOutputs,
        //     byte Label, FormPrincipal frm)
        double[] BackpropagateNeuralNet(double[] inputVector, double[] CibleVector, NeuroneSortieListe pMemorizedNeuronOutputs,
                                        FormPrincipal frm, Boolean distorsion)
        {
            _form = frm;

            // double erreur = 0.0;
            double[] VecteurCourant = new double[NombreSorties];

            nombreBackPropagation++;

            CalculateNeuralNet(inputVector, CibleVector, VecteurCourant, pMemorizedNeuronOutputs, distorsion);

            return(VecteurCourant);
        }
Example #2
0
        double[] BackpropagateNeuralNet(double[] inputVector, double[] CibleVector, NeuroneSortieListe _memorizedNeuronOutputs,
                                        byte Label, FormPrincipal frm)
        {
            _form = frm;

            // double erreur = 0.0;
            int nbreElement = CibleVector.Count();

            //double[] VecteurCourant = new double[10];
            double[] VecteurCourant = new double[nbreElement];


            CalculateNeuralNetTest(inputVector, CibleVector, VecteurCourant, _memorizedNeuronOutputs);

            return(VecteurCourant);
        }
Example #3
0
        public void ApprentissageThead()
        {
            try
            {
                uint   compteur = 0;
                double erreur   = 100.0;
                double eta      = 0.90; // learning rate - controls the maginitude of the increase in the change in weights. found by trial and error.
                double alpha    = 0.04;

                char   Label;
                double dMSE;

                NeuroneSortieListe _memorizedNeuronOutputs = new NeuroneSortieListe();

                Double size   = Math.Sqrt(TrainMatrix[0].Length);
                Double taille = TrainMatrix[0].Length;

                double[] VecteurEntree  = new double[(int)taille];
                double[] VecteurCible   = new double[NombreSorties];
                double[] VecteurCourant = new double[NombreSorties];

                //   archive.Serialisation(_RNN);

                while (_iEpochsCompleted < 30)
                //while (erreur > 0.10 * 0.1 && _iEpochsCompleted < 20)
                {
                    // initialisation

                    for (int i = 0; i < taille; i++)
                    {
                        VecteurEntree[i] = 0.0;
                    }

                    for (int i = 0; i < NombreSorties; i++)
                    {
                        VecteurCible[i]   = 0.0;
                        VecteurCourant[i] = 0.0;
                    }

                    // Boucle
                    if (Definitions.IndexPatternCourant == 0)
                    {
                        m_HiPerfTime.Start();
                        Helpers.ShuffleRows(TrainMatrix);
                        //Definitions.mnistApprentissageDatabase.RandomizePatternSequence();
                    }
                    // Randomize pattern
                    // Pad 28 ==> 29

                    byte[] padImage = new byte[SizePattern * SizePattern];

                    //byte[][] padImage = new byte[29][];
                    //for (int i = 0; i < padImage.Length; ++i)
                    //    padImage[i] = new byte[29];

                    uint iPattern = (uint)Definitions.IndexPatternCourant;

                    Label = (char)TrainMatrix[iPattern][0];

                    //uint iPattern = BaseApprentissage.GetNextPattern();
                    // Definitions.mnistApprentissageDatabase.result[iPattern].pixels.CopyTo(padImage, 0);
                    //Label = Definitions.mnistApprentissageDatabase.result[iPattern].label;


                    // Label = BaseApprentissage.

                    for (int i = 0; i < SizePattern * SizePattern; i++)
                    {
                        VecteurEntree[i] = 1.0;  // 1 Blanc et 0 noir
                    }
                    try
                    {
                        for (int hauteur = 1; hauteur < 32 * 32; ++hauteur)
                        {
                            VecteurEntree[hauteur] = TrainMatrix[iPattern][hauteur] / 128.0 - 1.0;
                        }
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err.Message);
                    }

                    //for (int hauteur = 0; hauteur < 32; ++hauteur)
                    //{
                    //    for (int largeur = 0; largeur < 32; ++largeur)
                    //    {
                    //        VecteurEntree[1 + largeur + 32 * (hauteur + 1)] = TrainMatrix[iPattern][largeur + 32 * hauteur + 1] / 128.0 -1.0 ;
                    //    }

                    //}


                    //for (int hauteur = 0; hauteur < 32; ++hauteur)
                    //{
                    //    for (int largeur = 0; largeur < 32; ++largeur)
                    //    {
                    //        VecteurEntree[1 + largeur + 32 * (hauteur + 1)] = (double)((int)(byte)padImage[largeur + 32 * hauteur]) / 128.0 - 1.0;
                    //        //VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[hauteur][largeur]) / 128.0 - 1.0;
                    //    }
                    //}

                    for (int i = 0; i < NombreSorties; i++)
                    {
                        VecteurCible[i] = -1.0;
                    }
                    // 90 65
                    // 122 97

                    int x = (int)Label;
                    int n = DetermineIndex(x);
                    VecteurCible[n] = 1.0;

                    //Chiffres 48
                    // Majuscules 65
                    // Minuscules 97
                    // int n = Label - 65; // -97;
                    //  int n = Label - 97; // -97;
                    //  int n = Label - 48; // -97;
                    //  VecteurCible[DetermineIndex(n)] = 1.0;
                    //  VecteurCible[n] = 1.0;

                    VecteurCourant = BackpropagateNeuralNet(VecteurEntree, VecteurCible, _memorizedNeuronOutputs, _form, false);

                    dMSE = 0.0;
                    for (int i = 0; i < NombreSorties; ++i)
                    {
                        dMSE += (VecteurCourant[i] - VecteurCible[i]) * (VecteurCourant[i] - VecteurCible[i]);
                    }
                    dMSE     /= 2.0;
                    _dMSE    += dMSE;
                    _dMSE200 += dMSE;


                    _nn++;
                    int    iBestIndex = 0;
                    double maxValue   = -99.0;

                    for (int i = 0; i < NombreSorties; ++i)
                    {
                        if (VecteurCourant[i] > maxValue)
                        {
                            iBestIndex = i;
                            maxValue   = VecteurCourant[i];
                        }
                    }

                    if (iBestIndex != n) // Label)
                    {
                        erreurReconnaissances++;
                    }
                    else
                    {
                        bonneReconnaissances++;
                    }

                    // make step
                    string s = "";
                    if (_nn >= 200)
                    {
                        _dMSE200 /= 200;
                        erreur    = _dMSE200;
                        s         = "MSE:" + _dMSE200.ToString();

                        double partielpourcentage = (erreurReconnaissances * 100) / Definitions.IndexPatternCourant;

                        _form.Invoke(_form._DelegateAddObject, new Object[] { 2, partielpourcentage });

                        _dMSE200 = 0;
                        _nn      = 0;
                    }

                    s = String.Format("{0} Miss Number:{1} Bonne reco {2}", Convert.ToString(Definitions.IndexPatternCourant), erreurReconnaissances, bonneReconnaissances);
                    if (_form != null)
                    {
                        _form.Invoke(_form._DelegateAddObject, new Object[] { 5, s });
                    }

                    if (Definitions.IndexPatternCourant >= TrainMatrix.Length - 1)
                    {
                        m_HiPerfTime.Stop();
                        _dMSE /= Definitions.IndexPatternCourant;
                        Definitions.IndexPatternCourant = 0;

                        double pourcentage = (erreurReconnaissances * 100) / TrainMatrix.Length;

                        s = String.Format("Epochs:{0}, Pourcentage:{1}, Temps {2}, Miss:{3} ",
                                          Convert.ToString(_iEpochsCompleted + 1), Convert.ToString(pourcentage), m_HiPerfTime.Duration, erreurReconnaissances.ToString());

                        if (_form != null)
                        {
                            _form.Invoke(_form._DelegateAddObject, new Object[] { 3, s });
                        }

                        erreurReconnaissances = 0;
                        bonneReconnaissances  = 0;

                        _iEpochsCompleted++;
                        Definitions.IndexPatternCourant = 0;
                        _dMSE = 0;
                    }
                    else
                    {
                        Definitions.IndexPatternCourant++;
                    }

                    compteur++;

                    Definitions.rnn.Backpropagate(VecteurCourant, VecteurCible, 0, _memorizedNeuronOutputs, nombreBackPropagation);
                }

                archive.Serialisation(_RNN);
                //archive.Serialisation(Definitions.rnn);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }
Example #4
0
        public void BackPropagationThead()
        {
            try
            {
                uint   compteur = 0;
                double erreur   = 100.0;
                double eta      = 0.90; // learning rate - controls the maginitude of the increase in the change in weights. found by trial and error.
                double alpha    = 0.04;

                byte   Label = 0;
                double dMSE;

                NeuroneSortieListe _memorizedNeuronOutputs = new NeuroneSortieListe();

                double[] VecteurEntree  = new double[841];
                double[] VecteurCible   = new double[10];
                double[] VecteurCourant = new double[10];

                //archive.Serialisation(_RNN);

                //while (erreur > 0.10 * 0.1 && _iEpochsCompleted < 40)
                while (_iEpochsCompleted < 70)
                {
                    // initialisation

                    for (int i = 0; i < 841; i++)
                    {
                        VecteurEntree[i] = 0.0;
                    }

                    for (int i = 0; i < 10; i++)
                    {
                        VecteurCible[i]   = 0.0;
                        VecteurCourant[i] = 0.0;
                    }

                    // Boucle
                    if (Definitions.mnistApprentissageDatabase.indexNextPattern == 0)
                    {
                        m_HiPerfTime.Start();
                        Definitions.mnistApprentissageDatabase.RandomizePatternSequence();
                    }
                    // Randomize pattern
                    // Pad 28 ==> 29

                    byte[] padImage = new byte[29 * 29];

                    //byte[][] padImage = new byte[29][];
                    //for (int i = 0; i < padImage.Length; ++i)
                    //    padImage[i] = new byte[29];


                    uint iPattern = BaseApprentissage.GetNextPattern();
                    Definitions.mnistApprentissageDatabase.result[iPattern].pixels.CopyTo(padImage, 0);
                    Label = Definitions.mnistApprentissageDatabase.result[iPattern].label;


                    // Label = BaseApprentissage.

                    for (int i = 0; i < 841; i++)
                    {
                        VecteurEntree[i] = 1.0;  // 1 Blanc et 0 noir
                    }
                    for (int hauteur = 0; hauteur < 28; ++hauteur)
                    {
                        for (int largeur = 0; largeur < 28; ++largeur)
                        {
                            VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[largeur + 28 * hauteur]) / 128.0 - 1.0;
                            //VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[hauteur][largeur]) / 128.0 - 1.0;
                        }
                    }

                    for (int i = 0; i < 10; i++)
                    {
                        VecteurCible[i] = -1.0;
                    }

                    VecteurCible[Label] = 1.0;

                    VecteurCourant = BackpropagateNeuralNet(VecteurEntree, VecteurCible, _memorizedNeuronOutputs, _form, this.Distorsion);

                    dMSE = 0.0;
                    for (int i = 0; i < 10; ++i)
                    {
                        dMSE += (VecteurCourant[i] - VecteurCible[i]) * (VecteurCourant[i] - VecteurCible[i]);
                    }
                    dMSE     /= 2.0;
                    _dMSE    += dMSE;
                    _dMSE200 += dMSE;

                    // Calcul seuil d'erreur
                    if (dMSE <= (0.10 * Convert.ToDouble(OCR.Properties.Settings.Default.EstimatedCurrentMSE)))
                    {
                        Backpropagate = false;
                    }
                    else
                    {
                        Backpropagate = true;
                    }

                    _nn++;
                    int    iBestIndex = 0;
                    double maxValue   = -99.0;

                    for (int i = 0; i < 10; ++i)
                    {
                        if (VecteurCourant[i] > maxValue)
                        {
                            iBestIndex = i;
                            maxValue   = VecteurCourant[i];
                        }
                    }

                    if (iBestIndex != Label)
                    {
                        erreurReconnaissances++;
                    }
                    else
                    {
                        bonneReconnaissances++;
                    }

                    // make step
                    string s = "";
                    if (_nn >= 200)
                    {
                        _dMSE200 /= 200;
                        erreur    = _dMSE200;
                        s         = "MSE:" + _dMSE200.ToString();

                        double partielpourcentage = ((float)erreurReconnaissances * 100) / (float)Definitions.mnistApprentissageDatabase.indexNextPattern;

                        _form.Invoke(_form._DelegateAddObject, new Object[] { 2, partielpourcentage });

                        _dMSE200 = 0;
                        _nn      = 0;
                    }

                    s = String.Format("{0} Miss Number:{1} Bonne reo {2}", Convert.ToString(Definitions.mnistApprentissageDatabase.indexNextPattern), erreurReconnaissances, bonneReconnaissances);
                    if (_form != null)
                    {
                        _form.Invoke(_form._DelegateAddObject, new Object[] { 5, s });
                    }

                    if (Definitions.mnistApprentissageDatabase.indexNextPattern >= nombre - 1)
                    {
                        m_HiPerfTime.Stop();
                        _dMSE /= Definitions.mnistApprentissageDatabase.indexNextPattern;
                        Definitions.mnistApprentissageDatabase.indexNextPattern = 0;

                        double pourcentage = ((float)erreurReconnaissances * 100) / (float)Definitions.mnistApprentissageDatabase.imageCount;

                        s = String.Format("Epochs:{0}, Pourcentage:{1}, Temps {2}, erreurs:{3} ",
                                          Convert.ToString(_iEpochsCompleted + 1), Convert.ToString(pourcentage), m_HiPerfTime.Duration, erreurReconnaissances.ToString());

                        if (_form != null)
                        {
                            _form.Invoke(_form._DelegateAddObject, new Object[] { 3, s });
                        }

                        erreurReconnaissances = 0;
                        bonneReconnaissances  = 0;
                        _iEpochsCompleted++;
                        Definitions.mnistApprentissageDatabase.indexNextPattern = 0;
                        _dMSE = 0;
                    }

                    compteur++;

                    if (Backpropagate == true)
                    {
                        Definitions.rnn.Backpropagate(VecteurCourant, VecteurCible, 0, _memorizedNeuronOutputs, nombreBackPropagation);
                    }
                }

                archive.Serialisation(Definitions.rnn);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }
Example #5
0
        public void CalculateNeuralNetTest(double[] inputVector, double[] cibleVector, double[] courantVector, NeuroneSortieListe neuroneSortieListe)
        {
            _RNN.etat = i++;



            _RNN.CalculateTest(inputVector, cibleVector, courantVector, neuroneSortieListe);
        }
Example #6
0
        public void CalculateNeuralNet(double[] inputVector, double[] cibleVector, double[] courantVector, NeuroneSortieListe neuroneSortieListe, bool Distorsion)
        {
            _RNN.etat = i++;

            if (Distorsion != false)
            {
                GenerateDistortionMap(1.0);
                ApplyDistortionMap(inputVector);
            }

            _RNN.Calculate(inputVector, cibleVector, courantVector, neuroneSortieListe);
        }
Example #7
0
        public void TestPattern(int pattern)
        {
            // int patternCourant = pattern;
            byte Label;
            int  matrice = Entree * Entree;

            NeuroneSortieListe _memorizedNeuronOutputs = new NeuroneSortieListe();

            double[] VecteurEntree  = new double[matrice];
            double[] VecteurCible   = new double[Sortie];
            double[] VecteurCourant = new double[Sortie];

            //double[] VecteurEntree = new double[841];
            //double[] VecteurCible = new double[10];
            //double[] VecteurCourant = new double[10];

            m_HiPerfTime.Start();

            //for (int i = 0; i < 841; i++)
            for (int i = 0; i < matrice; i++)
            {
                VecteurEntree[i] = 0.0;
            }
            for (int i = 0; i < Sortie; i++)
            {
                VecteurCible[i]   = 0.0;
                VecteurCourant[i] = 0.0;
            }
            byte[] padImage = new byte[29 * 29];

            //uint iPattern = BaseApprentissage.GetNextPattern();

            // patternCourant = (int)iPattern;
            BaseApprentissage.result[pattern].pixels.CopyTo(padImage, 0);
            Label = BaseApprentissage.result[pattern].label;

            for (int i = 0; i < matrice; i++)
            {
                VecteurEntree[i] = 1.0;      // 1 Blanc et 0 noir
            }
            for (int hauteur = 0; hauteur < Entree; ++hauteur)
            {
                for (int largeur = 0; largeur < Entree; ++largeur)
                {
                    VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[largeur + 28 * hauteur]) / 128.0 - 1.0;
                    //VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[hauteur][largeur]) / 128.0 - 1.0;
                }
            }

            for (int i = 0; i < Sortie; i++)
            {
                VecteurCible[i] = -1.0;
            }

            VecteurCible[Label] = 1.0;

            VecteurCourant = BackpropagateNeuralNet(VecteurEntree, VecteurCible, _memorizedNeuronOutputs, Label, _form);

            int    iBestIndex = 0;
            double maxValue   = -99.0;

            for (int i = 0; i < Sortie; ++i)
            {
                if (VecteurCourant[i] > maxValue)
                {
                    iBestIndex = i;
                    maxValue   = VecteurCourant[i];
                }
            }


            string s = "";

            s = "lblChiffreReconnu : " + iBestIndex.ToString();

            if (_form != null)
            {
                _form.Invoke(_form._DelegateAddObject, new Object[] { 8, s });
            }

            if (_form != null)
            {
                _form.Invoke(_form._DelegateAddObject, new Object[] { 9, VecteurCourant });
            }
        }
Example #8
0
        public void TestThread()
        {
            int  patternCourant = 0;
            byte Label;
            int  reconnu    = 0;
            int  nonreconnu = 0;
            int  matrice    = Taille * Taille;

            FileLog.SetLogFile(".\\Log", "Test_");

            FileLog.Info("Début du Test");

            NeuroneSortieListe _memorizedNeuronOutputs = new NeuroneSortieListe();

            double[] VecteurEntree  = new double[matrice];
            double[] VecteurCible   = new double[Sortie];
            double[] VecteurCourant = new double[Sortie];

            m_HiPerfTime.Start();

            while (patternCourant < nombre - 1)
            {
                for (int i = 0; i < matrice; i++)
                {
                    VecteurEntree[i] = 0.0;
                }
                for (int i = 0; i < Sortie; i++)
                {
                    VecteurCible[i]   = 0.0;
                    VecteurCourant[i] = 0.0;
                }
                byte[] padImage = new byte[29 * 29];

                uint iPattern = BaseApprentissage.GetNextPattern();

                patternCourant = (int)iPattern;
                BaseApprentissage.result[patternCourant].pixels.CopyTo(padImage, 0);
                Label = BaseApprentissage.result[patternCourant].label;

                for (int i = 0; i < matrice; i++)
                {
                    VecteurEntree[i] = 1.0;  // 1 Blanc et 0 noir
                }
                for (int hauteur = 0; hauteur < Entree; ++hauteur)
                {
                    for (int largeur = 0; largeur < Entree; ++largeur)
                    {
                        VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[largeur + 28 * hauteur]) / 128.0 - 1.0;
                        //VecteurEntree[1 + largeur + 29 * (hauteur + 1)] = (double)((int)(byte)padImage[hauteur][largeur]) / 128.0 - 1.0;
                    }
                }

                for (int i = 0; i < Sortie; i++)
                {
                    VecteurCible[i] = -1.0;
                }

                VecteurCible[Label] = 1.0;

                VecteurCourant = BackpropagateNeuralNet(VecteurEntree, VecteurCible, _memorizedNeuronOutputs, Label, _form);

                int    iBestIndex = 0;
                double maxValue   = -99.0;

                for (int i = 0; i < Sortie; ++i)
                {
                    if (VecteurCourant[i] > maxValue)
                    {
                        iBestIndex = i;
                        maxValue   = VecteurCourant[i];
                    }
                }

                string s = "";
                if (iBestIndex != Label)
                {
                    nonreconnu++;

                    s = "Pattern No:" + patternCourant.ToString() + " Valeur reconnue:" + iBestIndex.ToString() + " Valeur actuelle:" + Label.ToString();
                    FileLog.Info(s);
                    if (_form != null)
                    {
                        _form.Invoke(_form._DelegateAddObject, new Object[] { 6, s });
                    }
                }
                else
                {
                    reconnu++;
                }

                s = "Image No:" + patternCourant.ToString() + " Nombre bonne reco:" + reconnu.ToString() + " Mauvaise reco:" + nonreconnu.ToString();

                if (_form != null)
                {
                    _form.Invoke(_form._DelegateAddObject, new Object[] { 7, s });
                }
                //else
                //{
                //    s = patternCourant.ToString() + ", Mis Nums:" + reconnu.ToString();
                //    if (_form != null)
                //        _form.Invoke(_form._DelegateAddObject, new Object[] { 7, s });
                //}
            }
        }
Example #9
0
        public void Calculate(double[] INVector, double[] CibleVector, double[] CourantVector, NeuroneSortieListe pNeuronOutputs)
        {
            int count          = 0;
            var premiereCouche = Couches.First();

            if (Couches.Count > 1)
            {
                foreach (var neuron in premiereCouche.neurones)
                {
                    if (count < premiereCouche.neurones.Count)
                    {
                        //neuron.Sortie = 9;
                        neuron.Sortie = INVector[count];
                        count++;
                    }
                }


                // Calcul sur les couches cachées
                for (int i = 1; i < Couches.Count; i++)
                {
                    Couches[i].Calculate();
                }

                // Charge la sortie
                if (CourantVector != null)
                {
                    var lit = Couches[Couches.Count - 1];

                    for (int i = 0; i < lit.neurones.Count; i++)
                    {
                        CourantVector[i] = lit.neurones[i].Sortie;
                    }
                }


                if (pNeuronOutputs != null)
                {
                    pNeuronOutputs.Clear();
                    pNeuronOutputs.Capacity = Couches.Count;

                    foreach (CoucheBase cc in Couches)
                    {
                        var coucheSortie = new NeuroneSortie(cc.neurones.Count);
                        for (int i = 0; i < cc.neurones.Count; i++)
                        {
                            coucheSortie.Add(cc.neurones[i].Sortie);
                        }

                        pNeuronOutputs.Add(coucheSortie);
                    }
                }
            }
        }
Example #10
0
        /// <summary>
        /// Commence avec la dernière couche
        /// </summary>
        /// <param name="actualOutput"></param>
        /// <param name="desiredOutput"></param>
        /// <param name="count"></param>
        /// <param name="neuroneSorties"></param>
        public void Backpropagate(double[] actualOutput, double[] desiredOutput, int count,
                                  NeuroneSortieListe pMemorizedNeuronOutputs, int nombreBackPropagation)
        {
            int nombreNeurones = 0;

            // Au moins 2 couches
            if (Couches.Count < 2)
            {
                return;
            }

            if ((actualOutput == null) || (desiredOutput == null))
            {
                return;
            }

            if (nombreBackPropagation % NbPalierBackpropagation == 0)
            {
                double eta = this.EtaInitial;
                eta *= this.Eta;
                if (eta < this.MinimumEta)
                {
                    eta = this.MinimumEta;
                }

                this.TauxApprentissage = eta;
            }

            int taille = Couches.Count;

            nombreNeurones = Couches[Couches.Count - 1].neurones.Count;

            var dErr_wrt_dXLast = new ErreurListe(nombreNeurones);
            var differentials   = new List <ErreurListe>(taille);

            // Calcul sur la dernière couche

            for (int i = 0; i < nombreNeurones; i++)
            {
                dErr_wrt_dXLast.Add(actualOutput[i] - desiredOutput[i]);
            }

            for (int i = 0; i < taille - 1; i++)
            {
                var m_differentials = new ErreurListe(Couches[i].neurones.Count);
                for (int k = 0; k < Couches[i].neurones.Count; k++)
                {
                    m_differentials.Add(0.0);
                }
                differentials.Add(m_differentials);
            }
            differentials.Add(dErr_wrt_dXLast);

            bool Memorise = (pMemorizedNeuronOutputs != null);

            for (int j = taille - 1; j > 0; j--)
            {
                if (Memorise != false)
                {
                    Couches[j].Backpropagate(differentials[j], differentials[j - 1],
                                             pMemorizedNeuronOutputs[j], pMemorizedNeuronOutputs[j - 1], TauxApprentissage);
                }
                else
                {
                    Couches[j].Backpropagate(differentials[j], differentials[j - 1],
                                             null, null, TauxApprentissage);
                }
            }

            differentials.Clear();
        }