Introduction L'objectif de mon TIPE est la reconnaissance de sons ou de notes de musique à l'aide d'un réseau de neurones. Ce réseau doit être capable d'apprendre à distinguer les exemples présentés puis de généraliser ces exemples à tout son proche des données d'entraînement. Il s'agit d'un apprentissage supervisé, c'est à dire que l'on choisit de séparer les sons en différentes catégories (ici les notes et les gammes) et d'en donner un exemple de chaque. Un réseau de neurones est une structure imitant le fonctionnement d'un cerveau; le neurone formel est une unité reliée aux autre neurones, capable de recevoir de l'information, de la traiter puis de l'envoyer aux autres neurones. De la même façon qu'un journaliste traite différemment ses sources selon la confiance qui leur attribue, un neurone accord un certain poids aux informations reçues. Les neurones sont organisés de façon hiérarchique, "par couches", et l'ensemble est appelé réseau. L'information avance, couche par couche, depuis l'entrée du réseau qui traite les données jusqu'à la sortie renvoyant les résultats. On notera l'importance des connexions entre neurones caractérisées par les "poids" de ces liaisons. I Étude rapide du réseau - Apprentissage -On cherche à classer des notes de musique, ce qui revient à approcher la fonction qui au son associe sa hauteur et sa gamme. Approcher une fonction linéaire est très simple à l'aide d'un seul neurone. [schéma+explication brève?)] On définit l'erreur commise par le réseau comme la différence entre la sortie voulue sur l'exemple et la sortie réelle proposée par le réseau. (En pratique on se servira de la distance N 2 entre les deux n-uplets ) On peut alors associer sur un exemple donné, l'ensemble des poids du réseau à l'erreur, ce qui nous donne une fonction de R n dans R +, on veut désormais minimiser cette fonction. Le principe de la rétro-propagation est simple, on mesure l'effet d'une petite variation d'un poids sur l'erreur (dérivée partielle) et le gradient ainsi obtenu nous permet de nous "diriger" avec une vitesse donnée, appelée "pas", vers une erreur plus faible. En pratique, je modifie la dernière couche pour diminuer l'erreur puis je déduit de ce travail, la sortie de l'avant dernière couche qui aurait donné un erreur minimale (à l'aide cette fois-ci des dérivées partielles par rapport aux entrées des neurones), on obtient alors la sortie désirée pour cette avant dernière couche et on réapplique le principe de façon récursive à toute les couches. On constate alors la convergence du réseau vers une erreur minimale. II Application à la reconnaissance des notes. Le programme a été réalisé en plusieurs étapes, nécessaires pour obtenir une représentation efficace du réseau de neurones. Une première vision récursive, se prêtant bien à l'algorithme de rétro-propagation des erreurs n'a pas été retenue notamment à cause de la représentation peu claire des réseaux qui était nécessaire pour rendre l'algorithme efficace. Une seconde possibilité, en stockant un réseau sous une forme de matrices contenant les poids (vision inspirée du cours de sciences.ch), a également été mise de côté en raison de son caractère trop formel sans gain réel de rapidité
(utiliser une multiplication en O(n 3 ) sur des matrices diagonales est trop coûteux pour un gain de clarté trop faible). Enfin j'ai mis au point une version utilisant des enregistrements ce qui permet de concilier clarté (on utilise des appels comme : reseau.couche.neurone.poids ) et efficacité. type neurone= {poids: float array; mutable activation : float; mutable sortie:float;mutable sensib: float} type reseau=neurone array array Le réseau n'est évidement pas capable de traiter du son de façon brute, afin de lui fournir les données représentatives je me suis orienté vers la Transformée de Fourrier rapide, qui permettrait à un humain de classer aisément les notes par hauteur et gamme. -L'algorithme que j'ai utilisé est très simple: sur un exemple, on propage l'entrée dans le réseau puis on étudie la sortie et on modifie les poids par rétro-propagation des erreurs et on recommence jusqu'à ce que l'erreur passe en dessous d'un seuil défini à l'avance. On exécute cet algorithme sur tous les exemples jusqu'à ce que l'erreur globale soit faible. (voir Le programme) A l'aide d'un logiciel synthétiseur, nous avons fabriqué des fichiers midi de toutes les notes de 4 gammes jouées par plusieurs instruments auxquels j'ai appliqué la transformée de Fourrier. Le réseau s'est alors entraîne pendant environ 10 heures puis nous l'avons testé sur des accords (sur lesquels il n'était pas entraîné) de deux notes simultanées. On obtient alors le type de profil d'erreur (erreur au cours de l'apprentissage) suivant:
III Problèmes rencontrés lors de la convergence et solutions appliquées. La convergence d'un réseau vers la solution la plus efficace reste cependant très lente et non garantie. J'ai observé plusieurs problèmes récurrents lors des différents essai dont: la non convergence du réseau, l'instabilité de la convergence et la non généralisation. -Si l'algorithme ne converge pas, cela provient souvent de la difficulté de ce qu'on lui demande, disproportionnée par rapport à ses capacités. En effet, plus le réseau comporte de réseau, plus son pouvoir de résolution est important, le nombre de couche est également important (une couche ne peut résoudre que des problèmes linéaires alors que 3 suffisent généralement pour la plupart des problèmes). On peut donc essayer d'augmenter le nombre de neurones sur les différentes couches afin d'obtenir une convergence. Cependant il ne faut pas tomber dans l'excès inverse car un plus grand nombre de neurones augmente considérablement le nombre de liaisons donc le temps d'exécution de l'algorithme. (Il est toujours plus long de comprendre des choses difficiles) -l'instabilité du réseau peut se caractériser par le profil d'erreur suivant:
On obtient ce résultat lorsqu'on se trouve dans une "cuvette d'erreur" très étroite. Le pas d'avancement est peut alors trop grand et fait augmenter l'erreur même selon la direction du gradient. Pour résoudre ce problème, il faut alors savoir doser avec justesse le pas: trop grand, on risque de ne pas aboutir, trop faible la convergence est trop lente. Après avoir essayé de déterminer de façon automatique la valeur optimale du pas, j'ai opté pour une modification manuelle en cours d'entraînement. (Cependant les résultats obtenus en utilisant un pas que l'on pourrait qualifier d'inertiel (il augmente si l'erreur diminue et décroît si elle augmente) ont été assez prometteurs). -Le problème le plus gênant reste la non-généralisation du réseau, si celui-ci apprend parfaitement les exemples, ils peut cependant ne rester qu'un perroquet et se contenter de répéter ce qu'on lui a appris. Cela peut venir de plusieurs causes: le surentraînement, la sous capacité, la non-représentativité des exemples ou tout simplement le hasard! En effet, si l'on fixe le critère d'arrêt à une erreur très faible, le réseau peut alors perdre sa capacité à reconnaître de nouvelles données pour se focaliser sur les exemples. Le cas de la sous-capacité avait déjà été traité dans la non convergence, il suffit d'augmenter la taille du réseau. Enfin, le choix des exemples doit se faire avec attention: ils doivent être caractéristiques de leur catégorie (un mi bémol joué par un harmonica n'est pas vraiment représentatif de cette note!). Une amélioration de l'algorithme consiste à utiliser une validation croisée, il suffit de trouver deux sets d'exemples, l'un servant pour l'apprentissage, l'autre n'étant pas appris mais utilisé pour "valider" l'apprentissage c'est à dire vérifier la capacité de généralisation. L'algorithme se poursuit jusqu'à la validation, ce qui permet donc d'essayer d'éviter le "syndrome du perroquet". IV Résultats obtenus. Les résultats obtenus bien qu'imparfaits sont tout de même satisfaisants: la valeur ajoutée par le réseau montre une qu'une certaine linéarité a été acquise: la superposition de deux notes est comprise par le réseau ce qui n'est pas nécessairement évident. Nous avons généré la séquence suivante : ( a3 e4 ) c3 (g3 a4) g3 e4 a3 <- les indicatifs des notes testées (note+n de gamme), les
couples simultannés sont entre parenthèses. Les notes sont jouées successivement et tous les dt le réseau cherche à reconnaitre les notes. Seules les notes dont la sortie est supérieure à 0.3 sont représentées. 3a : 0.960967, 4a : 0.349771, (Reconnaissance du 3a et d'une note non jouée 4a qui correspond à une harmonique plus faible) 3a : 0.914490, 4a : 0.708136, 4e : 0.998923, 3a : 0.813077, 4e : 0.979943, 3a : 0.915108, (le réseau reconnait le doublet) 3a : 0.918132, 3c : 0.918148, 3f : 0.333713, (le réseau reconnait de même la fondamentale et l'harmonique suivante) 3c : 0.999911, 3c : 0.999937, 3c : 0.999998, 3c : 0.999943, 4g : 0.799655, (la note g3 commence à apparaitre sous la forme d'une de ses harmoniques) 3g : 0.976730, 3c : 0.418872, 3g : 0.999526, 3g : 0.997690, 4a : 0.786821, 4d : 0.435190, 3g : 0.999684, 4a : 0.984059, 4a : 0.797480, 3d : 0.648038, (le g3 disparait au profit d'un de ses harmoniques) 4g : 0.521302, 3g : 0.366555, 3a : 0.304001, 3g : 0.999369, 4a : 0.344807, (4a disparait alors que g3, la note seule suivante, se reforme) 3g : 0.998643, 3g : 0.999672, 4e : 0.985177, 3g : 0.431237, 4e : 0.999328, 4e : 0.999946, 4e : 0.999937, 4e : 0.812526, 3a : 0.993638, 3a : 0.998970, 3a : 0.998070, 3a : 0.998617, 3a : 0.998713 La capacité de généralisation est réelle puisque des tests sur des notes générées avec d'autres instruments (flûte, piano et harpe) ont données également d'excellents résultats. De même on aurait pu tester la capacité du réseau à reconnaître des triplets de notes simultanées. Conclusion: Ce TIPE permet de répondre à plusieurs des questions que je me suis posées: ->Un réseau de neurones est-il de l'intelligence artificielle? Il semble qu'on ne puisse pas qualifier notre réseau d'intelligent, pour plusieurs raisons. Tout d'abord, ce réseau est hyper-spécialisé et ne peut extrapoler les exemples appris que dans une certaine mesure: sons légèrement différents, simultanéité des notes mais certainement pas plus complexe sans risque d'erreur importante. De plus, la nécessité d'un apprentissage supervisé rend notre réseau comparable plus à un chien savant qu'à un une véritable intelligence. Enfin, la grande rigidité de ce réseau dans sa structure (liaisons synaptiques qui ne peuvent pas de détériorer au cours du temps, organisation par couches donc pas de cycles et manque de
souplesse dans la propagation), ne permettra jamais au réseau d'évoluer plus qu'une limite fixée dès la génération du réseau. En effet, un tel réseau ne pourra jamais, à moins de changer sa structure, comprendre la voix humaine ou tracer une partition. -Le réseau de neurones est-il un outil rapide?... Non, le réseau nécessite un grand nombre d'exécution de l'algorithme avant d'être opérationnel. En moyenne, plusieures heures sont nécessaires pour l'entraîner correctement sur 28 notes et quelques doublets. En revanche, une fois entraîné, le réseau est extrement rapide (environ 8000 propagations par secondes). -> Quel est alors l'interêt d'un réseau de neurones. Le réseau est spécialisé dans le classement de données, il peut ainsi apprendre à trier un grand nombre d'éléements à partir de quelques exemples bien choisis. Remerciements à: Thierry Artieres, professeur à Paris 6 pour ses conseils très utiles pour améliorer la convergence du réseau. M. Blain, mon prof de physique pour ses conseils sur la présentation du tipe. Ankush Sethi, un étudidant américain. Le Programme (très simplifié pour une meilleure lecture) :