/* -------------------------------------- */ /* Retro propagation du gradient */ /* Reseau multi-couches */ /* */ /* Auteur: Arrouy William */ /* Date : Fevrier 1996 */ /* Version : 1.1 */ /* -------------------------------------- */ /* Fichiers d'entetes */ /* ------------------ */ #include #include #include #include /* Structures */ /* ---------- */ struct neurone { float *w; float sortie; float erreur; }; /* Constantes du reseau */ /* -------------------- */ #define CACHE_MAX 10 /* Nombre maximal de couches cachees */ #define SEUIL_APP 0.05 /* Erreur moyenne toleree en sortie */ #define SEUIL 0.5 /* Seuil pour vrai/faux */ const long MAX_ITER = 100000; /* Nombre d'iterations en apprentissage */ #undef GENERALISATION /* Debut des procedures */ /* ++++++++++++++++++++ */ /* Initialisation des parametres du reseau */ /* --------------------------------------- */ void init_reseau(int *nb_neurones, int *nb_cache) { int i; printf("Retropropagation du gradient \n\n"); printf("Nombre de neurones d'entree : "); scanf("%d", &nb_neurones[0]); printf("Nombre de couches intermediaires : "); scanf("%d", nb_cache); if (*nb_cache > CACHE_MAX) *nb_cache = CACHE_MAX; for(i=0;i<*nb_cache;i++) { printf(" Nombre de neurones couche cachee No %d : ", i+1); scanf("%d", &nb_neurones[i+1]); } printf("Nombre de neurones de sortie : "); scanf("%d", &nb_neurones[*nb_cache+1]); } /* Allocation du reseau */ /* -------------------- */ int alloc_reseau(struct neurone ***n, int *nb_neurones, int nb_cache) { struct neurone **n1; int i, j; /* Allocation des couches */ if ( (n1 = (struct neurone **) malloc (sizeof(struct neurone*) * (nb_cache+2))) == NULL) return -1; /* Allocation des neurones */ for(i=0;i0;i--) { for(j=0;j=0;i--) for(j=0;jSEUIL_APP * nb_app) && (iter<(long)MAX_ITER) ); printf("\nPhase Apprentissage\n\n"); printf(" Convergence en %d iterations pour ecart moyen effectif %f (%f) \n", iter, SEUIL_APP, erreur/nb_app); printf(" Ecart moyen %f pour %d exemples\n", erreur, nb_app); } /* Verification et calcul des sorties */ /* ++++++++++++++++++++++++++++++++++ */ /* Test sur les exemples */ /* --------------------- */ void general_sur_exemple(struct neurone **n, int **exemples, int *nb_neurones, int nb_cache, int nb_app) { int i; int faux = 0; printf("\nPhase de generalisation sur apprentissage\n\n"); /* Pour chaque exemple calcule la sortie */ for(i=0;i= SEUIL) sortie = 1; else sortie = 0; if (exemples[i][nb_neurones[0]+j] != sortie) err = 1; } faux += err; } printf(" Erreur %d sur %d soit %3.2f \n", faux, nb_app, (faux * 100.0) / (nb_app * 1.0)); } /* Generalisation */ /* -------------- */ void generalisation(struct neurone **n, int *exemple, int *nb_neurones, int nb_cache) { FILE *fp; char buf[30]; do { printf("\n"); printf("Nom du fichier d'apprentissage : "); scanf("%s", buf); if ( (fp = fopen(buf, "r+") ) == NULL ) { printf(" Impossible d'ouvrir le fichier\n"); } else { int i, j; int nb_gen; int faux = 0; printf("\nPhase de generalisation\n\n"); fscanf(fp,"%d", &nb_gen); for(i=0;i= SEUIL) sortie = 1; else sortie = 0; if (exemple[nb_neurones[0]+k] != sortie) err = 1; } faux += err; } printf(" Erreur %d sur %d soit %3.2f \n", faux, nb_gen, (faux * 100.0) / (nb_gen * 1.0)); } } while(fp==NULL); } /* Point d'entree */ /* -------------- */ int main() { int nb_cache; /* Nombre de couches intermediaires */ int nb_neurones[CACHE_MAX+2]; /* Nombre de neurones */ struct neurone **neurones; int **exemples; /* Exemplaires */ int nb_app; /* Nombre de tests */ init_reseau(nb_neurones, &nb_cache); if ( alloc_reseau(&neurones, nb_neurones, nb_cache) == -1 ) { printf("Allocation impossible\n"); exit(-1); } init_poids(neurones, nb_neurones, nb_cache); if (lecture_exemples(&exemples, &nb_app, nb_neurones[0]+nb_neurones[nb_cache+1]) == -1 ) { printf("Lecture impossible\n"); exit(-1); } lance_apprentissage(neurones, exemples, nb_neurones, nb_cache, nb_app); general_sur_exemple(neurones, exemples, nb_neurones, nb_cache, nb_app); #ifdef GENERALISATION generalisation(neurones, exemples[0], nb_neurones, nb_cache); #endif /* affiche_poids(neurones, nb_neurones, nb_cache); */ return 0; }