begin process at 2008 05 12 02:35:03
1 170 129 membres
34 nouveaux aujourd'hui
13 956 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

RESEAUX NEURONAUX : MODELE DE HOPFIELD


Information sur la source

Catégorie :Maths & Algorithmes Niveau : Initié Date de création : 29/12/2003 Date de mise à jour : 11/04/2004 17:15:46 Vu : 9 440

Note :
9,75 / 10 - par 8 personnes
9,75 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (23)
Ajouter un commentaire et/ou une note

Description

Une classe qui peut-etre utiliser pour simuler un reseaux de Hopfield (tous les neurones sont connecter a tous les autres)

Un reseau de neurone comme celui de Hopfield sert normalement a faire de la reconnaisance de forme (apres lui avoir appris ce qu'est un 1, un 2 , ... le programme peu reconnaitre des 1 , des 2 manuscrit assez proche du modele appris (comme dans les Palms)).

pas encore de ZIP mais sa va venir !!

Source

  • //Hopfield.h
  • #include <stdlib.h> //pour calloc
  • //definition d'un neurone (08/01/04 19:22)
  • class Hopfield
  • {
  • private:
  • #define egal(a,b) (a == b ? 1 : -1) //1 si egaux -1 si different
  • #define T(a) (a<0 ? -1 : 1) //signe
  • int** poids; //poids associer entre les neurones i & j : "poids[i][j]"
  • public:
  • int* sortie;
  • int nb_neurone;
  • //fonction du reseau
  • void Apprendre(int** Modele,int nb_modele); //apprendre une series de modeles
  • void Definir(int nb_neurone); //initialise tous les poids a 0
  • void Calcul_Sortie(int* entree);
  • };//fin de la class Hopfield
  • void Hopfield::Apprendre(int** Modele,int nb_modele) //apprendre une series de modeles
  • {
  • for (int i = 0; i< nb_neurone; i++)
  • for (int j = 0; j<nb_neurone; j++) //ttes les liaisons
  • for (int k=0; k<nb_modele; k++){ //ts les modeles
  • if (i==j)
  • poids[i][j]=0;
  • else
  • poids[i][j]+= egal(Modele[k][i],Modele[k][j]);
  • }
  • }
  • void Hopfield::Definir(int nb_neurone) //initialise tous les poids a 0
  • {
  • int i;
  • Hopfield::nb_neurone=nb_neurone;
  • free (poids);
  • free(sortie);
  • poids = (int**) calloc(nb_neurone,sizeof(int*));
  • sortie = (int*) calloc(nb_neurone,sizeof(int));
  • for (i=0; i<nb_neurone; i++)
  • poids[i]= (int*) calloc(nb_neurone-i,sizeof(int));
  • for (i = 0; i< nb_neurone; i++)
  • for (int j = 0; j<nb_neurone; j++) //ttes les liaisons
  • poids[i][j]=0;
  • }
  • void Hopfield::Calcul_Sortie(int* entree)
  • {
  • int modif = true;
  • int* temp;
  • temp =(int*)calloc(nb_neurone,sizeof(int));
  • for (int i = 0 ; i<nb_neurone;i++)
  • {
  • sortie[i]=entree[i];
  • temp[i]=0;
  • }
  • while (modif !=false) //tant que l'on a pas atteint un etat stable
  • {
  • modif = false;
  • for (int i= 0 ; i<nb_neurone; i++)
  • {
  • for (int j = 0 ; j<nb_neurone ; j++)
  • {
  • temp[j]+=poids[i][j] * sortie[j];
  • }
  • }//etape Calcule
  • for (int i=0; i<nb_neurone; i++)
  • if (sortie[i]!=T(temp[i]))
  • {
  • sortie[i]=temp[i];
  • modif=true;
  • }
  • }//etat stable trouver ?
  • }
//Hopfield.h

#include <stdlib.h> //pour calloc

//definition d'un neurone (08/01/04 19:22)
class Hopfield
{
private:

#define egal(a,b) (a == b ? 1 : -1) //1 si egaux -1 si different
#define T(a) (a<0 ? -1 : 1)	//signe

int** poids; //poids associer entre les neurones i & j : "poids[i][j]" 

public:

int* sortie;
int nb_neurone;

//fonction du reseau
void Apprendre(int** Modele,int nb_modele); //apprendre une series de modeles
void Definir(int nb_neurone); //initialise tous les poids a 0
void Calcul_Sortie(int* entree);

};//fin de la class Hopfield


void Hopfield::Apprendre(int** Modele,int nb_modele) //apprendre une series de modeles
{
for (int i = 0; i< nb_neurone; i++)
for (int j = 0; j<nb_neurone; j++) //ttes les liaisons
for (int k=0; k<nb_modele; k++){ //ts les modeles
if (i==j)
poids[i][j]=0;
else
poids[i][j]+= egal(Modele[k][i],Modele[k][j]);
}
}

void Hopfield::Definir(int nb_neurone) //initialise tous les poids a 0
{

int i;
Hopfield::nb_neurone=nb_neurone;

free (poids);
free(sortie);

poids = (int**) calloc(nb_neurone,sizeof(int*));
sortie = (int*) calloc(nb_neurone,sizeof(int));

for (i=0; i<nb_neurone; i++)
poids[i]= (int*) calloc(nb_neurone-i,sizeof(int)); 

for (i = 0; i< nb_neurone; i++)
for (int j = 0; j<nb_neurone; j++) //ttes les liaisons
poids[i][j]=0; 
}

void Hopfield::Calcul_Sortie(int* entree)
{
int modif = true;
int* temp;

temp =(int*)calloc(nb_neurone,sizeof(int));

for (int i = 0 ; i<nb_neurone;i++)
{
sortie[i]=entree[i];
temp[i]=0;
}

while (modif !=false) //tant que l'on a pas atteint un etat stable
{
modif = false;

for (int i= 0 ; i<nb_neurone; i++)
{
for (int j = 0 ; j<nb_neurone ; j++)
{
temp[j]+=poids[i][j] * sortie[j];
}
}//etape Calcule
for (int i=0; i<nb_neurone; i++)
if (sortie[i]!=T(temp[i]))
{
sortie[i]=temp[i];
modif=true;
}
}//etat stable trouver ?
}

Conclusion

Pour utiliser cette classe :

#include <Hopfield.h>

//pour crée le reseau :
Hopfield Nom_du_reseau(nombre_de_neurone);

Nom_du_reseau.initialise();

//pour lui apprendre un ou plusieur modele:
Nom_du_reseau.Apprendre(modeles_a_apprendre, nombre de modeles);

//pour calculer sa sortie
Nom_du_reseau.Calcul_Sortie(entree_du_reseau);

//La forme des entrée ,sortie est:
int* soit entrée[nombre_de_neurone]
              sortie[nombre_de_neurone]

//la forme des modeles est:
int** soit modele[nombre_de_modele][nombre_de_neurone]

ATT: un reseau de Hopfield ne peut pas memoiriser plus de 0.13*nombre_de_neurone modeles sinon il devient "amnesique"

Voila je crois que tout est dit !!

PS: Ce code est le sujet de mon TPE de SI merci de me le dire si vous y voyez des erreurs !
  • signaler à un administrateur
    Commentaire de MoDDiB le 29/12/2003 16:03:47

    OK mais on le trouve ou modele.h ??

  • signaler à un administrateur
    Commentaire de AlexFlt le 29/12/2003 16:52:05

    desoler j'avais oublier ce petit detail de toute façon c'etait une verssion pour attendre la je me suis connecter pour mettre la nouvelle verssion !! (beaucoup plus "pro")

  • signaler à un administrateur
    Commentaire de MoDDiB le 30/12/2003 12:14:04

    Merci c'est mieux ^^ maintenant concretement : il apprends quoi?
    Des int simple? si ce n'est que ca il faudra voir autre chose pour en mettre plein els yeux aux correcteur de tpe ^^
    Mais bon je ne crois pas avoir compris ce qu'il apprenais ni comment rééllement le faire focntionner je pense qu'un prog exemple serait le mieux !
    Merci bcoup et bonen chance !

  • signaler à un administrateur
    Commentaire de AlexFlt le 30/12/2003 16:10:40

    Je vais voir pour le prog exemple actuellement je travail sur un reseaux type perceptrons multicouche

    Concretement ce qu'il apprend sa peut-etre n'importe quoi mais dans le cas des reseau de Hopfield on essais plutot de reconnaitre des forme  par exemple si on lui apprend les 26 lettre de l'alphabet on peut realiser une application  qui quand on scanne une page du dictionnaire reconnait toutes les lettre et l'enregistre sous forme d'un TXT (concretement ces programmes s'appellent des OCR)

    Exemple:
    trier les envelope a la poste selon les code postaux :
    on a 10 caractere a reconnaitre : 0 1 2 3 4 5 6 7 8 9
    il faut donc minimum 0.13*10 Neurones soit 76 on prend 100 Neurone pour simplifier.
    nos pattern seront de 10*10 (car 10*10=100 Neurone)
    on realise le pattern du 0 puis du 1 , ... et on les apprend o reseau
    int modele_a_apprendre[10][100]={{modele du 0},{modele du 1}, ...};
    exemple de pattern(pour 160 neurones):

    int Trois[160]={
    0,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,0,
    0,1,1,1,1,1,1,1,1,1,
    0,0,0,0,0,0,1,1,1,1,
    0,0,0,0,0,0,0,1,1,0,
    0,0,0,0,0,0,1,1,1,0,
    0,0,0,1,1,1,1,1,1,0,
    0,0,1,1,1,1,1,1,0,0,
    0,0,0,1,1,1,1,1,0,0,
    0,0,0,0,0,0,1,1,1,0,
    0,0,0,0,0,0,0,1,1,0,
    0,0,0,0,0,0,0,1,1,1,
    0,0,0,0,0,0,1,1,1,1,
    0,1,1,1,1,1,1,1,1,0,
    1,1,1,1,1,1,1,1,0,0,
    0,1,1,1,1,1,1,0,0,0,
    };

    ensuite on fait:

    notre_reseau.Apprendre(nos_10_modeles, 10);

    et voila notre reseau et pres !!!

    maintenant pour l'utiliser il faut realiser un pattern de 10*10 d'un chiffre (par exemple un chiffre manuscrit assez ressemblant a un des modeles appris)

    ensuite on fait :

    notre_reseau.Calcul_Sortie(pattern_du_chiffre_manuscrit);

    puis on lit le resultat si notre chiffre manuscrit a reconnaitre été un 3, on auras dans sortie le pattern du chiffre 3 appris au depard (ou un resultat trés proche , beaucoup plus proche que le 3 manuscrit)

    comme sa on dirait que sa sert a rien!! mais faut pensser au OCR, reconnaissance de courbe,  ... il y a plein d'utilisation

  • signaler à un administrateur
    Commentaire de Kirua le 31/12/2003 01:23:53

    moi je trouve pas du tout que ça à l'air de servir à rien, je trouve ça plutôt fascinant :-)

    je vais te dire assez brièvement ce que j'ai compris, ce serait cool que tu me dises quoi par rapport à ça.

    voilà, alors il y a ces modèles, par exemple pr reprendre ton exemple, 160 bool (oui tu as mis int, mais des booléens suffiraient non?), quand le réseau reçoit un tableau de 160 booléens, il demande à tous les néurones (qui corrsepondent chacun à une place du tableau de 160) si c'est potentiellement un 0, un 1, un 2, etc... puisque le neurone 'sait' que si c'est un 0, il doit/ne doit pas être 'allumé' (true). on passe en revue tous les nombres/caractères à reconnaître, et celui qui obtient le meilleur score de conformité est choisi. alors, j'ai gagné? :-P j'ai pas lu ton code, mais c'est à ça que j'ai pensé en lisant ton commentaire.

    ciao

    Kirua

  • signaler à un administrateur
    Commentaire de AlexFlt le 31/12/2003 11:00:09

    Oui  tu a presque bien compris comment sa marche !!!
    (et effectivement des bool sa sufirait mais j'y avais pensser en faisant le code et finalement j'etait revenu a des int je ne sais plus pourquoi je pensse par simplicité pour utiliser -1 et 1 plutot que 0 et 1.

    Comment sa marche :

    1/L'apprentissage regle tous les poids

    2/ A chaque neurone correspond une place du tableau

    3/ Chaque neurone calcul sa sortie en fonction de tous les autres neurones:
                         Sortie [j]= Somme (poid[i] * S[i])
                         Sortie[j]=sortie du neurone que l'on est en train de traiter
                         Sortie[i]=sortie du neurone i
                         poid[i]=poid associé a la liaison i-j

    4/ Quand tous les neurones on ete traiter (dans un ordre aleatoire) on reprend au 3/ . Jusqu'a ce que les sortie sont "stable" (ne change plus)
    (Hopfield a demontrée que son reseaux converger donc cela devrais se produire)

    5/ La sortie du reseau est ensuite la sortie de chaque neurone quand les sorties sont "stable" (ne change plus)

  • signaler à un administrateur
    Commentaire de Kirua le 01/01/2004 17:36:10

    Dis, merci pr tes explications mais c impossible que je suive, je sais pas ce que 'poids' veut dire dans ce contexte, j'ai jamais lu d'article à propos des réseaux de neurones donc j'ai pas du tout de vocabulaire.

    Et la sorte est de type quoi? oui/non c'est ça ?

    je vias qd même lire ton code, c peut etre pas idiot :-P

  • signaler à un administrateur
    Commentaire de Kirua le 01/01/2004 17:49:52

    à mon avis c'est à cause de cette ligne-ci que tu as du avoir 1 ou -1, ceci dit, un short aurait fait l'affaire (signed short int, mais c'est short en court, tiens, bizarre) (et puis, je voudrais pas t'emmerder, surtout pas, mais un bool aurait qd même fait l'affaire avec une macro, comme tu as l'air d'aimer.

    poid[i][j]+= egal(Modele[k][i],Modele[k][j]);

    une chtite remarque, poids ça prend un s même au singulier, si c'est bien la même orthographe que le poids au sens commun. ds mon dico robert (le gros volume, mais il a qq années mtnt) y a pas poid, ça existe pas.


    ah et puis tant que j'y suis, y a un truc que je voulais dire, à propos de la 'mise en page' de ton code. moi en général je mets la définitino de la classe avec toutes ses méthodes et propriétés dans un header, puis les implémentations dans un .cpp. c'est vrmnt pratique parce qu'il suffit de lire le header pr comprendre comment la classe fonctionne (pr le programmeur qui veut l'utiliser, pas forcément svr ce qu'elle a ds le ventre, ce qui n'est pas une bonne chose ds l'absolu mais parfois bien utile)

    mais donc ici ben tout est déclaré dans le bloc class{} et (AMHA) ça tue la lisibilité. l'avantage c évidemment d'avoir qu'un seul fichier, mais alors, on peut faire une entorse et mettre les implémentations à la suite du bloc, tjs ds le header, même si c pas vrmnt tt propre (je vois pas pq ce serait faux, c juste une "convention tacite".

    vala, c t ennuyeux ce message non? lol

  • signaler à un administrateur
    Commentaire de Laurent17 le 01/01/2004 20:50:23

    Développeur de logiciel de gestion depuis de nombreuses années, je suis aujourd'hui trés intéressé par ce genre de petites routines permettant d'offrir d'excellentes options dans des applications existantes :-). Je suis peu familiarisé avec ce genre de développement mais aussi au niveau syntaxe du langage utilisé dans ce source. (Ceci dit la transcription dans le langage que j'utilise ne me semble pas être insurmontable).
    J'ai cependant compris la technique de comparaison par rapport à des modèles, mais je me pose maintenant la question de la source des données à reconnaitre. En effet si ce source donne une methode de comparaison il faut bien avoir de la "matière" à comparer.
    Quels sont alors les méthodes d'acquisition des données à comparer ? Comment peut-on par exemple reconnaitre ensuite un caractère 'noyé' au milieu d'un fichier bitmap ?
    Merci de vos lumières et bonne année à tous

  • signaler à un administrateur
    Commentaire de AlexFlt le 04/01/2004 15:55:49

    la dans le cas de ce reseau, le plus facile c'est si l'on a une image en noir et blanc. Mais je pensse que sa marche aussi avec des couleurs mais sa va etre plus dur a transmettre au reseau et il va falloir des millions de neurones. Je ne suis pas un expert en reseau de neurone, (je ne suis que en Terminale et j'ai commençé a m'interressé au reseau de neurone au debut de l'année (scolaire).).
    Mais pour la couleur je pensse que le modele de Hopfield n'est pas bon, il faudrais utiliser un perceptron.(il faut que j'en fasse un pour mon TPE donc je le mettrais sur ccpfrance.com quand il sera terminé).
    Et desoler pour l'orthographe je rajouterai un s a poid(s), et je vais voir se que je peux faire pour la lisibilité.

  • signaler à un administrateur
    Commentaire de neocracker le 07/04/2004 20:33:56

    Bonjour,
    je pense etre un peut au-retard mais bon
    il est sur qu'un programme ne peut pas contenir que se genre de systeme mais AlexFlt parlait de perceptrons multicouches celui mis a la suite du reseau d'hopfield peut permettre de meilleur resultat
    voir meme un travail du genre un calcul sans hopfield puis un avec et on prend le meilleur resultat c la qu'un systeme plus classique peut prendre le relais

  • signaler à un administrateur
    Commentaire de AlexFlt le 11/04/2004 16:58:24

    Mon TPe est maintenant terminer. Pour celui-ci j'ai utiliser une petite optimisation du programme. Elle consiste a ne pas traiter les neurones dans un ordre aléatoire mais a traité toute une couche d'un seul coup. Cela permet de gagner en vitesse de "convergeance" et surtout de simplifier le code source.

  • signaler à un administrateur
    Commentaire de AlexFlt le 11/04/2004 17:18:38

    Voila ce n'est pas la version utiliser dans le TPE (celle du TPE était en Visual Basic pour des raison de simplicité)

  • signaler à un administrateur
    Commentaire de haikoull le 26/06/2004 17:55:53

    salut, je suis nouveau dans le site!! je suis intéressé par les réseaux de neurones !! en fait j'ai un sujet auquel je doi travailler : "utilisation des réseaux de neurones pour la détection q'une configuration graphique". mais le pb c que je sais pas trop de choses sur les RN.
    si vous pouvez me donner qques liens pour la documentation et en particulier pour cette application ( reconnaissance des courbes )!! merci

  • signaler à un administrateur
    Commentaire de BumpMANN le 12/08/2004 21:56:03

    Super! nikel, 10/10. ca va me servir ;)

  • signaler à un administrateur
    Commentaire de nestorfr le 26/12/2004 00:07:25

    es bacan tambien me sirve este codigo alguien que me pueda ayudar a hacer  un proyecto  de detecion de placas de autos por favor  contactarse a nestorricardo20@hotmail.com
    o a
    nmamaniza@unsa.edu.pe

  • signaler à un administrateur
    Commentaire de delfare le 09/09/2005 17:55:16

    bon, si je comprend bien, dans apprendre :
    poid[i][j] prend comme valeur le nombre modeles qui ont le pixel i qui est le meme que le pixel j mais je ne comprend pas comment ca peut servir a retrouver a la fin quel est le modele a qui correspond le tableau entree
    merci de m'expliquer

  • signaler à un administrateur
    Commentaire de tikenjah le 10/11/2005 11:30:12

    Joli travaille c'est trop utile en plus tes explication sont claires ;)
    Merci AlexFlt !

  • signaler à un administrateur
    Commentaire de djmalo le 26/02/2006 02:42:41

    Ce code n'est pas très exact, en effet il boucle pour ne jamais converger.

  • signaler à un administrateur
    Commentaire de stb2680 le 17/05/2006 17:33:35

    Salut,
    Ce programme est très interessant, mais comme tu le fais remarqué, assez limité.
    Je travaille sur des images de 640*480 en NDG, dc ce type de prog n'est pas utile ici.

    Je me tente le perceptron, mais c'est plus dure.

    Et t'en es où toi avec lui ?

  • signaler à un administrateur
    Commentaire de Raja_Lon_Flatterie le 24/08/2006 19:02:31

    Salut,

    Je cherche du code pour un réseau de Hopfield A VALEURS CONTINUES..
    Absolument introuvable sur le net apparemment !
    Code Python préféré, mais vu la rareté du truc je ne ferai pas le diffiçile.

    Si quelqu'un connaît un lien? Merci!

  • signaler à un administrateur
    Commentaire de romeofr le 13/03/2007 12:04:16

    Bonjour,

    Je cherche a voir si je peut utiliser le reseau de neurone pour resoudre un probleme d'effectation de ressource. Si c'est possible, informer moi sur la methode a suivre.

    Merci!

  • signaler à un administrateur
    Commentaire de MaxTB le 16/03/2008 14:33:50

    serai il possible d'avoir un petit sample tout simple montrant comment on l'utilise car je galère un peu...
    Merci

Ajouter un commentaire

Appels d'offres

Pub



CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Boutique

Boutique de goodies CodeS-SourceS