IA : RN : VBPerceptron : le code le + simple possible

en VB6 & VB .Net

 

Mise à jour de la page : 04/06/2005

Versions 0.20 (VB6) et 0.53 (VB .Net) du 04/06/2005

 

Table des matières

Introduction : Le Perceptron multicouche

Prédiction ponctuelle et prédiction à moyen terme avec une fenêtre glissante

Représentativité de l'apprentissage

Configuration et optimisation du Perceptron : le RN autoconfigurant

Stratégie d'apprentissage

Questions sur l'apprentissage

Questions sur la fonction d'activation

Comment choisir la fonction d'activation ?

Y a-t-il plusieurs types de fonction d'activation dans le même réseau ?

Pourquoi changer le centre de la fonction d'activation (biais) ?

Normalisation des entrées et des sorties entre 0 et 1

Analogie entre le neurone biologique et le Perceptron

Méta-Apprentissage et Conscience Artificielle : le projet IALib

Améliorations

Utilisation du jeu de validation pour éviter le sur-apprentissage

Un benchmark des réseaux de neurones : Proben1

Divers

Amélioration des démos

Projets envisagés

Apprentissage et prévision de la conjoncture économique

Dictionnaire

ChatBot Hyperlogotron (robot de discussion)

Apprentissage musicale

Traducteur automatique

Nombre premiers

Reconnaissance de caractères majuscules isolés

Reconnaissance de visages

Reconnaissance vocale

Autres démos

Versions

Prochaine étape

Version 1.20 du 01/04/2002

Version 1.10 du 01/02/2002

Version 1.00 du 24/11/2001

Version 0.53 du 04/06/2005 : version minimale en VB .Net

Version 0.52 du 28/03/2005 : version minimale en VB .Net

Version 0.51 du 15/08/2003 : version minimale en VB .Net

Version 0.50 du 09/01/2003 : version minimale en VB .Net

Version 0.20 du 09/01/2003 : version minimale en VB6

Version 0.12 du 01/04/2002

Version 0.11 du 01/02/2002

Version 0.10 du 24/11/2001

Liens

Téléchargement du Microsoft .Net Framework

 

 

Introduction : Le Perceptron multicouche

 

Un réseau de neurones (RN) du type Perceptron multicouche (MultiLayerPerceptron) est capable d'apprendre à peu près n'importe quoi : une porte logique XOR, une fonction sinus, les lettres de l'alphabet (OCR), les taches solaires, les résultats du loto, le CAC40...

 

Ce logiciel est, à l'origine (version 0.10), la traduction en Visual Basic du logiciel mlp en C++ de Sylvain BARTHELEMY : www.sylbarth.com.

 

C'est un "apprentisseur" universel : il est capable d'apprendre une fonction de transfert entre un signal d'entrée et un signal de sortie de façon entièrement automatique grâce à la technique de la rétropropagation, cf. l'introduction au RN suivante : www.isib.be/Etudiant/eln3/intro.htm

 

Le réseau de neurones peut apprendre puis reconnaître des signaux très variés et prédire tout ce qui est plus ou moins cyclique !

 

A force d'améliorer le Perceptron, le code s'est étoffé, mais obscurcis. Pour que la programmation du Perceptron soit réutilisable facilement, j'ai entièrement repris l'essentiel des fonctionnalités de base, et enlevé le reste. J'ai fait aussi une version en VB .Net (finalement, 95% du code est automatiquement bien migré et directement fonctionnel, y compris le code de l'interface de l'application, pas mal !). Par ailleurs, ce code contient une implémentation successive de 5 fonctions d'activation différentes, ce qui est assez rare à trouver sur le web selon mes recherches. Pour cela, j'ai du démêler ce qui relevait de l'optimisation de l'implémentation, de l'algorithme générale du Perceptron, ce qui n'est pas forcément trivial lorsque le développeur n'indique pas les assomptions sur lesquelles sont fondées ses optimisations (voir les remarques sur la dérivée de la fonction d'activation dans le code source).

Lien : www.vbfrance.com/code.aspx?ID=5612

 

Pré-requis pour les logiciels .Net : comme tout logiciel .Net, la version .Net du Perceptron requiert l'installation de la plate-forme .Net, elle est disponible gratuitement pour tous les systèmes d'exploitation Windows de bureau >= 98.

 

 

Prédiction ponctuelle et prédiction à moyen terme avec une fenêtre glissante

 

Les modes de prévision ponctuelle et à moyen terme fonctionnent lorsque l'apprentissage n'est réalisé que sur une partie seulement des données, le reste des données servant à évaluer le taux de prévision ponctuelle à partir des données apprises, ainsi que le taux de prévision cumulées à partir des données extrapolées au fur et à mesure que l'on se projette dans le futur. D'une façon pratique, il faut utiliser une fenêtre glissante sur les données du fichier de façon à éviter de dupliquer les lignes d'apprentissage, mais cela complique le code : des exemples avec la prévision des taches solaires, du CAC40 et du Loto sont disponibles ici : www.vbfrance.com/code.aspx?ID=2181 (seulement en VB6 pour le moment)

La reprise de l'implémentation de la fenêtre glissante fera partie de la prochaine étape, sinon le Perceptron ne sert pas à grand chose en fait ! (les séries temporelles constituant une bonne part des applications intéressantes)

 

 

Représentativité de l'apprentissage

 

La qualité des résultats dépend beaucoup de la représentativité de l'ensemble d'apprentissage. De plus, le réseau de neurones ne converge pas toujours en fonction du tirage aléatoire des poids initiaux (d'où l'idée de faire plusieurs tentatives d'apprentissage), ou bien s'il n'existe pas de séparabilité du jeu de résultats (signal cible), c'est-à-dire s'il n'existe pas une base de vecteurs indépendants pour représenter les résultats à partir du signal source (heu... là je ne suis plus très sûr :-). Même l'ordre des échantillons en entrée peut influencer l'apprentissage !

 

"On peut utiliser un réseau de neurones pour essayer d'apprendre n'importe quelle fonction numérique, mais la qualité des résultats dépend de beaucoup d'autres paramètres pour être exploitables : représentativité de l'ensemble d'apprentissage, représentation des paramètres d'entrée et de sortie, architecture du réseau, fonction numérique continue on discontinue, nature aléatoire de la fonction numérique...", cf. fr.comp.ia.

 

Note : Il est possible d'indexer les entrées de façon à filtrer les entrées incohérentes : de toute évidence, cela n'aurait pas de sens que d'apprendre des échantillons contradictoires (c'est à dire quand une même combinaison en entrée donne plusieurs résultats possibles en sortie). Cependant, il est préférable de se baser sur les statistiques pour sélectionner un jeu d'apprentissage représentatif, plutôt que de traiter soi-même les échantillons : les critères de sélection pourraient être complexes à déterminer.

 

 

Configuration et optimisation du Perceptron : le RN autoconfigurant

 

L'autre problématique du réseau de neurones est sa configuration. Si vous avez déjà testé ce genre de logiciel, vous vous êtes sans doute déjà demandé quel devait être son architecture : combien de couches votre RN devait avoir (en théorie, quatre couches suffisent dans le cas général), combien de neurones pour chaque couche, combien d'itérations faut-il prévoir, comment bien choisir les coefficients Alpha, Eta et le gain, comment choisir la fonction d'activation, ...

 

Stratégie d'apprentissage

Voici une stratégie possible pour mener à bien ces tests :

Commencez par réduire de façon drastique le nombre d'échantillon à apprendre, oubliez la prédiction pour le moment : le premier objectif est d'obtenir une reconnaissance excellente. Le nombre de couches doit être 3 ou 4, commencez par 3, et essayez 4 si le taux d'apprentissage est vraiment trop faible pour votre application. Pour le nombre de neurones par couche (intermédiaire), prenez le minimum du nombre de neurone en entrée et en sortie : tant que l'apprentissage et la reconnaissance marche bien, c'est inutile d'augmenter le nombre de neurones dans les couches intermédiaires. Ensuite, augmentez progressivement le nombre d'échantillon à apprendre, et regardez à partir de combien d'échantillon le taux d'apprentissage chute. Ensuite, posez-vous la question si vous, personnellement, vous auriez assez d'échantillons pour faire une prédiction : si oui alors essayez les prédictions, sinon, il faut augmenter leur nombre et donc le nombre de neurones ou passer à 4 couches. Enfin, vous pouvez vous préoccuper de l'optimisation de la vitesse d'apprentissage de façon à gagner du temps pour vos essais. Voilà !

 

Remarques :

- Si les échantillons à apprendre sont de même nature sur les différentes entrées du RN et que l'ordre d'apprentissage n'est pas signifiant, il faut adapter la structure du RN : par exemple pour le loto, l'ordre des boules en entrée et en sortie n'est pas signifiant, il faut donc mettre 49 neurones en entrées et en sortie (au lieu de 7 neurones sur la couche d'entrée comme je l'avait fait dans mes premiers essais) ;

- Il faut également adapter la structure du RN selon les cas où les sorties sont exclusives ou pas : ou bien vous souhaitez obtenir une décision sous forme d'un classement de reconnaissance et vous prenez ensuite une décision fondée sur ce classement, ou bien vous faites décidez le RN lui-même avec un résultat unique, ce qui change évidemment la nature de l'apprentissage (apprendre à reconnaître ou bien apprendre à prendre une décision de reconnaissance) ;

- En faisant des essais avec les tirages du loto, j'ai trouvé qu'il était difficile d'apprendre plus de 20 tirages consécutifs, au-delà, ça ne converge plus ou alors le nombre d'itérations requises explose (un RN possède une capacité d'apprentissage limitée, et plus le signal est aléatoire, plus la quantité d'information à mémoriser est grande).

 

Si cela vous semble trop complexe, trop laborieux ? pourquoi ne pas utiliser un RN autoconfigurant qui peut précisément faire à votre place ces différents tests ? consultez le document suivant, qui concerne surtout les ajustements de paramètres plutôt que le choix de la structure :

 

Configuration d'un réseau de neurones avec un méta-réseau de neurones :

http://patrice.dargenton.free.fr/ia/ialab/rnautoconfigurant.html

Je vais prochainement mettre à jour ce RN autoconfigurant, car il marche mieux maintenant, notamment car les configurations trouvées sont un peu plus stables, donc reproductibles (mais l'utilité du méta-RN n'est pas encore flagrante). Il est en VB6 seulement, mais une configuration trouvée ne dépend pas du langage.

Notes :

- La configuration de base (CoeffAjustPoid=0.9, CoeffAppr.=0.25, Gain=1) marche tout le temps, mais requiert beaucoup plus d'itérations !

- On pourrait reprendre la méthode d'indexation des entrées du méta-RN dans le code de la classe du Perceptron (fonction que l'on appellerait avant l'étape de normalisation), mais cela ne serait utile que lorsque le jeu d'apprentissage contient des contradictions ;

- Dans le document Proben1, j'ai cru comprendre que chercher à optimiser la configuration d'un RN pour améliorer l'apprentissage dans un cas donnée, n'était pas une bonne technique. Je pensais que l'optimisation serait valable pour la résolution d'un problème donnée quelque soient les données à traiter, mais selon ce document, il faudrait plutôt chercher à augmenter la capacité de généralisation pendant l'apprentissage, plutôt que de changer les paramètres du RN. Pour trancher la question, il suffit de mettre en oeuvre ce benchmark, on verra bien !

 

Questions sur l'apprentissage

- Peut-il y avoir une différence de résultat entre la fin de l'apprentissage et les tests à partir des même données ? Réponse : oui car sur la dernière itération, on continue l'apprentissage sur chaque échantillon, de sorte qu'à la fin de l'itération, il peut arriver que les résultats soient un peu modifiés, mais cela est peu probable lorsque l'erreur moyenne n'évolue presque plus ;

- Peut-on poursuivre un apprentissage en ajoutant des échantillons à un RN déjà entraîné ? Réponse : oui mais il faut réajuster les poids avec tous les échantillons, et les performances de reconnaissance risquent d'être moins bonnes que si l'on recommençait entièrement l'apprentissage depuis le début (ou alors le temps d'apprentissage des nouveaux échantillons très long).

 

 

Questions sur la fonction d'activation

 

Comment choisir la fonction d'activation ?

Il faut prendre la plus rapide en terme de temps de calcul global de l'apprentissage, quelque soit le nombre de couches intermédiaires et le nombre de neurones que le RN contient.

J'ai trouvé que pour l'apprentissage du XOR (avec 2 neurones sur la couche intermédiaire), c'est la Gaussienne qui est la plus rapide en temps de calcul (et la plus stable), avec 30 itérations seulement.

Dans certain cas, notamment celui de l'OCR, l'optimisation du temps de calcul de la reconnaissance directe une fois l'apprentissage terminé peut prévaloir sur le temps de calcul du seul apprentissage, ce qui peut alors amener à choisir une configuration plus complexe. Les autres critères généraux à considérer sont la stabilité (reproductibilité) de l'apprentissage, ainsi que la précision de l'apprentissage.

 

Y a-t-il plusieurs types de fonction d'activation dans le même réseau ?

Non ! pas dans le Perceptron multicouche : dans le document "An Introduction to Neural Networks" (www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html#algs), il est indiqué qu'un RN du type Back-Propagated delta rule network (BP) tel que le Perceptron, la fonction d'activation est la même dans tous les neurones de toutes les couches, tandis que dans un Radial Basis Function network (RBF), la fonction d'activation est une sigmoïde en sortie et une Gaussienne dans la seule couche cachée.

Cependant, certains estiment que cette vision est réductrice, et il existerait des RN du type Perceptron aussi avec plusieurs fonctions d'activation.

Quant à la fonction linéaire ou identité f(x) = x, elle existe bien et est parfois utile "pour les noeuds de sortie dans le cas de sorties gradientes non catégorielles", mais elle ne donne pas de résultat pour l'utilisation normale dans le Perceptron.

 

Pourquoi changer le centre de la fonction d'activation (biais) ?

Dans la neural network (NN) FAQ - Part 2 - à la question "Why use a bias/threshold?" (ftp://ftp.sas.com/pub/neural/FAQ2.html#A_bias), il est indiqué qu'un biais est requis dans le cas général de l'apprentissage du Perceptron (sinon l'apprentissage ne fonctionne que dans des cas particuliers) :

 

[Without a bias term, this separating hyperplane is constrained to pass through the origin of the space defined by the inputs. For some problems that's OK, but in many problems the hyperplane would be much more useful somewhere else. If you have many units in a layer, they share the same input space and without bias they would ALL be constrained to pass through the origin. The "universal approximation" property of multilayer perceptrons with most commonly-used hidden-layer activation functions does not hold if you omit the bias terms. But Hornik (1993) shows that a sufficient condition for the universal approximation property without biases is that no derivative of the activation function vanishes at the origin, which implies that with the usual sigmoid activation functions, a fixed nonzero bias can be used instead of a trainable bias.]

 

Après moult débats, la traduction proposée par des spécialistes (cf. fr.comp.ia) est la suivante :

 

[Dans le cas général, il faut un biais (variable) pour que le réseau de neurones soit un approximateur universel. Mais Hornik (1993) montre qu'une condition suffisante pour l'approximation universelle sans biais est qu'aucune dérivée (successive) de la fonction d'activation ne passe par 0 à l'origine. Ceci implique qu'avec la fonction d'activation sigmoïde classique, un biais fixe non nul peut être utilisé au lieu d'un biais variable.

 

Commentaires : Avec cette méthode (biais fixe non nul), on supprime des degrés de liberté au réseau de neurone, ce qui veut fatalement dire qu'il faudra plus de neurones pour faire la même chose. C'est quand même mieux d'ajouter des biais variables au réseau. L'implémentation la plus simple (du biais variable : "trainable") c'est d'ajouter une entrée au neurone, et de faire comme si elle était toujours à 1.

 

Détail de l'implémentation sur le RN XOR :

 

            1    1

            |    |

X1 ----o----O-\  |

        \  /   \ |

         \/     \|

         /\      O---- S

        /  \    /

X2 ----o----O--/

            |

            1

 

Il y a donc un poids supplémentaire, qui est en fait le biais. On utilise la même formule de l'apprentissage pour trouver le biais.]

 

Autrement dis, lorsqu'une dérivée de la fonction d'activation passe par zéro à l'origine, ce qui est le cas pour la gaussienne (dérivée première) ainsi que pour la sigmoïde standard et la tangente hyperbolique (dérivée seconde), l'ajout d'un simple biais fixe non nul garantit le caractère universel du RN : il suffit pour cela que le centre de la fonction d'activation soit différent de zéro, c'est tout !

Cependant, le RN convergera généralement plus vite avec un biais variable (ajout d'une entrée à 1 via un poids variable : "trainable bias"), c'est ce que j'appelle l'implémentation du "biais automatique" dans mon logiciel. Ce biais évite d'avoir à fixer une valeur arbitraire non nulle pour le centre de la fonction d'activation.

Pour l'implémentation de ce biais automatique, il suffit d'ajouter un neurone à la couche précédente (c'est-à-dire sur la première et la deuxième dans ce cas, voir sur le schéma ci-dessus), avec un signal égal à 1. Il faut cependant faire attention à ne pas rétro-propager le signal de ce neurone, qui doit rester à 1 (quoique dans le cas de la démo avec une fonction sinus à apprendre, cela permette une optimisation inégalable !). Une implémentation équivalente et plus simple consiste à ajouter un poids à chaque neurone de la couche précédente (et donc pas sur la dernière couche), toujours avec un signal égal à 1.

Pour la fonction d'activation "Pas Unitaire" qui n'est pas dérivable partout, on utilise la sigmoïde en guise de dérivée. Cependant, cette fonction d'activation ne fonctionne que lorsque le seuil du pas unitaire est situé ailleurs qu'en zéro (même avec l'implémentation du biais automatique, car la fonction n'est pas dérivable partout), c'est pour cette raison que j'ai conservé la possibilité de régler le centre de la fonction d'activation (et donc de ce seuil) dans la classe ClsPerceptronMultiCouche, en plus du biais automatique. Pour les autres fonctions d'activation, le biais peut être laissé à zéro (rCentreFctActivation = 0) lorsque le biais automatique est activé : m_bImplementerBiaisAutom = True.

Les tests réalisés avec le biais automatique font augmenter un peu le nombre d'itérations requises pour les configurations super-optimisées (moins de 100 itérations), mais par contre avec les paramètres par défaut du RN, il permet de passer de 3000 à 1000 itérations pour le XOR, et l'apprentissage est parfois plus stable (notamment pour la fonction d'activation double-seuil optimisée).

 

 

Normalisation des entrées et des sorties entre 0 et 1

 

Dans la neural network (NN) FAQ (ftp://ftp.sas.com/pub/neural/FAQ.html), il est précisé dans le chapitre 2 ("Should I normalize/standardize/rescale the data?" : ftp://ftp.sas.com/pub/neural/FAQ2.html#A_std) qu'une normalisation entre [-1, 1] est meilleure qu'entre [0, 1] : personnellement, je n'ai réussi à faire fonctionner mon RN sur [-1, 1] qu'avec la tangente hyperbolique (TH) pour fonction d'activation, à partir d'une configuration trouvée avec mon RN autoconfigurant (CoeffAjustPoid=1.7, CoeffAppr.=1.0, Gain=1.4 et CentreFA=2.8). La raison est probablement que la plage de sortie de la fonction d'activation doit aussi être entre -1 et 1, comme c'est bien le cas de la TH ; il faudrait donc peut être décaler les autres fonctions d'activation sur [-1, 1].

 

Faut-il normaliser entre [0.1, 0.9] ?

Dans ce même document, il est précisé que cela n'est pas utile lorsque l'apprentissage est correctement réalisé, et surtout, que cela fausse les estimations de probabilité associées. De toute façon, les différents paramètres du RN sont liés entre eux : à partir du moment où l'on fait varier tous les autres, il n'est probablement plus nécessaire de changer la plage de normalisation.

 

 

Analogie entre le neurone biologique et le Perceptron

 

En attendant la première preuve scientifique tangible, considérez cette analogie comme une simple plaisanterie de potache (les comiques sont plus nombreux qu'on ne le pense en science, surtout en IA ; d'ailleurs la section suivante s'inscrit bien dans ce cadre :-). Historiquement, il est cependant exact que c'est bien une telle analogie qui a été recherchée au départ (travaux de McCulloch & Pits en 1943).

Par contre, il existe de nombreuses analogies avec la psychologie cognitive qui sont pertinentes et intéressantes, par exemple la façon dont on mémorise les textes (récitation, pièce de théâtre...) ou bien les mélodies musicales : vous est-il déjà arrivé de siffler une mélodie, puis de "glisser" sans le vouloir vers une autre assez proche ? cela m'est déjà arrivé et je me suis dis que la mémoire humaine fonctionne probablement comme les modèles de Markov (qui sont proches du principe des RN), c'est-à-dire qu'en fait c'est la succession des notes qui est mémorisée, d'où l'idée de faire la même chose avec un RN, en utilisant une sorte de fenêtre glissante. Je pense que la mémorisation des textes peut fonctionner de manière analogue : c'est en fait la musicalité des mots successifs qui est mémorisée, d'où le risque de confusion entre deux textes qui ont un passage proche. Il existe aussi une façon visuelle de mémoriser les choses, qui consiste à visualiser mentalement la position relative des objets dans notre "bibliothèque mentale", mais je ne vois pas comment cette façon de mémoriser pourrait être simulée avec les RN.

 

 

Méta-Apprentissage et Conscience Artificielle : le projet IALib

 

Le projet (vb-)IALib est une librairie d'algorithmes d'Intelligence Artificielle (I.A.) génériques mais utiles et réutilisables pour traiter des problèmes concrets. Cette librairie se présente sous forme de code source de composants correspondants à des classes en Visual Basic, que l'on pourrait assembler comme un jeu de Lego créatif. Le Visual Basic permet de programmer en se concentrant à 90% sur le problème du "métier" et 10% seulement sur le langage, contrairement aux autres langages pour lesquels la proportion est souvent inverse.

 

Exemple d'algorithmes génériques qui ont prouvés leur utilité : algo. génétiques, réseaux de neurones, réseaux de Kohonen, de Hopfield, chaînes de Markov, machines de Boltzmann (avec la technique du recuit simulé : résolution du problème du voyageur de commerce), programmation par contraintes, mémoires associatives, mécanismes d'auto-régulation, vie artificielle, intelligence de groupe, systèmes multi-agents, ...

A voir aussi : des systèmes moins génériques mais tout aussi intéressants et utiles : systèmes experts, logique floue, blackboards, ... et autres algo. de jeux de réflexion (Echecs, Dames, Othello-Reversi, Bridge, ...).

 

Le Méta-Apprentissage (cf. RN autoconfigurant) consiste à apprendre à apprendre : on utilise par exemple un méta-réseau de neurones pour apprendre à configurer un réseau de neurones classique, qui lui s'occupe d'un problème concret.

 

Le point commun de toutes ces techniques, et donc l'intérêt de les regrouper dans une librairie unique, est le principe de la "boîte noire" : on ne sait pas très bien comment elle fonctionne, mais en tout cas, ça marche ! de sorte que cela alimente un peu le vieux fantasme de créer une machine qui un jour, on l'espère ou on le redoute, échappera au contrôle de son créateur, au moins en ce qui concerne ses capacités prévues ou imprévues... de là à voir émerger une sorte de "Conscience Artificielle", je ne serais pas le premier à l'évoquer :-)

 

Si vous voulez participer, par exemple en adaptant un des algorithmes cités avec une ou deux démos simples illustrant son intérêt (voir les Liens), vous êtes le bienvenu :

Projet IALib du IALab : "IA : le Laboratoire virtuel" (en rade jusqu'à nouvel ordre) : www.vbfrance.com/projetcommun.asp?ID=20

 

 

Améliorations

 

Utilisation du jeu de validation pour éviter le sur-apprentissage

Pourquoi utiliser un jeu de validation distinct du jeu d'apprentissage ?

Si l'apprentissage fonctionne bien, ou s'il y a une suite logique dans les données d'une série temporelle, alors le RN fonctionnera bien également sur les données non apprise. Dans ce cas, le fait de calculer l'erreur moyenne pour la condition d'arrêt de l'apprentissage, non pas sur le jeu d'apprentissage, mais sur un jeu de validation non appris, est une excellente mesure de la capacité de généralisation du RN. En effet, une trop grande précision d'apprentissage (sur-apprentissage) pourrait se faire au détriment de la généralisation du RN. Voilà pourquoi on utilise habituellement (voir le § suivant Proben1) 50%, 25% et 25% pour respectivement la proportion des échantillons du jeu d'apprentissage, du jeu de validation et enfin du jeu de test.

Note : dans le cas de l'apprentissage de la succession des tirages du loto, cette technique ne sera probablement pas adaptée, car on recherche d'abord un bon apprentissage avant une bonne capacité de généralisation, dont on sait qu'elle est quasi-impossible dans ce cas :-)

 

Un benchmark des réseaux de neurones : Proben1

Pour évaluer la qualité d'apprentissage et de généralisation d'un RN, et surtout pour comparer les RN entre eux, il faut utiliser un ensemble de tests standard. Un des premiers du genre, qui a mis l'accent sur l'interopérabilité et la reproductibilité des tests est le benchmark (banc d'essai) Proben1 :

ftp://ftp.ira.uka.de/pub/neuron/proben1.tar.gz (ou probenX pour les éventuelles versions suivantes)

www.ipd.uka.de/~prechelt/Biblio/1994-21.ps.gz (documentation)

Pour pouvoir effectuer ces tests, il faudra modifier le code de ce Perceptron afin de calculer les échantillons manquants (en les remplaçants par des moyennes par exemple). En effet, dans les jeux de données réelles comme c'est le cas dans Proben1, il arrive souvent que les données soient incomplètes ; ce n'est pas un inconvénient en soi, car l'intérêt des RN résident précisément en la capacité à surmonter les données manquantes. Comme autre modification requise du logiciel, il faudra aussi appliquer la condition d'arrêt de l'apprentissage sur le jeu de validation.

 

Tous les benchmarks : Neural Networks Databases - Benchmarks :

www.phys.uni.torun.pl/neural/node12.html

 

Notamment : Benchmarking of learning algorithms :

www.ipd.uka.de/~prechelt/NIPS_bench.html

 

Divers

- Initialisation des poids : dans divers documents, notamment celui de Proben1 (page 17), il est indiqué que les poids doivent être initialisé plutôt entre -0.1 et 0.1 (ou +/-0.01) qu'entre 0 et 1. En fait cela dépend du nombre de connexions, il faudrait utiliser la formule : -1/sqrt(N) et 1/sqrt(N) s'il y a N connexions ;

- Compter seulement le nombre de couches cachées : c'est une idée simple pour éviter la confusion sur le nombre de couche final du RN, elle est indiquée dans Proben1 ;

- Estimation du nombre d'itérations nécessaire : tracé de la courbe de résultat et la courbe d'erreur pour vérifier leur progression sur un grand nombre d'itérations et de tentatives et pour comparer par rapport aux meilleurs taux obtenus à un moment donné (si la courbe de résultat chute, il y a risque de sur-apprentissage, à supposer que cela soit possible -???-, et si la courbe d'erreur ne baisse plus, il y a suffisamment d'itération) ;

- Généralisation du RN autoconfigurant pour les démos autres que celle du XOR et du Sinus ;

- Fonction d'activation : autres paramètres possibles à implémenter pour la fonction double-seuil : la pente centrale et la pente de chaque coté ; autre fonction d'activation : y = x / (1+|X|) (cf. Proben1 : Page 26), fonction logistique ?

- Configuration des démos pendant l'exécution en utilisant un fichier ini (au lieu d'avoir à modifier le code source).

 

Amélioration des démos

Mode OCR : Classement des résultats des caractères reconnus, indication du caractère dans le fichier d'apprentissage, autre démo avec 1 neurone par caractère à reconnaître afin d'éviter d'avoir à traiter une indécision de reconnaissance ; exposer les neurones d'entrée et de sortie via une interface graphique et faire une démo avec des pixels "flous" (led) ;

Prévision du CAC40 par paliers en sortie : un neurone par palier de 50 ou 100 points (même chose pour les taches solaires : 10 neurones en sortie) ; autres idées intéressantes : prévision de la variation en % du CAC40 au jour le jour (ajouter les paramètres bApprendreVariation, bTracerVariation), apprendre une (ou plusieurs) moyenne mobile, combiner les trois entrées : normale / en variation / moyenne mobile avec la fenêtre glissante ;

Comparer la prévision du CAC40 et des taches solaires avec une simple extrapolation statistique classique (par exemple en exportant les données sous Excel). Problème : les régressions statistiques exigent la connaissance du modèle mathématique ;

Loto : il suffit d'un seul tirage pour prédire le suivant (le concept de tirages successifs ne fait apparemment que compliquer le procédé, et on peut très bien s'en passer), et il faut mettre 49 neurones aussi en entrée ;

Trouver un jeu de coefficients stables et optimal (avec un nombre minimum d'itération) pour toutes les fonctions d'activation : modifier la procédure du RN autoconfigurant pour qu'il teste toutes les fonctions d'activation à chaque configuration trouvée. L'idée, c'est de comparer le score global des fonctions d'activation sur plusieurs démo de façon à déterminer l'intérêt de chacune en fonction du type d'application du RN. Pour le moment, ce n'est pas clair.

 

 

Projets envisagés

 

Apprentissage et prévision de la conjoncture économique

Mettre en entrée du RN : PIB, taux d'intérêt, taux de chômage, indice des prix, de la confiance des ménages, montant des commandes, des investissements et endettement des entreprises, ... pour la France, l'Europe et les Etats Unis, et en sortie du RN : indices CAC40, Dow Jones, Nasdaq...

 

Dictionnaire

Faire un scrabble avec les lettres dans le désordre en entrée, ou bien une reconnaissance de mots dans lequel il manque une lettre (par exemple présence des seules consonnes, ou bien apprentissage des sigles), ou bien encore apprentissage des n-grammes fréquents (probabilité de succession de groupe de 2, 3 ou 4 lettres dans les mots du dictionnaire) de la langue française.

 

ChatBot Hyperlogotron (robot de discussion)

Indexer les m mots d'un texte, apprendre la succession de n mots en entrée vers le mot suivant en sortie (m*n neurones en entrée et m en sortie), les ponctuations comptant pour 1 mot. Test : vérifier que le texte est bien appris en tapant des mots dans l'ordre, puis essayer dans le désordre, engager la conversation... Pour éviter l'explosion combinatoire sur le nombre de mots, il faut les coder sur une puissance de 2, on n'a plus m neurones en sortie mais 2^NbBits = m mots. Autre possibilité : coder les lettres : c'est plus difficile, mais cela permettrait de rapprocher les mots qui se ressemblent, au lieu d'être totalement indépendant les uns des autres.

 

Apprentissage musicale

A partir d'une partition au format .Mid, apprendre les accords correspondant à une mélodie. Ensuite, lorsque l'on joue une mélodie au clavier, le smart-synthétiseur joue les accords qu'il a appris pour cette mélodie. Autre démo : reconnaissance du titre de la chanson jouée, application : détection des plagiats musicaux (7 notes consécutives identiques). En faisant le rapprochement avec le projet précédant, on pourrait imaginer aussi un parolier automatique, qui apprendrait à trouver des mots à une mélodie, ou bien à l'inverse, à trouver la mélodie évoquée par un texte, sur la base des paroles de musique existantes, tout un programme !

 

Traducteur automatique

En commençant par un facile traducteur mot à mot, puis un traducteur associant 2 mots en entrée à 2 mots en sortie, puis 3:3, un méta-RN pourrait analyser les résultats de ces 3 traducteurs afin de déterminer une décision finale. N'est-ce pas la stratégie de traduction humaine ? : confronter des méthodes de complexités croissantes tant que le résultat n'est pas probant.

 

Nombre premiers

Rechercher une suite logique (ça fait un bout de temps que l'humanité la recherche...), idée pour normaliser l'amplitude des nombres entre 0 et 9 : sommes récursives (dites "cabalistiques") des chiffres formants chaque nombre premier.

 

Reconnaissance de caractères majuscules isolés

En utilisant un système de matrice de pixels de diverses résolutions, un RN semble bien approprié à ce genre de reconnaissance, cela ne devrait pas poser de problème, cf.:

http://patrice.dargenton.free.fr/ia/rmc/index.html et

http://patrice.dargenton.free.fr/ia/rmc/rmc.html

 

Reconnaissance de visages

Pour associer les pixels aux entrées du RN, il suffit de faire une matrice de pixels capable de contenir les images de tous les visages à reconnaître. En sortie, la meilleure solution (dans le cas d'un contrôle d'accès par exemple) est de faire un neurone par personne à reconnaître : la reconnaissance consiste à classer les scores de chaque neurone et à retenir par exemple les 3 premiers, c'est-à-dire les 3 neurones les plus forts lorsqu'un visage est présenté (si la valeur du neurone le plus fort est au dessous d'un certain seuil, il s'agit d'un intrus). La difficulté pour mettre au point un tel logiciel est le réglage du nombre de pixels en entrée, par exemple 50x50 pixels requiert 2500 neurones en entrée : plus ce nombre sera élevé, plus l'apprentissage sera long mais plus le nombre de personnes distinguables par le RN sera élevé (si déjà un humain ne peut distinguer ces visages numérisés, le RN ne le pourra pas non plus). Il faut aussi rendre insensible la reconnaissance lorsque l'image est légèrement translatée, car les pixels n'ont rien à voir les uns aux autres à priori, même s'ils sont proches : la solution la plus simple est à mon avis de faire une transformée de Fourrier rapide (TFR) de l'image et de procéder à une reconnaissance sur les basses fréquences : l'avantage est que l'on est pas obligé de prendre tous les pixels de l'image, seulement les coefficients de Fourier correspondants aux basses fréquences du spectre de l'image : il faut augmenter le nombre de fréquences tant que tous les visages ne sont pas reconnus : on peut commencer par apprendre 3 visages seulement et tester la reconnaissance (tester aussi le rejet d'un intrus non appris), puis augmenter le nombre de visages en augmentant en conséquence le nombre de basses fréquences afin que la discrimination soit réalisée.

 

Reconnaissance vocale

En fixant à la fois une fenêtre spectrale et une fenêtre temporelle glissante, cela doit être faisable : la fenêtre spectrale doit permettre d'isoler et de distinguer tous les phonèmes, tandis que la fenêtre temporelle glissante, sur laquelle on calcul chaque spectre, doit permettre d'isoler la succession de chaque phonème, il suffit de trouver les réglages adéquat à chacune de ces 2 fenêtres antithétiques. C'est un peu le même problème que l'identification de la position et de la vitesse des particules en physique : on ne peut pas déterminer précisément l'un en même temps que l'autre. De même ici, il faut réduire la largeur de la fenêtre temporelle de façon à bien isoler les phonèmes sans toutefois empêcher leur reconnaissance dans la fenêtre spectrale qui elle sera rétrécie d'autant. La difficulté est ensuite de synchroniser l'apprentissage sur les fichiers audio (prononcer des phrases d'apprentissage).

 

Autres démos

Mémoire associative bidirectionnelle : nom <-> n° de tél., mémoire associative de "pattern" : des schémas qui en évoquent d'autre, détection de l'angle de rotation de patterns, tests de QI avec des séries de dessins logiques dont le dernier est à deviner, jeu d'Othello (Reversi),... proposez-en d'autres !

 

 

Versions

 

Prochaine étape

Le mode combinaison non ordonnée (une combinaison de neurones est apprise sans tenir compte de leur ordre, en sortie et en entrée si besoin est, par ex. le loto) et la Fenêtre glissante seront ajoutés à la version minimale en VB6 et VB .Net.

 

Version 1.20 du 01/04/2002

- Lien : www.vbfrance.com/code.aspx?ID=2936

- Correction du bug rRandomiser = Rnd() * (rMax - rMin) + rMin au lieu de : rRandomiser = Rnd() * (rMax - rMin + 1) + rMin et m_aCouches(i).aNeurones(j).rPoid(k) = rRandomiser(0, 1) par défaut ;

- Module spécifique pour traiter le loto : ModLoto.bas ;

- Normalisation indépendante de plusieurs entrées ;

Méta-RN : Configuration automatique du RN XOR dans une plage fixée de plusieurs paramètres ;

- La fonction d'activation double-seuil peut être utilisée à la place de la fonction sigmoïde.

 

Version 1.10 du 01/02/2002

- Lien : www.vbfrance.com/code.aspx?ID=2181

- Correction du bug sur le nombre max. de tentatives (+1) ;

bLireNombreReel : lecture des nombres négatif (oubli corrigé) ;

- Normalisation des entrées : rValMin et rValMax (au lieu de rValBoule1), elle améliore sensiblement l'apprentissage du loto ;

- Mode apprentissage avec une fenêtre glissante (indépendamment du mode loto) : ce mode permet de n'indiquer que les entrées, la sortie étant la ligne d'entrée qui suit la fin de la fenêtre, et aussi de gérer plusieurs tirages successifs ;

- Gestion du nombre maximum de lignes d'apprentissage et de lignes à prédire : on n'est pas obligé de traiter l'ensemble d'un fichier de données.

- Gestion de la sauvegarde sur disque des poids des neurones (fichier .pds) : si la case à cocher "Réinitialiser" est cochée, l'apprentissage est refait et, en cas de succès, les poids sont mis à jour dans le fichier ; si elle est non cochée, le fichier .pds est rechargé et le test est fait  sans apprentissage ;

- Tracé des courbes prévisionnelles par rapport aux courbes réelles ;

- Calcul des gains au loto ;

- Démos supplémentaires : prévision du CAC40, des taches solaires.

 

Version 1.00 du 24/11/2001

- Mode loto et mode OCR (Optical Character Recognition) : adaptation du fichier d'apprentissage et présentation spécifique des résultats ;

- Calcul du taux de résultat, multiples tentatives d'apprentissage.

 

Version 0.53 du 04/06/2005 : version minimale en VB .Net

- Lien : www.vbfrance.com/code.aspx?ID=5612

sFormater n'a jamais fonctionné en VB .Net !

  Il fallait mettre : sFormater = rReel.ToString(sFormat)

  Au lieu de : sFormater = String.Format(sFormat, rReel)

- Option Strict On.

 

Version 0.52 du 28/03/2005 : version minimale en VB .Net

- Fichier projet en version Visual Studio 2003 au lieu de 2002 ;

- Ancrage des contrôles avec des splitters pour redimensionner les zones de l'interface ;

- Simplification des duplications de tableau, exemple avec des Integers :

   MaCopieDeMonTableau = DirectCast(MonTableau.Clone, Integer())

 

Version 0.51 du 15/08/2003 : version minimale en VB .Net

Suppression des VB6.XX pour pouvoir compiler avec la version initiation de VB .Net, qui n'a pas l'interface de compatibilté avec VB6 :

- Changement de VB6.GetPath en Application.StartupPath ;

- Changement de VB6.Format en String.Format ;

- Changement de VB6.CopyArray en un redim + une boucle de copie.

 

Version 0.50 du 09/01/2003 : version minimale en VB .Net

C'est la version en VB .Net de la version 0.20 minimale en VB6 :

 

Version 0.20 du 09/01/2003 : version minimale en VB6

- Lien : www.vbfrance.com/code.aspx?ID=5612

- Correction du dimensionnement et de la sauvegarde des poids : For k = 0 To m_aCouches(i-1).iNbNeurones - 1 au lieu de .iNbNeurones : m_rVersionFichierPoids = 1.02! (il y a aussi la prise en compte du biais automatique : poids supplémentaire) ;

- Implémentation des fonctions d'activation suivantes : Sigmoïde, Tangente hyperbolique, Pas unitaire, Double-seuil, Gaussienne. Réglage possible du centre de la fonction d'activation, ou sinon utilisation du biais automatique ;

- Optimisation poussée des démos XOR et Sinus avec toutes les fonctions d'activation : moins de 100 itérations seulement sont requises pour l'apprentissage dans ces démos ; on peut maintenant apprendre 2 sinus consécutifs sans utiliser la fenêtre glissante ;

- Reprise des modifications et améliorations de base depuis les version 1.00 et supérieures (code francisé, tracé des fonctions d'activation et de leur dérivée, calcul du taux d'erreur, plusieurs tentatives d'apprentissage, apprentissage en une seule étape par rapport à la version d'origine en C++, normalisation entre 0 et 1 ou bien une autre plage avec les bornes constantes que l'on peut ajuster dans le code, ...).

 

 

Les versions 0.12 et inférieures sont fonctionnellement identiques au logiciel mlp d'origine en C++ de Sylvain BARTHELEMY : www.sylbarth.com

 

Version 0.12 du 01/04/2002

- Correction du bug RandomEqualREAL :

RandomEqualREAL = Rnd() * (High - Low) + Low  au lieu de :

RandomEqualREAL = Rnd() * (High - Low + 1) + Low

- et optimisation en conséquence par rapport à la version originale :

pLayers(i).pNeurons(j).w(k) = RandomEqualREAL(0, 1)  au lieu de :

pLayers(i).pNeurons(j).w(k) = RandomEqualREAL(-0.5, 0.5)

 

Version 0.11 du 01/02/2002

- Prise en compte de '-' dans read_number

 

Version 0.10 du 24/11/2001

 

 

Liens

 

- Code source sur VBFrance : version minimale en VB .Net (0.52) et VB6 (0.20) :

            www.vbfrance.com/code.aspx?ID=5612

- Code source en html : http://patrice.dargenton.free.fr/ia/ialab/ClsPerceptronMultiCouche.html

 

Perceptron multicouche et martingale pour le loto (en VB6, version 1.1) :

            www.vbfrance.com/code.aspx?ID=2181

- RN autoconfigurant (méta-RN) : http://patrice.dargenton.free.fr/ia/ialab/rnautoconfigurant.html

- Le méta-RN ressemble aux algorithmes génétiques (Genetic Algorithms) :

            ftp://ftp.sas.com/pub/neural/FAQ7.html#A_genetic

- Origine du logiciel Perceptron : mlp en C++ de Sylvain BARTHELEMY : www.sylbarth.com

- Projet IALib du IALab : "IA : le Laboratoire virtuel" (en rade jusqu'à nouvel ordre) :

            www.vbfrance.com/projetcommun.asp?ID=20

- Exemples de codes sources d'algorithmes de réseaux de neurones variés à adapter en Visual Basic :

            -> www.generation5.org

            -> Karsten Kutza : Neural Networks at your Fingertips :

                        www.geocities.com/CapeCanaveral/1624

- Librairie NeuroBox sur les RN en VB .Net sur SourceForge :

NeuroBox is an .Net OOP Library to generate, propagate and train complex neuronal networks with technologies like backpropagation with weight decay, momentum term, manhattan training, flatspot elimination etc., backpercolation and jordan/elman networks :

http://sourceforge.Net/projects/neurobox

- Forum IA en français : www.foorum.fr/news/list_header.asp?group=fr.comp.ia

- FAQ sur les RN en anglais : ftp://ftp.sas.com/pub/neural/FAQ.html

- Introductions claires en français sur les RN :

            www.isib.be/Etudiant/eln3/intro.htm

            http://diwww.epfl.ch/mantra/tutorial/french

            http://home.alex.tuxfamily.org/neuro/neurones.html

            www.robotic.dlr.de/Smagt/books/neuro-intro.ps.gz (en anglais)

- Projet RN et Robots : http://perso.wanadoo.fr/iar/IAr_Projet.htm

- Cours théorique sur les RN :

            www.cmla.ens-cachan.fr/Utilisateurs/lacaille/papiers.html#RN

            www.cmla.ens-cachan.fr/Utilisateurs/lacaille/papiers/rn.ps.gz

            (visualisation sous Windows avec GhoSt view : gsview32.exe)

- Lien entre système expert et RN :

http://patrice.dargenton.free.fr/ia/vbbrainbox/index.html#RNEtSE

 

Téléchargement du Microsoft .Net Framework

Pré-requis pour les logiciels .Net :

Comme tout logiciel .Net, ce logiciel requiert l'installation de la plate-forme .Net (le .Net Framework : 20 Mo, c'est en quelque sorte le runtime .Net, ou plus précisément la machine virtuelle .Net, l'équivalent multi-langage de Microsoft de la machine virtuelle Java), elle est disponible gratuitement pour tous les systèmes d'exploitation Windows de bureau de version plus récente que Windows 95 (la compilation du logiciel n'est toutefois possible que sous les systèmes de type NT : NT4, NT2000 et XP). Voici où on peut la télécharger :

 

Plateforme .Net (Microsoft .Net Framework 1.1) :

www.microsoft.com/downloads/details.aspx?FamilyID=262d25e3-f589-4842-8157-034d1e7cf3a3&displaylang=fr

 

Vérifiez également les mises à jour via votre menu Démarrer : Windows Update.

 

 

Note : il y d'autres infos dans le code source.

 

Patrice Dargenton : patrice.dargenton@free.fr

http://patrice.dargenton.free.fr/ia/ialab/perceptron.html

http://patrice.dargenton.free.fr/index.html