| Bonjour à tous,
Je vois que sur ce forum les réponses apportées sont souvent pertinentes et intéressantes (ce qui n'est pas le cas de tous les forums il faut bien le dire...), donc je vais tenter ma chance à mon tour !
Voilà : je suis entrain de coder un réseau de neurone destiné à la reconnaissance de caractères manuscrits (je ne m'intéresse ici qu'aux chiffres, mais bon le principe est le même...). Mon réseau est un perceptron multi-couche :
- 1 couche d'entrée de 64 neurones (images de 8*8 pixels)
- 1 couche cachée au nombre de neurones variable
- 1 couche de sortie de 10 neurones (de 0 à 9)
J'utilise bien entendu un algorithme de rétroprogation du gradient pour le calcul des poids.
Pour l'apprentissage j'utilise une base de donnée de 3823 images de 8*8 pixels en niveaux de gris et environ 1800 pour les vérifications (cette base est gratuite et disponible à cette adresse : http://www.ics.uci.edu/~mlearn/MLRepository.html dans la section 'optdigits').
Au début mon réseau ne fonctionnait pas ou peu, comme pour un certain nombre d'entre vous (je suppose). J'ai alors décidé de paramétrer tout le réseau :
- fonctions de transfert à paramètres (et non pas une simple sigmoïde) : j'entends par là f(x) = 1/(1+exp(a*x)) translatée de plus entre -1 et 1 pour une meilleure efficacité (a variable)
- nombre de neurones de la couche cachée
- coefficient d'apprentissage : coeff pour la modification des poids : w = w +b*modif (b variable)
En procédant de la sorte on obtient tout de suite des résultats très satisfaisants et je pense que les documents que l'on peut trouver sur le sujet n'insistent pas assez sur ce point.
(personnellement j'ai trouvé a=(de 0,08 à 0,12 ) environ, et b entre 0,1 et 1 : b ne change pas grand chose à l'efficacité du réseau mais peut accroîrte la rapidité des calculs..).
En fait ce que je veux faire c'est étudier ce réseau à fond, et trouver les paramètres qui permettent d'obtenir un réseau le plus efficace possible (l'efficacité du réseau est pour moi la reconnaissance par le réseau des images de la base de vérification qui n'interviennent pas dans l'apprentissage, ainsi que le coût d'apprentissage ou la durée d'apprentissage ou le nombre de modification des poids lors de l'apprentissage, comme on veut).
J'ai déjà fait tourné mon PC pendant de nombreuses heures (une bonne journée au moins, et oui c'est très long !!!...), et certains résultats m'étonnent.
- Pour le paramètre des sigmoïdes tout ce passe comme je l'imaginait : si on représente l'efficacité en fonction du paramètre on obtient une forme de parabole avec un minimum (qui correspond pour mon réseau à 0,115 environ). Donc de ce côté là tout va bien !
- par contre plus j'augmente le nombre de neurones de la couche cachée et plus le réseau est efficace, aussi bien au niveau de la base de vérification qu'au niveau du coût des calculs (sans toutefois aller trop loin sinon le coût n'est pas négligeable) : moi qui pensait que le "bon nombre de neurones" de cette couche serait de l'ordre du nombre de neurones de la couche de sortie (comme c'est parfois conseillé dans les documents), j'obtiens des couches avec près de 20 à 100 neurones !!!
Est-ce que quelqu'un pourrait m'expliquer cela ??
Sinon concrètement pour l'efficacité j'obtient un taux de réussite au minimum de 3% sur la base d'apprentissage (ce qui fait quand même environ 60 exemples non reconnus) et bien sûr 100% sur la base d'apprentissage. J'obtiens de plus environ 60% d'efficacité sur des images que j'ai moi même scanées.
C'est pas mal, mais est-ce qu'il y a moyen d'améliorer ces résultats ??
Merci de vos réponses,
Matthieu Répondre à matmdx | Salut Matthieu,
Ca fait plaisir d'avoir un problème aussi bien posé !
Bon, y'a plein de choses à dire, alors je pense que je répondrai en plusieurs fois...
Avant tout, merci pour l'adresse de la base d'exemples, c'est toujours utile, des trucs comme ça.
Ce que tu fais là, c'est un travail de recherche de niveau mastere, alors si c'est pas indiscret... Tu fais quoi, dans la vie ?
Bon, première remarque sur tes 3 paramètres :
Le coefficient d'apprentissage (b) est très classique, et utilisé par tout le monde, normalement. Tu as bien identifié ce qu'il faisait, accélérer le calcul, mais pour être plus précis, il faut trouver un juste milieu : s'il n'est pas assez grand, ton réseau met des plombes à s'entrainer, mais s'il est trop grand, tu perds en finesse, et tu risque d'osciller (donc perdre du temps), voire de ne pas trouver le minimum global (les poids optimaux). Une solution simple et généralement employée, c'est d'avoir un paramètre variable : tant que les variations des poids se font dans le même sens, tu augmentes b à chaque pas de calcul, et quand tu sens que tu t'approche des poids optimum, tu diminues b à chaque pas.
Mon conseil : laisse tomber ce problème, il a été et est encore étudié, mais pour un raiseau donné qui doit faire un travail donné, si tu as un b qui a l'air de bien marché, n'y touche pas !
Deuxième paramètre : a
Je n'ai jamais entendu parler d'une paramétrisation de la fonction de transfert, et je dois dire que tes résultats me paraissent... étonnants. Je m'explique : tu me donnes l'impression d'avoir super bien étudié la question, puisque tu obtiens un paraboloïde avec un minimum bien marqué. Donc c'est une question qui mérite d'être approfondie ! Peut-être que tu es un précurseur sur ce point (on peut toujours rêver. En tout cas, je ne pourrais pas me prononcer avec certitude : je ne travaille pas dans le milieu des RN actuellement !). Mais juste une chose : est-ce que tu as bien réalisé cette "expérience" (parce que je sais que c'est long, l'expérimentation sur les RN, alors si tu as déterminé une parabole avec seulement 5 points, avant de breuveter ta découverte, vérifie ! Bon, OK, c'est un peu exagéré, mais c'était pour te montrer ce que je voulais dire) ?
En fait, si je me permets de douter, c'est pas pour rien : tu es d'accord pour dire que les poids sont des valeurs réelles (théoriquement) ? Donc la somme des entrées pondérées également. Et la valeur de sortie d'un neurone (en supposant par exemple qu'elle est comprise entre -1 et 1) doit pouvoir s'approcher de 1 ou de -1. J'en déduis (mais c'est à vérifier) que si tu peux obtenir un résultat en un temps donné avec une faible valeur de a, donc une sigmoïde "étirée", tu dois pouvoir obtenir le même résultat avec une sigmoïde "normalisée" (a=1), dans le même temps, juste en jouant sur le taux d'apprentissage b ! (dans ce cas, b sera plus faible). Peut-être que tu as fait ton test avec une valeur de b fixée qui favorisait effectivement a=0,115. A ce moment là, on retombe sur le problème de l'optimisation de b. Peut-être aussi que ta méthode, pour étirer les sigmoïdes, permet d'avoir plus de précision avec un codage fixé pour les réels. Mais je pense que des floatants sur 16 bits sont largement suffisant précis pour enregistrer des poids (puisque cette précision est négligeable devant b).
Quoi qu'il en soit, ces paramètres a et b n'interviennent que pour la rapidité d'apprentissage, et pas pour l'efficacité du réseau proprement dit.
On en arrive donc à la partie intéressante : le nombre de neurones de la couche cachée. Avant tout, il n'y a pas de recette miracle pour trouver le bon nombre de neurone d'une couche ! Il n'y en a jamais eu, et si certains textes conseillent de mettre le même nombre dans la couche cachée que dans la couche de sortie, il ne faut pas leur faire confiance ! En fait, ça pourrait marcher, si tu avais autant de neurones dans la couche d'entrée que dans celle de sortie : tu n'aurais aucune raison de changer ce nombre entre les 2 (et encore ! Ca dépend pour quoi faire !). Maintenant, pour passer de 64 à 10, il faut trouver un juste milieu qui peut effectivement être à 5 comme à 500 neurones ! Personellement, j'aurais commencé avec 40 (ça, c'est juste par expérience, je peux pas t'expliquer pourquoi en fait).
Mais il y a un point sur lequel j'aimerais revenir : tu utilises des "couches" abstraites qui ne tiennent pas compte de l'aspect "dessin" (donc planaire) de la représentation d'un chiffre. Alors je sais, on peut se dire que les connections vont se faire et se défaire au fil de l'apprentissage pour lier les neurones "proches", c'est-à-dire qui apparaissent souvent ensemble. Mais il reste un problème : a aucun endroit dans ton réseau tu n'indiques que 2 neurones voisins sur la grille d'entrée sont voisins par leur influence sur le réseau et peuvent éventuellement se substituer l'un à l'autre ! Il y a donc tout un paquet d'informations importantes dont tu ne te sers pas.
Il existe une solution bien plus adaptée à la reconnaissance de formes (donc de caractères) dans la catégorie RN : les cartes auto-organisatrices et tout ce qui en découle (j'en ai parlé plusieurs fois plus haut). Mais ne te décourage pas pour autant ! Ton réseau n'est peut-être pas ce qui se fait de mieux pour la reconnaissance de chiffres, mais il présentes un intérêt théorique, et peut même être utile pour un autre usage (à toi de découvrir). Et dans ce cas, ta base d'exemple, même en n'étant composée que de chiffres (donc de matrices) est un base comme une autre pour tester ton réseau !
Elle est peut-être juste un peu grande par rapport à la taille de ton réseau, ce qui te fait perdre un peu de temps : je pense qu'une cinquantaine d'exemples par caractère sont largement suffisants pour l'apprentissage !
Bon, c'est pas tout ça mais il se fait tard, donc la suite dans la semaines... N'hésites pas à répondre ! Surtout si tu n'es pas d'accord avec ce que j'ai dit ;-p
Devine si tu peux, et choisis si tu l'oses Répondre à franky* |
| Eh bien ! ça n'a pas traîné !
Merci Franky* pour ta réponse.
>>> Tu fais quoi, dans la vie ?
Je suis en prépa maths !!! :-)
En fait je travaille sur ce sujet dans le cadre de mes TIPE...
>>> Coefficient b :
Je ne reviens pas dessus car on semble être d'accord.
>>> Coefficient a :
Je te confirme que j'ai réalisé des mesures très précises (et que d'autres sont prévues) : pour chaque couple de paramètres ( a , nombre de neurone de la couche cachée) j'entraîne 10 réseaux et je récupère pour chacun le nombre de modification des poids et le nombre de chiffres reconnus sur la base de test, puis ensuite j'effectue une moyenne des 10 valeurs... En effet je ne peut pas effectuer les mesures sur seulement 1 réseau, les poids initiaux étant choisis aléatoirement !
J' ai donc réalisé ces mesures pour 160 couples de paramètres (!!!) pour obtenir une belle surface en 3D !
J'observe donc la décroissance pour les neurones cachés et la cuvette pour le coeff a, pour le nombre de modifications.
J'observe la décroissance pour les neurones cachés, et une cuvette (applatie d'un côté) pour l'efficacité.
(si tu veux des images, je peux te les envoyer par mail)
J'aime bien ton idée de compensation de a par b et vis versa, et je vais voir si ça se vérifie expérimentalement. De toute manière je comptais réaliser à nouveau les mesures pour d'autres coeff d'apprentissage a.
>>> La couche cachée :
Ta réponse me rassure ! Merci ! ;-)
>>> Influence des neurones proches :
C'est vrai, dans mon réseau un neurone n'influence pas ceux qui sont proches de lui. J'avoue que je n'avais pas pensé à le faire, mais qu'aussi je ne vois pas trop comment le faire... faudra que tu me ré-expliques ça plus en détail... si ça apporte vraiment quelque chose pour ce type de réseau. (je verrais plutôt ça dans des réseaux de type Hopfieldiens...)
>>> La taille de la base d'apprentissage :
Je compte également réalisé des mesures en fonction de la taille de la base, mais ce que j'ai constaté sur quelques exemples (et ce qui me paraît tout à fait logique) pris pour des valeurs différentes de la taille de la base, c'est que l'efficacité est meilleure plus il y a d'exemples ! Par contre c'est vrai le coût d'apprentissage est moindre pour des bases plus petites (logique aussi).
>>> Les autres types de réseaux :
Tu vas rire, mais je compte également réalisé 2 autres réseaux de type carément différents (pour la reconnaissance de caractères toujours), pour de même effectuer des mesures, et au final comparer l'efficacité des 3 réseaux !! :-)
Je compte réaliser très prochainement :
- un réseau de type carte auto-organisatrice de Kohonen (comme tu me le conseille), mais je ne pensais pas que c'était lui le meilleur (d'après toi)
- un réseau de type mémoire auto-associative de Hopfield (j'avais déjà essayé, mais ça marchait pas... mais je compte recommencer !)
Je ne suis pas au bout de mes peines !!!
Et tu peut être certain que j'aurais besoin d'aide pour régler ces reéseaux !
Encore merci pour ta réponse,
@ très bientôt,
Matthieu Répondre à matmdx | Salut,
>>Je suis en prépa maths !!! :-)
>>En fait je travaille sur ce sujet dans le cadre de mes TIPE...
Eh ben ! Ca, c'est ce qui s'appelle s'ouvrir à d'autres choses ! (je suis passé par là aussi ;-) ) Tu vises l'IMAG ? Les ENS ?
Si un jour, après une école, tu veux continuer dans la recherche, y'a une équipe dans mon labo qui s'occupe exclusivement des RN... J'en profite pour leur faire de la pub ! (équipe cortex au loria) Tu pourras toujours me recontacter à ce moment-là !
Pour le coef a, c'est bien ce que je pensais : t'as super bien fait ça !
Préviens-moi si ça se confirme... Ca a l'air d'être un résultat sympa.
L'influence des neurones proches, en fait, c'est du type Kohonen. J'y reviens après.
Pour la base d'apprentissage, il faut faire attention : a partir d'un moment, si tu augmentes trop sa taille, tu perds beaucoup de temps d'apprentissage pour un gain en précision négligeable...
Mais il ne faut pas non plus passer d'un extrême à l'autre : j'imagine que tu as entendu parler de surapprentissage (overfitting en anglais) ? Sinon, ça vaut le coup de chercher de quoi il s'agit, pour ce que tu fais...
Tant que tu y es, cherches aussi des infos sur le "compromis biais-variance", ça fera toujours bien quand tu passeras l'oral.
En résumé, la variance, c'est l'erreur d'estimation liée au manque de données (ce qui ne risque pas de t'arriver, là !), et le biais, c'est les erreurs d'approximation liées aux hypothèses, à la forme du modèle. Le problème c'est que pour un ensemble de données fixe, tu ne peux pas diminuer l'un sans augmenter l'autre... D'où la recherche d'un compromis.
Mais dans ton cas, ça veut surtout dire que tu as suffisemment de données pour ne pas avoir peur de complexifier (raisonnablement) ton modèle. Et également que tu n'as pas forcément besoin de toute ta base d'apprentissage.
Euh... désolé, je suis un peu parti dans mon trip, là... ;-p
Revenons aux différents types de réseaux, et pour commencer, le bon vieux Hopfield : c'est simple, je te le déconseille purement et simplement. Et ne t'en fait pas pour ton TIPE, c'est tout a fait justifiable de dire que les recherches récentes t'ont fait penser que tu n'avais pas intérêt à t'engager sur une voie sans avenir...
Je m'explique, il est possible que ce type de réseaux puisse présenter un intérêt. C'est d'ailleurs un peu mon domaine (IA distribuée, SMA, etc.). Le problème, c'est qu'on ne sait pas QUEL intérêt ! Parce qu'il y a une manière "naturelle" d'utiliser ces réseau, pour l'apprentissage, sauf qu'il ne sont pas très performants ! Ce qui fait que la recherhce dans ce domaine est un peu dans une impasse pour le moment... Ils présentent bien quelques avantages, avec en premier plan celui de reconnaitre des prototypes très fortements dégradés (images bruitées, ...). Seulement, on est obligé de lui faire apprendre par coeur ces prototypes, et sa capacité de mémorisation n'est pas géniale : de l'odre de 0,15 x le nombre de neurones, en comptant un neurone pour un pixel dans le cas de la reconnaissance d'images !
Maintenant, le Kohonen. Lui aussi, il a ses avantages et ses inconvénients. D'abord, il est très adapté à la reconnaissance de caractères, grace à la propriété dont je t'ai parlé hier : il sait reconnaitre des formes proches ! Par contre (il me semble l'avoir dit plus haut dans le discussion), dans ce cas, il y aura absolument besoin d'un prétraitement ! (sauf si tu sais que tous tes caractères ont la même taille, sont centrés, et ne sont pas trop bruités).
Mais surtout, il y a un point fondamental qui te concerne particulièrement : ta base d'exemples est visiblement utilisable pour un réseau de type perceptron, c'est-à-dire pour faire de l'apprentissage supervisé. J'en déduis que chaque image est associée à la bonne "réponse", le chiffre dessiné. Or les réseaux de type kohonen sont fait pour de l'apprentissage non supervisé : dans le cas où tu n'as qu'une collection d'images sans catégorie associée, un tel réseau est capable de rassembler ces images par ressemblance. D'où leur nom de cartes auto-organisatrices.
Ce qui veut dire que tu ne vas pas utiliser à fond toutes les ressources qu'offre ta base d'exemples, et il est finalement possible (même si ça m'étonnerait) que le perceptron marche mieux que Kohonen dans ton cas !
Bon, je te laisse méditer ça (autrement dit, on m'attend pour faire autre chose que mon autiste sur l'ordi ;-p ),
Bon courage !
Devine si tu peux, et choisis si tu l'oses Répondre à franky* |
|
|