Bonjour a vous amis du clavier,et de la souris
alors voila,je suis sur un projet ou il faut developper un perceptron multicouche...j'ai codé ce dernier sous java,mais étant donné que j'ai des doutes sur la source du probleme,qu'il soit lié au langage,ou qu'il soit algorithmique,je me permet de poster ici.
En fait,le perceptron tel que je l'ai codé est sous forme d'un ensemble de vecteurs:le premier vecteur est un tableau de taille 256 accueillant un ensemble de valeurs a classifier de taille 256 aussi,et le deuxieme est de taille 10 et renvois un ensemble de 10 valeurs auxquelles il faut prendre le maximum qui sera donc la classe des données a analyser.
ces deux vecteurs sont au debut initialisés avec des valeurs aleatoires qui seront donc les poids de neurones,valeurs entre 0 et 1.
voici donc la classe "Reseau" que j'utilise afin de modeliser le pmc:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class Reseau { private double[] couche_interne; private double[] couche_interne2; private double[] couche_sortie; private double[] tabb;//tableau servant a des calculs intermediaires entre la couche interne et la couche de sortie private double[] tabb_add; public Reseau(){ couche_interne2=new double[256]; couche_interne=new double[256]; couche_sortie=new double[10]; for(int i=0;i<256;i++){ getCouche_interne()[i]=Math.random(); couche_interne2[i]=Math.random(); } for(int j=0;j<10;j++){ getCouche_sortie()[j]=Math.random(); } } public double[] Calcul_Val2(double[] val) throws ErreurReseauException{//calcule les valeurs de la matrice representant le reseau de neuronnes.renvoie un tableau a une dimension qui est la sortie du reseau de neuronnes,prend en argument un tableau a une dimension double[] tab2=new double[256]; double[] tab2_add=new double[256]; double[]tab3=new double[10]; if(getCouche_interne()==null){ throw new ErreurReseauException("Couche interne non initialisée"); } else if(getCouche_sortie()==null){ throw new ErreurReseauException("Couche de sortie non initialisée"); } else{ double x=1;//on regle le biais ici for(int i=0;i<256;i++){ for(int j=0;j<256;j++){ x=x+(getCouche_interne()[i]*val[j]); //calcule les valeurs du vecteur de la couche interne du reseau.Chaque valeurs de la matrice ainsi obtenue est donc le vecteur passé a la couche de sortie. } tab2[i]=1/(1+Math.exp(-x)); x=0; } setTabb(tab2.clone()); x=1; for(int i=0;i<10;i++){ for(int j=0;j<256;j++) x=x+(getCouche_sortie()[i]*tab2[j]); tab3[i]=1/(1+Math.exp(-x)); x=0; } } return tab3; }
jusqu'ici,rien de bien plus compliqué que de vulgaires produits matriciels et vectoriels...
but,je galère avec l'apprentissage,qui est donc codé sous cette classe:
Et donc,avec ceci je veux que ce pmc prenne en entrée pour l'entrainement,256 données+ 1 chiffre qui est la classe de ces données
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public class Apprentissage extends Reseau { private double seuil_erreur;// seuil d'erreur constituant le critere de convergence de l'algorithme de descente du gradient*/ private ArrayList <double[]> List;//examples utilisés afin d'apprendre au PMC*/ private int seuil_iterations;//iterations max du reseau*/ private double pas_param_appr;//parametre du pas d'apprentissage public Apprentissage(double[] couche_interne,double[] couche_sortie,double seuil_erreur,ArrayList<double[]> List){ super(couche_interne,couche_sortie); this.seuil_erreur=seuil_erreur; this.List=List; } public Apprentissage(int it,double pas,ArrayList<double[]> List){ super(); this.seuil_iterations=it; this.List=List; this.pas_param_appr=pas; } public void Apprendre1(double[] val) throws ErreurReseauException{ while(seuil_iterations>=0){//convergence du PMC Iterator T=List.iterator();//on parcours tous les échantillons de données permettant l'apprentissage while(T.hasNext()){ double[] tab_pixels=(double[]) T.next();//j'utilise une arrayList,dans laquelle il y'a des tableaux double[] de dimension 256 qui constituent les données d'apprentissage double[] vecteur_sortie_PMC=super.Calcul_Val2(tab_pixels);//propagation de l'information a travers le pmc:on recupere un vecteur de taille 10 en sortie int classe=(int)tab_pixels[tab_pixels.length-1];//valeur de la classe de l'objet double[] dk=new double[10];//tableau du gradient de chaques cellules de la couche de sortie double[] dj=new double[256];//tableau du gradient de chaques cellules de la couche interne double[] vecteur_ccaché=super.getTabb(); for(int i=0;i<dk.length;i++){//a mon avis,l'erreur est dans cette boucle if(i==classe) dk[i]=vecteur_sortie_PMC[i]*(1-vecteur_sortie_PMC[i])*(1-vecteur_sortie_PMC[i]); else dk[i]=vecteur_sortie_PMC[i]*(1-vecteur_sortie_PMC[i])*(0-vecteur_sortie_PMC[i]); } double somme_Dk_Wkj=0; for(int i=0;i<10;i++) somme_Dk_Wkj=somme_Dk_Wkj+dk[i]*super.getCouche_sortie()[i]; for(int j=0;j<256;j++) dj[j]=vecteur_ccaché[j]*(1-vecteur_ccaché[j])*somme_Dk_Wkj; // calcul du pas et mise a jour des poids double Dw_ji=0,Dw_kj=0; for(int i=0;i<10;i++){ Dw_kj=pas_param_appr*dk[i]*super.getCouche_sortie()[i]; super.setCouche_sortie(super.getCouche_sortie()[i]+Dw_kj,i); } for(int i=0;i<256;i++){ Dw_ji=pas_param_appr*dj[i]*super.getCouche_interne()[i]; super.setCouche_interne(super.getCouche_interne()[i]+Dw_ji,i); } } seuil_iterations--; } }
et me renvoit un vecteur de taille 10(representant 10 neurones)...la valeur maximale de ce vecteur doit etre donc la classe des 256 valeurs en entrée
voila...le probleme,c'est que lorsque je lui fait apprendre un seul tableau,il arrive a modifier correctement les poids pour reconnaitre la classe des données de ce tableau...
par contre,lorsque j'essaye de l'entrainer avec toutes les données d'entrainement(donc a partir de 2 tableaux et plus),la sortie finale du pmc est un vecteur qui ressemble la plupart du temps a :
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
ou bien
0.73.... 0.1 0.1 0.1 0.1 etc
et je note que la valeur 0.73 revient tres tres tres souvent en 1ere position.
j'espere avoir bien exposé le problème et m'en remet a votre sagesse et votre experience
edit:j'ai mis en piece jointe le sujet du projet en lui meme,qui contient l'algorithme d'apprentissage...
en fait,dans la ligne dk<-ak(1-ak)(ypk-ak),ce que j'ai fait,c'est que lorsque pour dk[i],i egale la classe de l'objet,je fais dk<-ak(1-ak)(1-ak) (car on veux obtenir 1 pour la neurone de sortie i) et
dk<-ak(1-ak)(0-ak) lorsque i est different de la classe de l'objet
je ne sais pas si c'est ceci qu'il faut faire ou autre chose...
Partager