Bonjour,
Cela fait plusieurs jours que j'essaye d'implémenter un algorithme de retro-propagation du gradient sur un réseau de neurones de type perceptron multicouches, sans succès.
Mon domaine étant plus le code que les notations mathématiques, j'éprouve quelques difficultés à déchiffrer celles-ci.
J'ai actuellement un réseau de neurone à taille et a nombre de couche dynamique. Celui-ci s'exécute correctement, mais cela ne sert pas a grand chose sans l'algo d'apprentissage qui va avec !
Ce que je pense avoir compris à propos de la retro-propagation:
On part de la dernière couche (output layer) et on analyse les différences entre l'output voulue et l'output obtenu. J'ai décidé d'utiliser pour cela la fonction tangente hyperbolique.
Cela donne : g'(resultatAttendu) - g'(resultatActuel) avec g' = tanh' = 1 - tanh
Cela me donne une représentation numérique de l'erreur qui est censée être propagée selon la responsabilité de chaque neurone sur l'erreur grâce a la formule :
Je recalcule ensuite mes poids grâce la formule :
Un premier problème semble apparaitre : les poids ne font que descendre jusqu'à atteindre 0.
Mon code est de ce type pour l'apprentissage d'un XOR
Creation réseau (2, 2, 1)
while (NombreEssaisJuste d'affilé < 1000)
{
input[0] = rand()%2;
input[1] = rand()%2;
resultat = reseau.run(input);
if (resultat != XOR(input))
reseau.learn(input, desiredOutput);
}
J'ai donc beaucoup de zones d'ombre :
Comment choisir les poids au départ ? (entre 0 et 1 ?)
Dans mon cas j'utilise la fonction d'activation tanh. Qu'est-ce que la zone de transition et comment savoir si un neurone s'active lorsqu'il est proche de 0 ? ( actuellement mon neurone s'active si tanh(valeur) > 0. La valeur étant la somme des poids synaptiques multipliée par 0 ( si le neurone est activé ) ou 1( dans le cas contraire )))
Mes poids doivent-ils changer dans le cas ou le résultat de mon réseau est juste ? Si oui, selon quelle formule ( car actuellement, je calcule l'erreur, donc 0 dans le cas ou l'output est juste, et j'applique le calcul ci dessus soit erreur * coef d'apprentissage * xj, ce qui fait 0 et donc réduit mon poids à 0... ) ?
Le biais, ou threshold ou seuil, est-il une variable contenue dans le neurone définissant le seuil a dépasser ? Si oui, comment dois-je l'initialiser et le corriger ?
Dois-je corriger tous les poids avant de les mettre à jour ?
Actuellement mes entrées et sorties sont des bits (bool), mais est-il possible d'utiliser un double par exemple ?
Ce type de réseau est-il adapté pour faire une IA, pour un jeu par exemple ? ( actuellement, j'essaye de lui faire apprendre un xor avec un réseau a 2 entrées, 2 neurones cachés, et 1 sortie, donc j'en suis loin ).
Comment faire en sorte que son réseau puisse prendre un nombre d'entrées variable ?
C’est à dire que mon nombre d'entrées augmente au fur et à mesure ? (quid des nouveau poids ?)
Comment comparer une sortie à un résultat lorsque nous ne savons pas ce que nous voulons obtenir directement ? ( Encore une fois, dans un jeu, je ne sais pas directement si l'action que le réseau a fait va contribuer à la victoire/défaite de celui-ci)
Malgré toute la doc que j'ai lu, j'ai l'impression que ceux qui expliquent ces réseaux ne s'adressent qu'a des mathématiciens. Les rares exemples clairs que j'ai trouvés m'ont permis d'améliorer ma compréhension énormément !
Je pourrais fournir mon code, mais l'idéal serait une explication d'un cas concret comme celui du XOR, avec un tour d'application de l'algorithme de rétro-propagation.
Merci d'avance, je suis preneur de tout lien (anglais ou français) pouvant m'aider (si possible sans trop de notations complexes).
Partager