Problèmes Poids synaptiques réseaux de neurones
Bonsoir à tous,
Pour un projet, je dois coder un réseau de neurones permettant l'identification de caractères/nombres mais sans utilisation de librairies comme Tensorflow ou Keras.
J'ai donc suivi la théorie mais problème, mes poids synaptiques ainsi que mon erreur au bout d'une centaine d'itérations seulement deviennent incohérents (tendent vers 0 ou 1).
Je suppose deux choses:
1-Soit mon calcul de l'erreur avec la dérivée de la fonction sigmoïde est fausse
2-Soit la rétro propagation du gradient est erronée
Code:
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
| from matplotlib import pyplot as plt #Libraires pour opérations mathématiques"
import numpy as np
import math
import random
"""import step1"""#etape recuperation info image
import step2#étape conversion image en liste binaire
import retribution#fonction pour ecrire poids synaptiques dans fichier txt
x=64 #Variables"
y=64
z=10
t_apprentissage = 0.1 #Taux d'apprentissage#
Donnees = [0]*x #Données de l'image#
for o in range(x):
Donnees[o]=int(step2.listes[o])
Entrees = [0]*x #Couche d'entrée#
Cachees = [0]*y #Couche cachée#
Sorties = [0]*z #Couche de sortie#
W_En_Ca = [random.uniform(-1, 1) for i in range(x*y)] #Poids synaptiques de la couche cachée#
W_Ca_So = [random.uniform(-1, 1) for i in range(y*z)] #Poids synaptiques de la couche de sortie#
for c in range(x*y):
W_En_Ca[c]=float(retribution.listes1[c])
for n in range(y*z):
W_Ca_So[n]=float(retribution.listes2[n])
Intermed = [0]*y #Somme pondérées cumulées pour la couche cachée#
Sort_p = [0]*z #Somme pondérées cumulées pour la couche de sortie#
S_Souhaitées = [0]*z #Sorties Souhaitées#
Erreurs = [0]*z #Erreurs simples#
Gradients = [0]*(y*z) #Gradients de l'erreur#
Cache_Local = [0]*(x*y) #Liste stockant la rétropagation de l'erreur de la couche sortie vers cachée#
def sigmoid(x): #fonction sigmoïde#
return 1/(1+np.exp(-x))
def sigmoidDerivee(x):#derivative of sigmoid
return x*(1.0 - x)
def propager():
for f in range(z):
S_Souhaitées[f]=float(step2.Sortie[f])
for g in range(x): #Copie les données dans la couche d'entrée#
Entrees[g]=Donnees[g]
for i in range(y): #Propage dans la couche cachée#
for j in range(x):
Intermed[i] += (W_En_Ca[(i*x)+j])*Entrees[j]
for k in range(y): #Applique la fonction sigmoïde#
Cachees[k] = sigmoid(Intermed[k])
for l in range(z): #Propage dans la couche de sortie#
for m in range(y):
Sort_p[l] += (W_Ca_So[(l*y)+m])*Cachees[m]
for n in range(z): #Applique la fonction sigmoïde#
Sorties[n] = sigmoid(Sort_p[n])
def apprentissage():
for i in range(z): #Calcul de l'erreur en sortie#
Erreurs[i] = (S_Souhaitées[i] - Sorties[i])
for j in range(z): #Calcul des gradients couche de sortie#
for k in range(y):
Gradients[(j*y)+k] = ((Erreurs[j])*sigmoidDerivee(Sorties[j]))
for l in range(y): #Calcul des gradients couche cachée#
for n in range(x):
e=0
for m in range(z):
e+= (W_Ca_So[(n*z)+m])*Gradients[(l*z)+m]
Cache_Local[(l*x)+n] = e*sigmoidDerivee(e)
for o in range(z): #Mise à jour des poids couche de sortie#
for p in range(y):
W_Ca_So[(o*y)+p]=(W_Ca_So[(o*y)+p])+e
for q in range(x): #Mise à jour des poids couche cachée#
for r in range(y):
W_En_Ca[(q*y)+r]=(W_En_Ca[(q*y)+r])+Cache_Local[(l*x)+n]
str_W_En_Ca=','.join(map(str, W_En_Ca))
fichier1 = open("Poids_synaptiques_Entrees_Cachee.txt", "w")
fichier1.write(str_W_En_Ca)
fichier1.close()
str_W_Ca_So=','.join(map(str, W_Ca_So))
fichier2 = open("Poids_synaptiques_Entrees_Sortie.txt", "w")
fichier2.write(str_W_Ca_So)
fichier2.close()
retribution.lirecompter1()
retribution.lirecompter2()
propager() #On propage#
apprentissage() #Phase d'apprentissage#
print(Sorties)
print(S_Souhaitées) |
Voilà, désolé si mon code est un peu long