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
| import random
import math
def f(x) :
return 1/(1+math.e**(-x))
def derivee(x) :
return (math.e**(-x)) / ((1+math.e**(-x))**2)
def f(x) :
if x>=0 : return math.sqrt(x)
else : return -math.sqrt(-x)
def derivee(x) :
if x>0 : return -0.5/math.sqrt(x)
elif x==0 : return 0
else : return 0.5/math.sqrt(-x)
class ReseauDeNeurones :
"""Gere les principales fonctions d'un reseau de neurones."""
def __init__( self, nb_neurones_par_couche=[10,8,1], valeur_par_defaut_synapses = "random.random()*2-1", fonction = f, derivee=derivee ) :
"""Constructeur de l'objet.
nb_neurones_par_couche : liste contenant le nombre de neurones par couche
le premier etant les entrees et le dernier les sorties
valeur_par_defaut_synapses : contient la valeur par defaut des synapses sous la forme de str /!\
fonction : fonction d'activation (sigmoide par defaut)"""
self.f = self.fonction = fonction
self.f_ = derivee
self.couches = []#contient self.couches[couche][neurone][poids]
for nb in range(len(nb_neurones_par_couche)-1) :
self.couches.append([])#une couche de plus
for i in range(nb_neurones_par_couche[nb]) :
self.couches[-1].append([])#un neurone de plus
for synapse in range(nb_neurones_par_couche[nb+1]) :
self.couches[nb][i].append(eval(valeur_par_defaut_synapses))
def executer(self,*entrees) :
"""Execute le reseau de neurones avec les entrees donnees (qui doivent etre egales au nombre de neurones).
Les neurones de sortie et d'entree n'appliquent pas la fonction d'activation."""
sortie=[0]*len(self.couches[1])
for i in range(len(entrees)) :
entree=self.f(entrees[i])
for ii in range(len(self.couches[0][i])) :
poids = self.couches[0][i][ii]
sortie[ii]+=poids*entree
for couche in self.couches[1:] :
sortie,entrees = [0]*len(couche[0]), sortie
for i in range(len(entrees)) :
entree=self.fonction(entrees[i])
for ii in range(len(couche[i])) :
poids = couche[i][ii]
sortie[ii]+=poids*entree
return [self.f(v) for v in sortie]
def _executer_(self,*entrees) :
"""Execute le reseau de neurones avec les entrees donnees (qui doivent etre egales au nombre de neurones).
Les neurones de sortie et d'entree n'appliquent pas la fonction d'activation.
fonction renvoyant les sorties des differentes couches"""
S = []
sortie=[0]*len(self.couches[1])
for i in range(len(entrees)) :
entree=self.f(entrees[i])
for ii in range(len(self.couches[0][i])) :
poids = self.couches[0][i][ii]
sortie[ii]+=poids*entree
S.append(list(sortie))
for couche in self.couches[1:] :
sortie,entrees = [0]*len(couche[0]), sortie
for i in range(len(entrees)) :
entree=self.fonction(entrees[i])
for ii in range(len(couche[i])) :
poids = couche[i][ii]
sortie[ii]+=poids*entree
S.append(list(sortie))
return S #-> valeurs brutes sans seuillage par la fonction f
def retropropagation(self, entree, sortie) :
"""entree -> entrees voulues
sortie -> sortie voulue
s -> sortie obtenue avant modification
deja pour 3 couches"""
nouveaux_poids = []
for couche in range(len(self.couches)) :
nouveaux_poids.append([])
for neurone in self.couches[couche] :
nouveaux_poids[-1].append(list(neurone))
s = self._executer_()
#dernière couche : k
E=[]
for i in range(len(s[1])) : #i : position du neurone dans la couche 2 = sortie
erreur_neurone = self.f_(s[1][i]) * ( sortie[i] - self.f(s[1][i]) )
#on "repare" l'erreur
for j in range(len(self.couches[1])) :
nouveaux_poids[1][j][i] -= erreur_neurone * self.couches[1][j][i]
E.append(erreur_neurone)
for i in range(len(s[0])) : #i : position du neurone dans la couche 1
somme = 0
for k in range(len(self.couches[1][i])) :
somme+=E[k]*self.couches[1][i][k]
erreur = self.f_(s[0][i])*somme
#on "repare" l'erreur
for j in range(len(self.couches[0])) :
nouveaux_poids[0][j][i] -= erreur * self.couches[1][j][i]
self.couches = nouveaux_poids
a=ReseauDeNeurones([2,2,2])
print(a.executer(1,3))
for i in range(10) :
a.retropropagation((1,3),(10,2))
s=(1,3)
print(s,a.executer(*s)) |
Partager