Actions sur le document

Réseaux de neurones 2

Planète Juridique - admin, 7/05/2014

Ce billet est la suite de celui-ci qu'il est préférable de lire avant mais c'est vous qui voyez.

Après quelques heures passées sur l'apprentissage du langage Go, je me suis résolu à revenir à mes fondamentaux: le langage C. Cela fait 20 ans que je n'ai pas codé sérieusement, et j'ai eu peur de perdre trop de temps à m'initier à un nouveau langage. Ce qui suit va faire sourire tous les développeurs actuels et définitivement me décrédibiliser auprès d'eux...

Il y a 20 ans, j'étais chercheur et je programmais sur une station de calcul Apollo, dans un environnement de développement équivalent à vi (sous Domain/OS). J'appelais quelques routines graphiques de base, à une époque où l'environnement graphique informatique était en pleine révolution. Mes langages favoris étaient le langage OCCAM et le langage C.

Lorsque de chercheur, je suis devenu professeur en école d'ingénieurs, j'ai enseigné le langage C. La mode était alors au Turbo C de Borland. Mon enseignement n'incluait pas la partie graphique. Mes étudiants se contentaient très bien des tableaux de pointeurs de fonctions de structures doublement chaînées, et des envois de données sur le réseau.

Me voici donc aujourd'hui (enfin, il y a quelques mois), à me demander ce qui pouvait être utilisé comme IDE aujourd'hui, avec tous les progrès informatiques. Je me suis dit qu'un environnement multiplateformes pourrait être intéressant, pour profiter du meilleur des univers Windows ou GNU/Linux.

J'ai choisi Code::Blocks.

Me voici donc en train de compiler quelques programmes simples trouvés sur les différents sites d'initiation à cet IDE. Je redécouvre alors la joie de compiler un code source, d'éditer les liens avec les bibliothèques standards, et de voir les premiers "Hello world" à l'écran. J'ai eu une petite pensée pour Dennis MacAlistair Ritchie...

Très vite, je me suis retrouvé à écrire quelques procédures de calcul concernant les réseaux de neurones. J'ai créé mon premier réseau, mes premières structures, mes premiers malloc (et à chaque malloc son free correspondant ;-).

Comme 20 ans auparavant, j'ai vite trouvé l'affichage standard limité: il me fallait tracer des courbes, des nuages de points, des évolutions de critères en cours de minimisation. Il me fallait appeler quelques fonctions graphiques...

Et là... Grosse déception !

En 20 ans de foisonnement d'interfaces graphiques et d'amélioration de processeurs spécialisés, aucune bibliothèque graphique SIMPLE n'a l'air de s'être imposée. Un truc du genre: j'ouvre une fenêtre, je dessine un pixel dedans quand je veux et basta. Si je suis sous Windows, ça m'ouvre une fenêtre Windows, si je suis sous GNU/Linux, et bien ça m'ouvre une fenêtre GNU/Linux... Bon, j'avoue que je n'ai pas beaucoup cherché, et je compte un peu sur vous pour me montrer la voie si je me suis fourvoyé.

J'ai choisi la bibliothèque graphique SDL parce que pas mal de sites ont l'air de dire que c'est très bien pour s'initier. Ça tombe bien, parce que je ne souhaite pas devenir un professionnel du graphisme, je veux juste dessiner quelques courbes.

Ce qui m'a un peu surpris, c'est de devoir "bidouiller" Code:Blocks pour que mes premiers programmes utilisant SDL puissent fonctionner (je n'ai pas conservé les messages d'erreur, mais j'ai ramé). Heureusement, pas mal de monde utilise le combo Code::Blocks + SDL et la communauté publie des tutos bien faits.

Me voici donc en train de faire mes premières courbes. Bon, mes programmes sont devenus beaucoup moins lisibles maintenant que je les ai truffé d'appels à des routines graphiques plus ou moins claires, mais j'ai compris les bases du truc. Jusqu'au jour où j'ai voulu tracer une courbe dans une nouvelle fenêtre... En effet, SDL ne permet pas d'ouvrir plusieurs fenêtres. Mais heureusement SDL2 peut le faire! Sauf qu'il faut tout réécrire car les concepts graphiques n'ont rien à voir. Je me suis donc tapé le guide de migration SDL1.2 vers SDL2.0 dans la même journée que l'apprentissage de SDL1.2. Je râle, je râle, mais je remercie tous les développeurs qui consacrent leur vie à créer tous ces outils (et les manuels qui vont avec). Je sais maintenant manipuler (un peu) les pointeurs de fenêtres et de Renderer.

Comme SDL2 est sortie en août 2013, j'ai un peu galéré à trouver comment adapter Code::Blocks pour faire fonctionner mes premiers programmes SDL2 (mais j'ai trouvé!). Et j'ai pleuré des larmes de joie quand j'ai vu mes premières courbes tracées dans deux fenêtres séparées.

J'ai ensuite pu attaquer les choses sérieuses avec la mise au point des routines d'optimisation. J'en ai déjà expliqué une partie dans ce billet. Mes premiers programmes ont consisté à mettre au point les routines suivantes:
- calcul du gradient par rétropropagation de l'erreur
- méthode d'optimisation par descente de gradient à pas constant
- amélioration de la méthode précédente avec calcul économique d'un pas variable (méthode de Wolfe et Powell)
- amélioration de la méthode précédente avec calcul itératif de l'inverse du Hessien (méthode de Broyden, Fletcher, Goldfarb et Shanno).

Je suis toujours bluffé par l'accélération foudroyante des méthodes quasi-newtoniennes pour s'approcher du minimum de la fonction.

J'en suis là aujourd'hui.
J'ai un programme illisible qui fonctionne malgré tout parfaitement: je peux créer un réseau de neurones complètement connecté qui peut apprendre virtuellement n'importe quel ensemble d'apprentissage, dès lors que celui-ci est constitué d'un nombre fini de couples {entrées connues, sorties désirées}. Je suis à la recherche d'un problème pas trop complexe, en évitant si possible tous les problèmes de classification (type mémorisations de visage ou reconnaissance de caractères). J'aimerais plutôt un problème de modélisation, comme par exemple la prédiction des éruptions du "Old Faithful" (si quelqu'un a des données récentes sur ce geyser, avec températures, pression, etc.).

Il me faut du temps pour rendre mes routines plus lisibles, pour sauvegarder les coefficients calculés, pour tester d'autres environnements, pour créer un tableur Excel et OpenOffice, pour trouver un problème intéressant à ma portée...

Il me faut aussi comprendre comment faire pour exploiter toute la mémoire de ma machine. Je n'arrive pas encore à créer des matrices de grandes tailles (du genre 10000x10000 réels double précision). Je suis pour l'instant limité à un réseau d'au maximum 50 neurones et 1224 connexions.

Mais 50 neurones, c'est déjà beaucoup ;-)








Lire l'article...

Ce billet est la suite de celui-ci qu'il est préférable de lire avant mais c'est vous qui voyez.

Après quelques heures passées sur l'apprentissage du langage Go, je me suis résolu à revenir à mes fondamentaux: le langage C. Cela fait 20 ans que je n'ai pas codé sérieusement, et j'ai eu peur de perdre trop de temps à m'initier à un nouveau langage. Ce qui suit va faire sourire tous les développeurs actuels et définitivement me décrédibiliser auprès d'eux...

Il y a 20 ans, j'étais chercheur et je programmais sur une station de calcul Apollo, dans un environnement de développement équivalent à vi (sous Domain/OS). J'appelais quelques routines graphiques de base, à une époque où l'environnement graphique informatique était en pleine révolution. Mes langages favoris étaient le langage OCCAM et le langage C.

Lorsque de chercheur, je suis devenu professeur en école d'ingénieurs, j'ai enseigné le langage C. La mode était alors au Turbo C de Borland. Mon enseignement n'incluait pas la partie graphique. Mes étudiants se contentaient très bien des tableaux de pointeurs de fonctions de structures doublement chaînées, et des envois de données sur le réseau.

Me voici donc aujourd'hui (enfin, il y a quelques mois), à me demander ce qui pouvait être utilisé comme IDE aujourd'hui, avec tous les progrès informatiques. Je me suis dit qu'un environnement multiplateformes pourrait être intéressant, pour profiter du meilleur des univers Windows ou GNU/Linux.

J'ai choisi Code::Blocks.

Me voici donc en train de compiler quelques programmes simples trouvés sur les différents sites d'initiation à cet IDE. Je redécouvre alors la joie de compiler un code source, d'éditer les liens avec les bibliothèques standards, et de voir les premiers "Hello world" à l'écran. J'ai eu une petite pensée pour Dennis MacAlistair Ritchie...

Très vite, je me suis retrouvé à écrire quelques procédures de calcul concernant les réseaux de neurones. J'ai créé mon premier réseau, mes premières structures, mes premiers malloc (et à chaque malloc son free correspondant ;-).

Comme 20 ans auparavant, j'ai vite trouvé l'affichage standard limité: il me fallait tracer des courbes, des nuages de points, des évolutions de critères en cours de minimisation. Il me fallait appeler quelques fonctions graphiques...

Et là... Grosse déception !

En 20 ans de foisonnement d'interfaces graphiques et d'amélioration de processeurs spécialisés, aucune bibliothèque graphique SIMPLE n'a l'air de s'être imposée. Un truc du genre: j'ouvre une fenêtre, je dessine un pixel dedans quand je veux et basta. Si je suis sous Windows, ça m'ouvre une fenêtre Windows, si je suis sous GNU/Linux, et bien ça m'ouvre une fenêtre GNU/Linux... Bon, j'avoue que je n'ai pas beaucoup cherché, et je compte un peu sur vous pour me montrer la voie si je me suis fourvoyé.

J'ai choisi la bibliothèque graphique SDL parce que pas mal de sites ont l'air de dire que c'est très bien pour s'initier. Ça tombe bien, parce que je ne souhaite pas devenir un professionnel du graphisme, je veux juste dessiner quelques courbes.

Ce qui m'a un peu surpris, c'est de devoir "bidouiller" Code:Blocks pour que mes premiers programmes utilisant SDL puissent fonctionner (je n'ai pas conservé les messages d'erreur, mais j'ai ramé). Heureusement, pas mal de monde utilise le combo Code::Blocks + SDL et la communauté publie des tutos bien faits.

Me voici donc en train de faire mes premières courbes. Bon, mes programmes sont devenus beaucoup moins lisibles maintenant que je les ai truffé d'appels à des routines graphiques plus ou moins claires, mais j'ai compris les bases du truc. Jusqu'au jour où j'ai voulu tracer une courbe dans une nouvelle fenêtre... En effet, SDL ne permet pas d'ouvrir plusieurs fenêtres. Mais heureusement SDL2 peut le faire! Sauf qu'il faut tout réécrire car les concepts graphiques n'ont rien à voir. Je me suis donc tapé le guide de migration SDL1.2 vers SDL2.0 dans la même journée que l'apprentissage de SDL1.2. Je râle, je râle, mais je remercie tous les développeurs qui consacrent leur vie à créer tous ces outils (et les manuels qui vont avec). Je sais maintenant manipuler (un peu) les pointeurs de fenêtres et de Renderer.

Comme SDL2 est sortie en août 2013, j'ai un peu galéré à trouver comment adapter Code::Blocks pour faire fonctionner mes premiers programmes SDL2 (mais j'ai trouvé!). Et j'ai pleuré des larmes de joie quand j'ai vu mes premières courbes tracées dans deux fenêtres séparées.

J'ai ensuite pu attaquer les choses sérieuses avec la mise au point des routines d'optimisation. J'en ai déjà expliqué une partie dans ce billet. Mes premiers programmes ont consisté à mettre au point les routines suivantes:
- calcul du gradient par rétropropagation de l'erreur
- méthode d'optimisation par descente de gradient à pas constant
- amélioration de la méthode précédente avec calcul économique d'un pas variable (méthode de Wolfe et Powell)
- amélioration de la méthode précédente avec calcul itératif de l'inverse du Hessien (méthode de Broyden, Fletcher, Goldfarb et Shanno).

Je suis toujours bluffé par l'accélération foudroyante des méthodes quasi-newtoniennes pour s'approcher du minimum de la fonction.

J'en suis là aujourd'hui.
J'ai un programme illisible qui fonctionne malgré tout parfaitement: je peux créer un réseau de neurones complètement connecté qui peut apprendre virtuellement n'importe quel ensemble d'apprentissage, dès lors que celui-ci est constitué d'un nombre fini de couples {entrées connues, sorties désirées}. Je suis à la recherche d'un problème pas trop complexe, en évitant si possible tous les problèmes de classification (type mémorisations de visage ou reconnaissance de caractères). J'aimerais plutôt un problème de modélisation, comme par exemple la prédiction des éruptions du "Old Faithful" (si quelqu'un a des données récentes sur ce geyser, avec températures, pression, etc.).

Il me faut du temps pour rendre mes routines plus lisibles, pour sauvegarder les coefficients calculés, pour tester d'autres environnements, pour créer un tableur Excel et OpenOffice, pour trouver un problème intéressant à ma portée...

Il me faut aussi comprendre comment faire pour exploiter toute la mémoire de ma machine. Je n'arrive pas encore à créer des matrices de grandes tailles (du genre 10000x10000 réels double précision). Je suis pour l'instant limité à un réseau d'au maximum 50 neurones et 1224 connexions.

Mais 50 neurones, c'est déjà beaucoup ;-)









Retrouvez l'article original ici...

Vous pouvez aussi voir...