Bonjour, ceci est un repost car je n'ai pas trouvé de réponse la dernière fois je retente donc ma chance
J'essaie d'apprendre les bases du deep learning depuis peu de temps et je suis confronté à un problème. Après l'élaboration d'un réseau à une couche pour classifier des données linéairement séparable qui fonctionne très bien, j'ai tenté de créer un réseau de neurones à plusieurs couches pour classifier des données un peu plus complexe (XOR par exemple). Le problème étant que celui ci ne marche pas du tout, en effet ces prédictions sont totalement fausses.
Ici j'entraine l'IA sur le problèm ET (car le XOR ne marchait pas)
et voici la réponse du réseau pour la classification de données ET:
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 import matplotlib.pyplot as plt import numpy as np import random #-------------------------------------------- # Fonctions mathématiques #-------------------------------------------- def square(nb): return nb * nb def moyQuadra(prediAttendu, prediRealise): somme = 0 i = 0 for predis in prediAttendu: dif = prediAttendu[i] - prediRealise[i] carreDif = square(dif) somme += carreDif moyQuadra = 1/(len(prediAttendu)) * somme return moyQuadra def Gradient(erreur, predi, valEntree): return -1 * erreur * predi * (1-predi) * valEntree def funcSigmoide(sommePonderee): return 1 / (1 + np.exp(-sommePonderee)) def sommePondereeCalc(biais, wb, X1, w11, X2, w21): return biais*wb + (X1*w11 + X2*w21) def erreurLinCalc(prediAttendu, prediRealise): return prediAttendu - prediRealise def valAjustement(txApp, grad): return grad*txApp def novPoid(poid, valAjustement): return poid - valAjustement #-------------------------------------------- # Observations et prédictions #-------------------------------------------- observations = np.array([ [1, 0], [1, 1], [0, 1], [0, 0] ]) predis = np.array([[0], [1], [0], [0]]) # génération des poids w11 = np.random.normal(scale=0.1) w21 = np.random.normal(scale=0.1) w31 = np.random.normal(scale=0.1) w41 = np.random.normal(scale=0.1) w12 = np.random.normal(scale=0.1) w22 = np.random.normal(scale=0.1) # Biais biais1 = 1 biais2 = 1 w51 = np.random.normal(scale=0.1) w61 = np.random.normal(scale=0.1) w32 = np.random.normal(scale=0.1) # Taux d'apprentissage txApp = 0.05 # Nbr d'epochs epochs = 300000 #-------------------------------------------- # Graphique #-------------------------------------------- graphiqueMSE = [] #-------------------------------------------- # Apprentissage #-------------------------------------------- for epoch in range(0,epochs): print(f"EPOCH {epoch+1} / {epochs}") prediRealiseEpoch = [] prediAttenduEpoch = [] numObservation = 0 for observation in observations: # Chargement de la couche de neurone x1 = observation[0] x2 = observation[1] # Prediction attendu prediAttendu = predis[numObservation][0] # Calcul de la somme ponderee H1 sommePondereeH1 = sommePondereeCalc(biais1, w51, x1, w11, x2, w31) # Fonction d'activation h1 = funcSigmoide(sommePondereeH1) # Calcul de la somme ponderee H1 sommePondereeH2 = sommePondereeCalc(biais1, w61, x1, w21, x2, w41) # Fonction d'activation h2 = funcSigmoide(sommePondereeH2) # Calcul de la somme ponderee H1 preactivation = sommePondereeCalc(biais2, w32, h1, w12, h2, w22) # Fonction d'activation prediRealise = funcSigmoide(preactivation) # Erreur linéaire erreurLin = erreurLinCalc(prediAttendu, prediRealise) # MAJ poid x1 GradientW11 = Gradient(erreurLin, prediRealise, x1) valAjustementW11 = valAjustement(txApp, GradientW11) w11 = novPoid(w11, valAjustementW11) GradientW21 = Gradient(erreurLin, prediRealise, x1) valAjustementW21 = valAjustement(txApp, GradientW21) w21 = novPoid(w21, valAjustementW21) # MAJ poid x2 GradientW31 = Gradient(erreurLin, prediRealise, x2) valAjustementW31 = valAjustement(txApp, GradientW31) w31 = novPoid(w31, valAjustementW31) GradientW41 = Gradient(erreurLin, prediRealise, x2) valAjustementW41 = valAjustement(txApp, GradientW41) w41 = novPoid(w41, valAjustementW41) # MAJ poid biais1 GradientW51 = Gradient(erreurLin, prediRealise, biais1) valAjustementW51 = valAjustement(txApp, GradientW51) w51 = novPoid(w51, valAjustementW51) GradientW61 = Gradient(erreurLin, prediRealise, biais1) valAjustementW61 = valAjustement(txApp, GradientW61) w61 = novPoid(w61, valAjustementW61) # MAJ poid h1 GradientW12 = Gradient(erreurLin, prediRealise, h1) valAjustementW12 = valAjustement(txApp, GradientW12) w12 = novPoid(w12, valAjustementW12) # MAJ poid h2 GradientW22 = Gradient(erreurLin, prediRealise, h2) valAjustementW22 = valAjustement(txApp, GradientW22) w22 = novPoid(w22, valAjustementW22) # MAJ poid biais2 GradientW32 = Gradient(erreurLin, prediRealise, biais2) valAjustementW32 = valAjustement(txApp, GradientW32) w32 = novPoid(w32, valAjustementW32) # Sortie print(f" EPOQUE: {epoch+1}/{epochs} - OBERVATION: {numObservation+1}/{len(observations)}") # Stockage valeur prédite prediRealiseEpoch.append(prediRealise) prediAttenduEpoch.append(prediAttendu) numObservation += 1 MSE = moyQuadra(prediRealiseEpoch, predis) graphiqueMSE.append(MSE) print(f"MSE: {MSE}") plt.plot(graphiqueMSE) plt.ylabel("MSE") plt.show() #-------------------------------------------- # Prédiction #-------------------------------------------- print(f""" -------------------------------------------- Poids finaux: -------------------------------------------- x1: W11: {w11} W21: {w21} x2: W31: {w31} W41: {w41} biais1: W51: {w51} W61: {w61} h1: W12: {w12} h2: W22: {w22} biais2: W32: {w32} """) print(f""" -------------------------------------------- Prédiction -------------------------------------------- """) print("NON et OUI") x1 = 0 x2 = 1 # Calcul de la somme ponderee H1 sommePondereeH1 = sommePondereeCalc(biais1, w51, x1, w11, x2, w31) # Fonction d'activation h1 = funcSigmoide(sommePondereeH1) # Calcul de la somme ponderee H1 sommePondereeH2 = sommePondereeCalc(biais1, w61, x1, w21, x2, w41) # Fonction d'activation h2 = funcSigmoide(sommePondereeH2) # Calcul de la somme ponderee H1 preactivation = sommePondereeCalc(biais2, w32, h1, w12, h2, w22) # Fonction d'activation prediRealise = funcSigmoide(preactivation) print(f"La prédiction est: {prediRealise}") print("") print("NON et NON") x1 = 0 x2 = 0 # Calcul de la somme ponderee H1 sommePondereeH1 = sommePondereeCalc(biais1, w51, x1, w11, x2, w31) # Fonction d'activation h1 = funcSigmoide(sommePondereeH1) # Calcul de la somme ponderee H1 sommePondereeH2 = sommePondereeCalc(biais1, w61, x1, w21, x2, w41) # Fonction d'activation h2 = funcSigmoide(sommePondereeH2) # Calcul de la somme ponderee H1 preactivation = sommePondereeCalc(biais2, w32, h1, w12, h2, w22) # Fonction d'activation prediRealise = funcSigmoide(preactivation) print(f"La prédiction est: {prediRealise}") print("") print("OUI et OUI") x1 = 1 x2 = 1 # Calcul de la somme ponderee H1 sommePondereeH1 = sommePondereeCalc(biais1, w51, x1, w11, x2, w31) # Fonction d'activation h1 = funcSigmoide(sommePondereeH1) # Calcul de la somme ponderee H1 sommePondereeH2 = sommePondereeCalc(biais1, w61, x1, w21, x2, w41) # Fonction d'activation h2 = funcSigmoide(sommePondereeH2) # Calcul de la somme ponderee H1 preactivation = sommePondereeCalc(biais2, w32, h1, w12, h2, w22) # Fonction d'activation prediRealise = funcSigmoide(preactivation) print(f"La prédiction est: {prediRealise}") print("") print("OUI et NON") x1 = 1 x2 = 0 # Calcul de la somme ponderee H1 sommePondereeH1 = sommePondereeCalc(biais1, w51, x1, w11, x2, w31) # Fonction d'activation h1 = funcSigmoide(sommePondereeH1) # Calcul de la somme ponderee H1 sommePondereeH2 = sommePondereeCalc(biais1, w61, x1, w21, x2, w41) # Fonction d'activation h2 = funcSigmoide(sommePondereeH2) # Calcul de la somme ponderee H1 preactivation = sommePondereeCalc(biais2, w32, h1, w12, h2, w22) # Fonction d'activation prediRealise = funcSigmoide(preactivation) print(f"La prédiction est: {prediRealise}") print("")
je vous met aussi le graphique obtenue avec matplotlib sur la courbe d'apprentissage:
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 -------------------------------------------- Poids finaux: -------------------------------------------- x1: W11: 1117.7448265952485 W21: 1117.6809972016065 x2: W31: 1105.319318773727 W41: 1105.3205546414201 biais1: W51: -4.890231026215392 W61: -4.760379221211809 h1: W12: 2.2567798898444993 h2: W22: 2.0216586042455456 biais2: W32: -4.977385798748952 -------------------------------------------- Prédiction -------------------------------------------- NON et OUI La prédiction est: 0.33204566524926027 FAUX NON et NON La prédiction est: 0.007079980459272605 FAUX OUI et OUI La prédiction est: 0.33204566524926027 FAUX OUI et NON La prédiction est: 0.33204566524926027 FAUX
Le réseau à été entrainé pendant 300 000 époques avec un taux d'apprentissage de 0.05. J'ai tout tenté: changer le nombre d'époque, le tx d'apprentissage, l'initialisation des poids... J'utilise une somme pondérée comme pré activation, une fonction sigmoïde pour la fonction d'activation, un calcule d'erreur linéaire pour la fonction de perte et un calcul de gradient pour l'ajustement des poids. Je suppose que l'erreur se trouve au niveau de la rétropropagation, peut être je calcule mal ajustement des poids ? Ou peut être les fonctions que j'utilise ne marche plus avec plusieurs couches ? Ou bien l'erreur se trouve dans mon paramétrage de mon réseau ?
Je vous fournit aussi mon réseau à une couche qui lui marche très bien pour voir la comparaison:
Courbe d'apprentissage:
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 import matplotlib.pyplot as plt import numpy as np import random #-------------------------------------------- # Fonctions mathématiques #-------------------------------------------- def square(nb): return nb * nb def moyQuadra(prediAttendu, prediRealise): somme = 0 i = 0 for predis in prediAttendu: dif = prediAttendu[i] - prediRealise[i] carreDif = square(dif) somme += carreDif moyQuadra = 1/(len(prediAttendu)) * somme return moyQuadra def Gradient(erreur, predi, valEntree): return -1 * erreur * predi * (1-predi) * valEntree def funcSigmoide(sommePonderee): return 1 / (1 + np.exp(-sommePonderee)) def sommePondereeCalc(biais, wb, X1, w11, X2, w21): return biais*wb + (X1*w11 + X2*w21) def erreurLinCalc(prediAttendu, prediRealise): return prediAttendu - prediRealise def valAjustement(txApp, grad): return grad*txApp def novPoid(poid, valAjustement): return poid - valAjustement #-------------------------------------------- # Observations et prédictions #-------------------------------------------- observations = np.array([ [1, 0], [1, 1], [0, 1], [0, 0] ]) predis = np.array([[0], [1], [0], [0]]) # génération des poids random.seed(1) borneMin = -1 borneMax = 1 w11 = (borneMin - borneMax) * random.random() + borneMin w21 = (borneMin - borneMax) * random.random() + borneMin # Biais biais = 1 wb = (borneMin - borneMax) * random.random() + borneMin # Taux d'apprentissage txApp = 0.1 # Nbr d'epochs epochs = 20000 #-------------------------------------------- # Graphique #-------------------------------------------- graphiqueMSE = [] #-------------------------------------------- # Apprentissage #-------------------------------------------- for epoch in range(0,epochs): print(f"EPOCH {epoch+1} / {epochs}") prediRealiseEpoch = [] prediAttenduEpoch = [] numObservation = 0 for observation in observations: # Chargement de la couche de neurone x1 = observation[0] x2 = observation[1] # Prediction attendu prediAttendu = predis[numObservation][0] # Calcul de la somme ponderee H1 preactivation = sommePondereeCalc(biais, wb, x1, w11, x2, w21) # Fonction d'activation prediRealise = funcSigmoide(preactivation) # Erreur linéaire erreurLin = erreurLinCalc(prediAttendu, prediRealise) # MAJ poid x1 GradientW11 = Gradient(erreurLin, prediRealise, x1) valAjustementW11 = valAjustement(txApp, GradientW11) w11 = novPoid(w11, valAjustementW11) # MAJ poid x2 GradientW21 = Gradient(erreurLin, prediRealise, x1) valAjustementW21 = valAjustement(txApp, GradientW21) w21 = novPoid(w21, valAjustementW21) # MAJ poid biais GradientWb = Gradient(erreurLin, prediRealise, biais) valAjustementWb = valAjustement(txApp, GradientWb) wb = novPoid(wb, valAjustementWb) # époque actuel afficher print(f" EPOQUE: {epoch+1}/{epochs} - OBERVATION: {numObservation+1}/{len(observations)}") # Stockage valeur prédite prediRealiseEpoch.append(prediRealise) prediAttenduEpoch.append(prediAttendu) numObservation += 1 MSE = moyQuadra(prediRealiseEpoch, predis) graphiqueMSE.append(MSE[0]) print(f"MSE: {MSE}") plt.plot(graphiqueMSE) plt.ylabel("MSE") plt.show() #-------------------------------------------- # Prédiction #-------------------------------------------- print(f""" -------------------------------------------- Poids finaux: -------------------------------------------- W11: {w11} W21: {w21} Wb: {wb} """) print(f""" -------------------------------------------- Prédiction -------------------------------------------- """) print("NON et OUI") x1 = 0 x2 = 1 sommePonderee = sommePondereeCalc(biais, wb, x1, w11, x2, w21) prediRealise = funcSigmoide(sommePonderee) print(f"La prédiction est: {prediRealise}") print("") print("NON et NON") x1 = 0 x2 = 0 sommePonderee = sommePondereeCalc(biais, wb, x1, w11, x2, w21) prediRealise = funcSigmoide(sommePonderee) print(f"La prédiction est: {prediRealise}") print("") print("OUI et OUI") x1 = 1 x2 = 1 sommePonderee = sommePondereeCalc(biais, wb, x1, w11, x2, w21) prediRealise = funcSigmoide(sommePonderee) print(f"La prédiction est: {prediRealise}") print("") print("OUI et NON") x1 = 1 x2 = 0 sommePonderee = sommePondereeCalc(biais, wb, x1, w11, x2, w21) prediRealise = funcSigmoide(sommePonderee) print(f"La prédiction est: {prediRealise}") print("")
Prédiction:
Voilà tout, merci d'avance.
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 -------------------------------------------- Poids finaux: -------------------------------------------- W11: 9.68703598431491 W21: 10.954228729714323 Wb: -15.612502229996101 -------------------------------------------- Prédiction -------------------------------------------- NON et OUI La prédiction est: 0.009393741202956978 FAUX NON et NON La prédiction est: 1.6579688273268266e-07 FAUX OUI et OUI La prédiction est: 0.9934956757469703 VRAI OUI et NON La prédiction est: 0.002663449349460153 FAUX
Partager