Bonjour,
Je cherche à coder une bibliothèque de réseau de neurones avec les algorithmes d'apprentissages qui vont avec.
J'ai commencé par une méthode de monte carlo (poids générés aléatoirement et je ne garde la solution que si elle est meilleure que la précédente, c'est-à-dire avec une plus faible erreur quadratique), qui fonctionne.
Maintenant j'essaye de mettre en place un algorithme de rétropropagation du gradient sur un MLP.
Le problème c'est qu'il ne converge pas du tout quelque soit le taux d'apprentissage que je choisisse, la fonction a approximer et les fonctions d'activations des couches cachées (non linéaires).
Mes poids (initialisés de manière gaussienne) ne divergent pas mais l'erreur quadratique ne diminue pas même après des millions d'itérations.
En fait j'ai constaté empiriquement que mon MLP approxime systématiquement une fonction constante égale à la moyenne des sorties théoriques de mes données d'entrainement. Je ne sais pas si c'est très clair, donc voici un exemple. Si je cherche à approximer la fonction f(x)=x avec les données d'entrainement 1->1; 2->2 ; 7->7 alors mon MLP donne (après apprentissage) toujours 3,33.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        for(int i = 0; i < nbOfExamples; ++i)
        {
            // On calcule les deltas de la dernière couche
            // k est un neurone de la couche de sortie, et getDerivativeValue() c'est la dérivée de la fonction d'activation qui pour la dernière couche est la fonction f(x) = x donc f'(x) = 1
            for(int k = 0; k < nbOfOutputs; ++k)
                outputs.setDelta( 2 * (desiredOutputs[k] - calculatedOutputs[k]) * outputs.getDerivativeValue() );
 
            // on met à jour les poids de la dernière couche
            foreach (neuron currentNeuron, outputs)
            {
                foreach (neuron inputOfCurrentNeuron, currentNeuron.getInputs())
                {
                    inputValue = inputOfCurrentNeuron.getValue();
                    formerWeight = currentNeuron.getWeight(inputOfCurrentNeuron);
 
                    // On applique la règle du delta
                    newWeight = formerWeight + learningRate * currentNeuron.getDelta() * inputValue;
                    currentNeuron.setWeight(inputOfCurrentNeuron, newWeight);
                }
 
                currentNeuron.setBias(currentNeuron.getBias() + learningRate * currentNeuron.getDelta());
            }
 
            // calcule les deltas des couches cachées et applique les nouveaux poids au couches précédentes
            retropropagateError(learningRate);
 
            MQE = meanQuadraticError(inputVector, desiredOutputs);
        }
Le code compile mais pour simplifier la compréhension je l'ai un peu changé.

Est-ce que quelqu'un aurait une idée de ce qui ne va pas?
Ce serait super cool de m'aider à trouver une solution car j'ai passé plusieurs semaines entières à chercher une solution sans rien trouver. Je suis un peu dans une impasse.
Merci d'avance,
Léonard Henriquez