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)
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("")
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
 
--------------------------------------------
                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
je vous met aussi le graphique obtenue avec matplotlib sur la courbe d'apprentissage:
Nom : Capture d_écran 2024-04-22 152520.png
Affichages : 137
Taille : 17,8 Ko

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:

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("")
Courbe d'apprentissage:

Nom : Capture d_écran 2024-04-22 154220.png
Affichages : 128
Taille : 20,6 Ko

Prédiction:
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
Voilà tout, merci d'avance.