0% ont trouvé ce document utile (0 vote)
42 vues13 pages

Annexe Python

Le document présente une implémentation d'un réseau de neurones en Python, incluant des classes pour différentes couches comme Dense, Convolution, Maxpooling, et des fonctions d'activation telles que Tanh et Sigmoide. Il aborde également les méthodes de rétropropagation et les calculs d'erreur, ainsi que le processus d'entraînement du réseau. Les classes et fonctions sont conçues pour optimiser les calculs tout en évitant les boucles coûteuses.

Transféré par

Oussama Chakir
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
42 vues13 pages

Annexe Python

Le document présente une implémentation d'un réseau de neurones en Python, incluant des classes pour différentes couches comme Dense, Convolution, Maxpooling, et des fonctions d'activation telles que Tanh et Sigmoide. Il aborde également les méthodes de rétropropagation et les calculs d'erreur, ainsi que le processus d'entraînement du réseau. Les classes et fonctions sont conçues pour optimiser les calculs tout en évitant les boucles coûteuses.

Transféré par

Oussama Chakir
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

TIPE:Chakir Oussama

Mathématiques Appliquées et informatiquepratique

[]: inport nnpy as np # Essentielu


-pour les array, calculs,
import matplotlib.pyplot as plt # Pour lesy
-graphiques/images
from scipy import signal :
# Calcul de convolution le coder soi-même est
3imple mais les boucles for
# sont trs couteuses et n'optimisent pas lesy
calculs (réseau trop Lent)

from skimage.measure import block_reduce # Calcul de mazpooling (même raison


que convolution, néanmoins pour
la rétropropagation, il n 'y a pasU
de telle fonction donc on utilise
# des boucles etc ce qui rend les
programme plus lent)
import tine # Chronomtre
import scipy # Pour la fonction scipy.special.ezpit qui permet dey
-calculer sigmoid sans overflow

1 Implémentation du réseau de neurones


1.1 Couches
[]: class Dense ():

definit_(self, taille_entree,taille_sortie):
self.poids = np.random.randn(taille_sortie, taille_entree)
self.biais = np.random.randn(taille_sortie, 1)

def propagation_directe(self, entree):


self.entree entree
return (np.dot(self .
poids, self.entree) + self.biais)

def retropropagation(self,grad_sortie, pas_apprentissage):


grad_poids = np.dot (grad_sortie,self.entree.T)

1
self poids-= pas_apprentissage * grad_poids
self.biais -= pas_apprentissage * grad _sortie
return np.dot(self.poids .T, grad_sortie)

[]: class Convolution(0:

def _init__(self, dimensions_entree, taille_filtre, profondeur_sortie):


profondeur_ sortie = nombrede filtres
self profondeur_sortie = profondeur_sortie
self.profondeur_entree, self .hauteur_entree, self .largeur_entree

u
.dimensions_entree
self.dimensions_entree = dimensions_entree
self.dimensions_sortie = (profondeur_sortie, self .hauteur_entree u
taille_filtre + 1,
self.largeur_entree - taille_filtre + 1)
self.dimensions filtres (profondeur_sortie, self-profondeur_entree,u
taille_filtre, taille_filtre)
self.filtres = np. random.randn(*self.dinensions_filtres)
self.biais = np. random.randn(*self.dinensions_sortie)

def propagation_directe(self,entree):
self.entree = entree
.
self.sortie = np.copy (self biais)
for i in range (self .profondeur_sortie) :
.
for j in range(self profondeur_entree):
self.sortie[i) += signal.correlate2d(self.entree [j], self.
filtres [i,j], "valid")
return self.sortie

def retropropagation(self, grad_sortie, pas_apprentissage) :


grad_filtres =
np.zeros (self.dimensions_filtres)
grad_entree = np.zeros(self.dimensions _entree)
for i in range(self .profondeur_sortie):
.
for j in range(self profondeur_entree):
grad_filtres [i,j] = signal.correlate2d(self. entree[j],u
-grad_sortie [i], "valid")
grad_entree[j]+= signal.correlate2d (grad_sortie[i), self.
filtres[i,j], "full")
grad_biais = grad_sortie

# Mise å jour
self.filtres -= pas_apprentissage grad_filtres
self.biais -= pas_apprentissage * grad_biais

return grad _entree

2
[]: class Maxpooling() :
def _init__(self, dimensions_entree, taille_filtre, stride):
self profondeur_entree, .
self.hauteur_entree, self largeur_entree u
.dimensions_entree
self.dimensions_entree = dimensions_entree
self.taille_filtre = taille_filtre
self .filtre_h, self .filtre_l = taille_filtre
self .stride = stride

self.hauteur_sortie = int (1 + (self .hauteur_entree - self. filtre_h) u


-stride)
self.largeur_sortie = int (1 + (self .largeur_entree self.filtre _1) /u
stride)
self.profondeur_sortie = self .prof ondeur_entree

def propagation_directe (self,entree):

self.entree = entree
( .
sortie = np.zeros (self prof ondeur_sortie, self.hauteur_sortie, self.
largeur_sortie))
stride= self.stride

for c in range (self.profondeur_sortie):


for i in range(self . hauteur_sortie):
for j in range (self .largeur_sortie):
sortie [c, i, j]= np.max(entree [c, i * stride : i * stride
t self.filtre_h j stride : j * stride + self.filtre_l ])
return sortie

def retropropagation(self, grad_sortie, pas_apprentissage) :

grad_entree = np.zeros( (self profondeur_entree, self . hauteur _entree,u


-
self.largeur_entree) )
entree =
self.entree
stride= self.stride
for c in range(self .profondeur_sortie):
for i in range(self hauteur_sortie):
for j in range (self.largeur_sortie):
internediaire = entree [c, i * stride : i* stride + self.
filtre _h,j* stride : j* stride + self.filtre_1]
i_max, j_max = np.where(np.max(intermediaire)
intersediaire)
i_max, j_max =
i_max [0], j_max[o]
grad_entree [c,i *stride : i * stride + self.filtre_h, j *u
-stride : j* stride + self.filtre_1] [i_max, j_max] = grad_sortie [c, i, j]

3
return grad_entree

[]: class Dropout ():

def _init__(self, q_bernouilli) :


self.p_bernouilli = 1 - q_bernouilli

def propagation_directe (self, entree) :


self.entree= entree

self.masque_binaire = np.random.binomial (1, self.p_bernouilli, size =u


entree.shape)/ self.p_bernouilli
self.sortie entree self .masque_binaire
return self. sortie

def retropropagation(self, grad_sortie, pas_apprentissage) :


return grad_sortie self .masque_binaire

[]: class Dimension () :


,
def _init__(self dimension_entree, dimension_sortie) :
self.dimension_entree= dimension_entree
self.dimension_sortie = dimension_sortie

def propagation_directe (self, entree) :


return np.reshape (entree, self.dimension_sortie)

def retropropagation(self, grad_sortie, pas_apprentissage) :


return np.reshape (grad_sortie, self .dimension_entree)

1.2 Couches d'Activation

4
[]: # Tang en te hyperbolique
class Tanh ()

:
def _init__(self):
tanh = lambda x : np.tanh (x)
tanh_p lambda 1 x:
- np.tanh (x)**2
self.activation = tanh
self.derivee_activation = tanh_p

def propagation_directe (self, entree):


self.entree = entree
return self.activation(self.entree)

def retropropagation(self, grad _sortie, pas_apprentissage) :


return np.multiply (grad_sortie, self .derivee_activation (self.entree) )
[]:#Sigmoide
class Signoide () :

def _init__(self):

def sigmoide (x) :


return scipy.special.expit (x)

def signoide_p(sig):
return sig (1- sig)

self.activation = sigmoide
self.derivee_activation = sigmoide_p

def propagation_directe (self, entree):


self.entree = entree
self .sig = self.activation(self .entree)
return self.sig

def retropropagation (self ,grad_sortie, pas_apprentissage) :


return np.multiply (grad_sortie, self. derivee_activation(self.sig))

[]:# Sof tmaz


class Softmax():

def propagation_directe (self,entree):


maxi = np.max(entree)
entree entree maxi
expo = np.exp(entree)
self.sortie =
expo/np.sun(expo)

5
return self.sortie

def retropropagation (self, grad_sortie, pas_apprent issage): # L'erreuru


utilisée étant toujours cce
# en comp lémen t de softmam, et comme on a déjå calculé la dérivée de
'erreur par rapport å
#L'entrée du softmaz, on La transmet (cf cce)

return grad_sortie

[]:# ReLU
class Relu ():

def propagat ion_directe (self, entree) :


self.entree = entree
self.sortie = np.maximun(0, entree)
return self.sortie

def retropropagation (self, grad_sortie, pas_apprentissage) :


inter = grad_sortie.copy ()
inter (inter (= 0] = 0
return inter

1.3 Erreur

[]:#Erreur quadratique moyenne (eqm)

[]: def eqm(sortie_voulue, sortie):


return np.mean (np.power(sortie_voulue - sortie, 2))

def eqm_derivee(sortie_voulue, sortie) :


return 2 * (sortie - sortie_voulue) / np. size(sortie)

[]:# Erreur croisée binaire (binary crossentropy notée bce)

def bce (sortie_voulue, sortie) :


sortie_voulue = np.clip(sortie_voulue, le-7, 1 - le-7) # Pour ne pas avoinu
de diuision par zero/ log (0)
sortie = np.clip(sortie, le-7, 1 - 1e-7) # Pour ne pas avoir de divisiony
-par zero/ log (0)
return -np.mean (sortie_voulue * np.log(sortie) + (1 - sortie_voulue)* np.
log(1-sortie) )
def bce_derivee(sortie_voulue, sortie):
sortie =
np.clip(sortie, 1e-7, 1 - le-7)

6
sortie_voulue = np.clip(sortie_voulue, le-7, 1 le-7) -
return ((1 sortie_voulue) / (1 - sortie) - sortie_voulue/ (sortie)) np.
-size (sortie)

[]:# Erreur croisée (categori cal crossentropy noté cce)

def cce (sortie_voulue, sortie):


sortie_voulue = np.clip(sortie_voulue, 1e-7, 1 - le-7)
sortie = np.clip(sortie, le-7, 1 - le-7)
return -np.sum(np.log(sortie) sortie_voulue)

def cce_derivee(sortie_voulue, sortie): # Ici, pour un soucis de rapidi té de


calcul, on cal cule directe
# la dérivée de l 'erreur par rapport åu
'entrée du softmaz en utilisant
# cce comme erreur d la derniêre couche.
En effet, la formu le est bien
# plus simple comme ceci, et onu
utilisera toujours Softmaz comme fonction
# d'activation en derniëre couche avecu
cce (cf. Softmaz)
sortie_voulue = np.clip(sortie_voulue, le-7, 1 - le-7)
sortie = np.clip(sortie, le-7, - le-7) 1

return sortie- sortie_voulue

1.4 Réseau de neurones


[]:def precision_erreur(res, entree_t, sortie_t):

succes = 0
total= 0

e 0
for i in range (1en(entree_t) : )
s= prediction(entree_t[i])
res.
e t= res.erreur(sortie_t[i],s)
maxi = np.argmax(s)
if maxi =* np.argmax(sortie_t[i]) :
succes 1
+
total t= 1

return (succes/total,e/total)

[]:class Reseau ():


def_init__(self, couches, erreur, erreur_derivee):
self.couches = couches

7
self.erreur = erreur
self.erreur_derivee = erreur_derivee

def prediction (self, entree):


sortie = entree
for couche in self.couches:
sortie = couche. propagation_directe (sortie)
return sortie

def entrainement (self,entree_e , sortie_e, entree_t, sortie_t, iterations,u


-pas_apprentissage): #entree_e et sortie_e : entrée et sortie entrainement
nb_entrainements = len (entree_e)
liste_erreur = O
liste_erreur_t = 0
precision_e
precision_t = O
tini = time.time ()

for itera in range(iterations) :


print ("Itération numéro ", itera+1)
erreur = 0

titer = time.tine ()
succes_e= 0

tot_e = 0
for i in range (nb_entrainements) :
# Propagation directe
sortie= entree_e[i]

for couche in self.couches:


sortie = couche. propagation_directe (sortie)
if np.argmax(sortie) = np. argmax(sortie_e [i]):
succes_e + 1

tot_e t=
1
# Ajout de l'erreur

,
erreur t= self. erreur (sortie_e [il sortie)

# Rétropropaga tion

sortie_retro = self .erreur_derivee (sortie_e [1J , sortie)


for couche in reversed(self.couches):
sortie_retro =
couche.retropropagation (sortie_retro,u
pas_apprentissage)
# Traitement de 'erreur

erreur /= nb_entrainements
liste_erreur. append(erreur)
print ("Erreur:", erreur)

prec_test, err_test = precision_erreur(self,entree_t, sortie_t)


liste_erreur_t.append(err_test)
print ("Erreur sur la base de test :", liste_erreur_t[-1])

precision_e.append(succes_e/tot_e)
precision_t.append(prec_test)
print ("Précision sur la base entrainement :", precision_e[-1])
print ("Précision sur la base test ", precision_t [-1])
print("Durêe de 1'itération :", round (time.time() - titer, 2),"s")
print ()
print ()
print ("Fin de l'apprentissage")
print ("Durée de l'apprentissage : ", round(time .time() tini,2), "s")
return (1iste_erreur, liste_erreur_t, precision_e , precision_t)

def test (self, entree_t, sortie_t):


nb_entrainements = len(entree_t)
erreur = 0
for i in range (nb_entrainements)
:
# Propagation directe
sortie = entree_t [1]
for couche in self.couches:
sOrtie couche.propagation_directe(sortie)
# Ajout de l'erreur

erreur += self.erreur(sortie_t[i],sortie)
erreur /= nb_entrainements
return erreur

Voici trois applications de ce code ci-dessOus :

2 XOR (ou exclusif)


[]:# Données (entree_e et sortie_ e : liste des entrées/sorties voulues)

(
entree_e = np.reshape [O,0], (2,1) ),np.reshape([o,1],(2,1)), np.
,
-reshape([1,0] (2,1)), np.reshape([1,1],(2,1))]
sortie_e = np.array(
[o]),np.array ( [1])
[1]),np. array( ,np.array( [o])]

# Structure du réseau (Reseau (couches, erreur, erreur_derivee))

9
couches = (Dense(2,5), Tanh (), Dense(5,3), Tanh () ,Dense(3,1), Tanh ()]
reseau1 (
= Reseau [Dense(2,5), Tanh), Dense(5,3), Tanh (),Dense (3,1) ,u
Tanh () ,eqm,eqm_derivee)
reseau2 =Reseau ([Dense(2,5), Tanh (), Dense(5,3), Tanh (),Dense(3,1) ,u
-Tanh()),
eqm,eqm_derivee)
(
reseau3 = Reseau [Dense (2,5), Tanh (), Dense(5,3), Tanh (O,Dense(3,1),u
-Tanh ()],eqm,eqm_derivee)

,
#Entrainement (reseau. en trainement(entree_ e, sortie_e, iterations,u
-pas_ apprentissage))

err_pas1, - reseaul.entrainement(entree_e, sortie_e, entree_e,U


sortie_e, 100, 0.01)
err_pas2, --t reseau2. entrainement (entree_e, sortie_e, entree_e,u
sortie_e, 100, 0.1)
err_pas3, -b-t reseau3.entrainement (entree_e, sortie_e, entree_e,u
-sortie_e, 100, 1)

[]:x = xfor x in range(1,101)]


plt.plot(x,err_pas1)
plt.plot(x, err_pas2)
plt.plot(x, err_pas3)
plt.legend(["0.01","o.1", "1"])
plt.savefig("XOR : pas d'apprentissage 2")
plt.show()

[]: couches = [Dense(2,5), Tanh(), Dense (5,3) , Tanh ()


,Dense (3,1) , Tanh ()]

reseau_al1 = Reseau ([Dense(2,5), Tanh (), Dense (5,3), Tanh ,Dense(3,1) ,u


()
,
Tanh ()] eqm,eqm_derivee)
(
reseau_al2 = Reseau [Dense(2,5), Tanh (), Dense(5,3), Tanh () ,Dense(3,1),u
,
-Tanh ()] eqm, eqm_ derivee)
reseau_al3 =Reseau ([Dense(2,5), Tanh (), Dense (5,3), Tanh (),Dense(3,1) ,u
-Tanh ()],eqm,eqm_derivee)
(
reseau_al4 = Reseau [Dense(2,5), Tanh (), Dense (5,3), Tanh () , Dense (3,1),u
-Tanh()],eqm,eqm_derivee)
reseau_al5 = Reseau( [Dense(2,5), Tanh (),Dense (5,3), Tanh ,Dense(3,1) ,u
()
-Tanh ()],eqm,eqm_derivee)

err_aleal, - = reseau_al1.entrainement(entree_e, sortie_e, entree_e,u


-sortie_e, 100, 0.1)
err_alea2, - =reseau_al2. entrainement(entree_e, sortie_e, entree_e,u
-sortie_e, 100, 0.1)
err_alea3, -t- reseau_al3.entrainement (entree_e, sortie_e, entree_e,u
-sortie_e, 100, 0.1)

10
err_alea4,
sortie_e,
err_alea5,
,=
,-=100, 0.1)
reseau_al4.entrainement (entree_e, sortie_e, entree_e,u

reseau_al5. entrainement(entree_e, sortie_e, entree_e,u


-8ortie_e, 100, 0.1)

[]: x = [x for x in range (1,101) )


plt.plot(x, err_alea1)
plt.plot (x,err_alea2)
plt.plot(x,err_alea3)
plt plot (x, err_alea4)
plt.plot (x,err_alea5)
plt.savefig(" X0R : initialisation des poids et biais 2")
plt.show()

11
##INFLUEN CE DU CHOIX DE LA FONCTION
net1= N.Network ([784,30,10])
net2= N.Network ([784 ,30,10] )
(
net3= N.NetwOrk [784,30,10] )
(
net4= N.Network [784 ,30,10] )
x,y1= net1.evolution_entrainement (training_data ,10,3.0,test ,
sigmoid ,ds)
-.y2= net2.evolution_entrainement (training-data ,10, 3.0 ,
test , tanh, dtanh)
-.y3= net3.evolution_entrainement (training_data ,10,3.0,test ,
f3,df3)
-,y4= net4.evolution_entrainement (training_dat a ,10,3.0,test ,

.
f4,df4)

:
Plot s ome data on the (implicit) axes .
'
'
plt. plot (x[0:5000:10],y1 [0:5000: 10], label= Sigmoid ') #

plt plot (x [0 5000: 10], y2 [0:5000: 10), label= tanh ') # etc.
. :
plt plot (x [O 5000:10] , y3 [O:5000: 10], label=1/1+z^2)
plt. plot (x [0: 5000:10] , y4 [0:5000:10] , label='arctan')
plt. xlabel("nombres d'images ")
plt .ylabel ('pr cision ')
plt.title ("Influence du choix de la fonction f")
plt.legend ()
plt. show ()

#influence de la structure du r seau


(
structure1 = N.Network [784 ,10] )
,
structure2 = N.Network ([784 16,10])
structure3 = N.Network([784 ,16,16,10])

a1,b1= structure 1.evolution_entrainement(training_data


,
,10,3.0,test sigmoid , ds)

11
-,b2 =
structure2 .evolution_entrainement (training_data
,
,10,3.0,test ,sigmoid ds)
-,b3 = structure3. evolution_entrainement (training_data
,
,10,3.0,test ,sigmoid ds)

.plot (a1 [O:5000:10] , b1[O:5000:10],


plt
couches)
'
1abel = r seau

plt .plot (a1 [O:5000:10], b2 [O:5000:10], label = r seau


couches ')
plt .plot(a1 [O:5000:10], b3 [O:5000:10], label ='r seau
2

3
4
couches ')
plt. xlabel ("nombres d'images ")
plt.ylabel (' pr cision )
plt.title ("Influence de la structure du r seau ")
plt. legend()
plt.show ()

11

Vous aimerez peut-être aussi