Accueil du site > Programmation > Programmation de réseaux neuronaux artificiels sous Linux

Programmation de réseaux neuronaux artificiels sous Linux

mardi 27 décembre 2005, par Pierre-Luc Bacon

Étant contraint par des échéances trop demandantes, mon projet de développement d’une bibliothèque de fonctions pour l’implémentation d’un algorithme de rétropropagation de l’erreur (BPNN) a été interrompu par la découverte d’un outil puissant qui sera applicable dans les délais.

Bien que la compréhension générale des principes soutenant les modèles de réseaux neuronaux puisse être assez accessible, il en est cependant tout autrement quand vient le temps d’implémenter ces concepts dans un programme. Plutôt que de coder entièrement des bibliothèques dédiées à cette fin, il serait nettement plus efficace de tirer profit des travaux déjà réalisés dans le domaine. Ainsi, la bibliothèque FANN, acronyme de Fast Artificial Neural Network Library, nous permet de parvenir à notre objectif rapidement.

FANN permet le déploiement d’algorithmes de réseaux neuronaux artificiels multicouches à rétropropagation de l’erreur (backpropagation neural network) avec accès à tous ses paramètres : pas d’apprentissage, nombre d’époques etc. Également, l’accès aux fonctions peut se faire à partir de plusieurs langages (C++, PHP, Rubby, Python, Pure Data, .NET et Delphi pour nommer que ceux-là) autant sous Linux que Windows.

Fait à ne pas négliger : il est possible d’ajuster les paramètres du réseaux de manière à l’optimiser au fil de l’apprentissage. Par exemple, cette fonctionalité s’avérerait particulièrement intéressante dans le cas d’un système dynamique d’évitement des minimas locaux.

Installation

L’installation à partir des sources se fait de manière classique. Il faut d’abord récupérer l’archive sur ce site :

http://leenissen.dk/fann/

Décompresser l’archive :

tar xjf fann-1.x.x.tar.bz2

ou

tar xzf fann-1.x.x.tar.gz

Ensuite dans le répertoire :

./configure —prefix=/usr
make
su -c "make install"

La compilation ne devrait pas poser de problèmes particuliers. Si tel est le cas, assurez-vous qu’il ne manque pas de bibliothèques essentielles, ce qui serait fort surprenant compte tenu des demandes minimales de FANN.

Exemple

Le but de cet article n’étant pas de reproduire tout le détail du manuel de référence du projet FANN, je n’élaborerai davantage sur ses fonctions. Le code présenté plus bas sera divisé en deux programmes : l’un permettant d’entraîner le réseau à partir de données, et l’autre d’exécuter le réseau une fois correctement ajusté.

Entraînement


include "fann.h"

int main()
{
       const float connection_rate = 1;
       const float learning_rate = 0.5;
       const unsigned int num_input = 2;
       const unsigned int num_output = 1;
       const unsigned int num_layers = 3;
       const unsigned int num_neurons_hidden = 4;
       const float desired_error = 0.0001;
       const unsigned int max_iterations = 500000;
       const unsigned int iterations_between_reports = 1000;

       struct fann *ann = fann_create(connection_rate, learning_rate, num_layers,
               num_input, num_neurons_hidden, num_output);

       fann_train_on_file(ann, "xor.data", max_iterations,
               iterations_between_reports, desired_error);

       fann_save(ann, "xor_float.net");

       fann_destroy(ann);

       return 0;
}

Notez ici que cette première partie provient directement du manuel de FANN et nous servira dans le cas présent à vérifier d’abord si nous parvenons à compiler un programme avec la bibliothèque et ensuite à introduire les concepts de l’API.

La compilation peut se faire ainsi :

gcc entrainement.c -o entrainement -lfann -lm -O3

S’il arrivait que vous obteniez un message d’erreur tel que :

ld : can’t locate file for -lfann

Cela peut signifier que vous ayez installé FANN dans un répertoire non reconnu par ld (dans /usr/local/lib/ par exemple). Dans ce cas, on peut procéder en définissant une variable d’environnement qui spécifie le répertoire à utiliser :

export LD_LIBRARY_PATH=/usr/local/lib/

Les étapes permettant de parvenir à un résultat sont réduites. Ainsi, suffit-il d’abord de créer un réseau en renseignant un pointeur de structure fann avec la fonction fann_create().

struct fann * fann_create(float connection_rate, float learning_rate, unsigned int num_layers, unsigned int ...);

L’argument connection_rate permet d’indiquer si le réseau sera complètement connecté avec comme valeur 1 pour une structure d’interconnection complète et 0.2 pour une autre à 20% par exemple.

Ensuite est chargé un fichier contenant les données qui formeront le corpus d’apprentissage. Celui-ci respecte la syntaxe suivante :

JPEG - 20.6 ko
Syntaxe d’un fichier de données pour la règle XOR

La fonction fann_train_on_file permet d’effectuer cette opération :


void fann_train_on_file(struct fann * ann, char * filename, unsigned int max_epochs, unsigned int epochs_between_reports, float desired_error);

Il ne reste plus ensuite qu’à enregistrer la structure finale du réseau dans un fichier et à détruire toute instance du réseau dans le programme. Les prototypes des fonctions utilisées à cette fin sont respectivement les suivants :

bool fann_save(resource ann, string filename);
void fann_destroy(struct fann * ann);

Utilisation du réseau
Cette seconde partie permettra d’établir un réseau neuronal artificiel à partir du fichier descriptif obtenu précédemment après entraînement.


#include <stdio.h>
#include <stdlib.h>
#include "floatfann.h"

int main()
{
       fann_type *calc_out;
       fann_type input[2];
       struct fann *ann = fann_create_from_file("xor_float.net");
       char ligne[10];
       int val;

printf("Entree 1:");
fgets(ligne,sizeof(ligne),stdin);
sscanf(ligne,"%d",&val);
input[0]=(fann_type) val;

printf("\nEntree 2:");
fgets(ligne,sizeof(ligne),stdin);
sscanf(ligne,"%d",&val);
input[1]=(fann_type) val;

calc_out = fann_run(ann, input);

       printf("xor test (%f,%f) -> %f\n",
               input[0], input[1], *calc_out);

       fann_destroy(ann);
       return 0;
}

Cette fois encore, les appels de fonctions sont guère plus nombreux. L’allure finale du réseau obtenu après entraînement à été retenu dans un fichier duquel sera chargé le réseau. La fonction fann_create_from_file est donc d’abord appellée à cette fin.

struct fann * fann_create_from_file(const char * configuration_file);

Sans plus d’ennuis sont évalués ensuite les entrées fournis par l’utilisateur avec fann_run.

fann_type * fann_run(struct fann * ann, fann_type * input);

Finalement, quitte le programme après avoir appellé fann_destroy qui libère la mémoire allouée dynamiquement au réseau neuronal artificiel.

Résultat
Ainsi, si vous avez correctement entraîné le réseau avec le programme entrainement.c, vous devriez obtenir un scénario du genre lors de l’exécution du programme ci-haut :

pierre-luc@goll:~/ann$ ./exec  
Entree 1:1

Entree 2:1
xor test (1.000000,1.000000) -> 0.009030

On peut donc voir ici que la réponse du système est plus que satisfaisante. En effet, il avait été convenu lors de la phase d’entraînement du réseau que l’erreur devait être minimisée au moins jusqu’à la valeur de 0.0001. Ainsi, après exécution, voici ce qui avait été obtenu :


pierre-luc@goll:~/ann$ ./entrainement
Max epochs   500000. Desired error: 0.0001000000
Epochs            1. Current error: 0.2508315742
Epochs          350. Current error: 0.0000983779

L’erreur finale après 350 époques est de 0.0000983779 alors qu’elle était de 0.2508315742 initialement. De plus, cette opération s’effectue à une vitesse impressionnante. La commande time pour le programme d’exemple entrainement sur un P4 1.5 ghz montrait ces résultats :


real    0m0.031s
user    0m0.000s
sys     0m0.000s

Le temps réel passait parfois à 0m0.010s mais se tenait généralement en dessous de 0m0.020s.

Considérant à la fois sa facilité d’utilisation ainsi que ses performances, fann est tout indiqué pour un projet en phase de développement ou en processus final. Il est certes beaucoup moins avantageux du côté pédagogique de l’utiliser, mais d’un autre, il est possible plus facilement par cet outil de s’attarder aux véritables préoccupation du projet et à sa recherche, donc d’apprendre.

Projet en suspend d’une bibliothèque pour l’algorithme BPNN :
http://pierreluc.aqra.ca/projet/Bac...

Manuel de référence pour FANN :
http://leenissen.dk/fann/html/index.html

Enregistrer au format PDF
Marquer cet article: Delicious Technorati

Répondre à cet articleRépondre à l'auteur:Pierre-Luc BaconRecommander à un ami