Implémentation de la Rétropropagation
Approche générale
Lors de la propagation avant, chaque couche l prend les sorties de la couche précédente, al−1, comme entrées et calcule ses propres sorties. Ainsi, la méthode forward()
de la classe Layer
prend le vecteur des sorties précédentes comme unique paramètre, tandis que le reste des informations nécessaires est stocké dans la classe.
Lors de la rétropropagation, chaque couche l a seulement besoin de dal pour calculer les gradients correspondants et retourner dal−1, donc la méthode backward()
prend le vecteur dal comme paramètre. Le reste des informations requises est déjà stocké dans la classe Layer
.
Dérivées des fonctions d'activation
Puisque les dérivées des fonctions d'activation sont nécessaires pour la rétropropagation, les fonctions d'activation comme ReLU et sigmoïde doivent être structurées comme des classes plutôt que comme des fonctions autonomes. Cela permet de définir à la fois :
- La fonction d'activation elle-même (implémentée via la méthode
__call__()
), permettant son application directe dans la classeLayer
avecself.activation(z)
; - Sa dérivée (implémentée via la méthode
derivative()
), permettant une rétropropagation efficace et utilisée dans la classeLayer
commeself.activation.derivative(z)
.
En structurant les fonctions d'activation comme des objets, il est facile de les passer à la classe Layer
et de les utiliser dynamiquement.
ReLu
La dérivée de la fonction d'activation ReLU est la suivante, où zi est un élément du vecteur des pré-activations z :
f′(zi)={1,zi>00,zi≤0class ReLU:
def __call__(self, z):
return np.maximum(0, z)
def derivative(self, z):
return (z > 0).astype(float)
Sigmoïde
La dérivée de la fonction d'activation sigmoïde est la suivante :
f′(zi)=f(zi)⋅(1−f(zi))class Sigmoid:
def __call__(self, x):
return 1 / (1 + np.exp(-z))
def derivative(self, z):
sig = self(z)
return sig * (1 - sig)
Pour ces deux fonctions d'activation, l'application se fait sur l'ensemble du vecteur z, ainsi que pour leurs dérivées. NumPy applique l'opération à chaque élément du vecteur. Par exemple, si le vecteur z contient 3 éléments, la dérivation est la suivante :
f′(z)=f′(z1z2z3)=f′(z1)f′(z2)f′(z3)La méthode backward()
La méthode backward()
est responsable du calcul des gradients en utilisant les formules ci-dessous :
a^{l-1} et zl sont stockés respectivement comme attributs inputs
et outputs
dans la classe Layer
. La fonction d'activation f est stockée comme attribut activation
.
Une fois tous les gradients nécessaires calculés, les poids et biais peuvent être mis à jour car ils ne sont plus requis pour des calculs ultérieurs :
Wlbl=Wl−α⋅dWl=bl−α⋅dblAinsi, learning_rate
(α) est un autre paramètre de cette méthode.
def backward(self, da, learning_rate):
dz = ...
d_weights = ...
d_biases = ...
da_prev = ...
self.weights -= learning_rate * d_weights
self.biases -= learning_rate * d_biases
return da_prev
L’opérateur *
effectue une multiplication élément par élément, tandis que la fonction np.dot()
réalise un produit scalaire dans NumPy. L’attribut .T
transpose un tableau.
Merci pour vos commentaires !
Demandez à l'IA
Demandez à l'IA
Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion
Awesome!
Completion rate improved to 4
Implémentation de la Rétropropagation
Glissez pour afficher le menu
Approche générale
Lors de la propagation avant, chaque couche l prend les sorties de la couche précédente, al−1, comme entrées et calcule ses propres sorties. Ainsi, la méthode forward()
de la classe Layer
prend le vecteur des sorties précédentes comme unique paramètre, tandis que le reste des informations nécessaires est stocké dans la classe.
Lors de la rétropropagation, chaque couche l a seulement besoin de dal pour calculer les gradients correspondants et retourner dal−1, donc la méthode backward()
prend le vecteur dal comme paramètre. Le reste des informations requises est déjà stocké dans la classe Layer
.
Dérivées des fonctions d'activation
Puisque les dérivées des fonctions d'activation sont nécessaires pour la rétropropagation, les fonctions d'activation comme ReLU et sigmoïde doivent être structurées comme des classes plutôt que comme des fonctions autonomes. Cela permet de définir à la fois :
- La fonction d'activation elle-même (implémentée via la méthode
__call__()
), permettant son application directe dans la classeLayer
avecself.activation(z)
; - Sa dérivée (implémentée via la méthode
derivative()
), permettant une rétropropagation efficace et utilisée dans la classeLayer
commeself.activation.derivative(z)
.
En structurant les fonctions d'activation comme des objets, il est facile de les passer à la classe Layer
et de les utiliser dynamiquement.
ReLu
La dérivée de la fonction d'activation ReLU est la suivante, où zi est un élément du vecteur des pré-activations z :
f′(zi)={1,zi>00,zi≤0class ReLU:
def __call__(self, z):
return np.maximum(0, z)
def derivative(self, z):
return (z > 0).astype(float)
Sigmoïde
La dérivée de la fonction d'activation sigmoïde est la suivante :
f′(zi)=f(zi)⋅(1−f(zi))class Sigmoid:
def __call__(self, x):
return 1 / (1 + np.exp(-z))
def derivative(self, z):
sig = self(z)
return sig * (1 - sig)
Pour ces deux fonctions d'activation, l'application se fait sur l'ensemble du vecteur z, ainsi que pour leurs dérivées. NumPy applique l'opération à chaque élément du vecteur. Par exemple, si le vecteur z contient 3 éléments, la dérivation est la suivante :
f′(z)=f′(z1z2z3)=f′(z1)f′(z2)f′(z3)La méthode backward()
La méthode backward()
est responsable du calcul des gradients en utilisant les formules ci-dessous :
a^{l-1} et zl sont stockés respectivement comme attributs inputs
et outputs
dans la classe Layer
. La fonction d'activation f est stockée comme attribut activation
.
Une fois tous les gradients nécessaires calculés, les poids et biais peuvent être mis à jour car ils ne sont plus requis pour des calculs ultérieurs :
Wlbl=Wl−α⋅dWl=bl−α⋅dblAinsi, learning_rate
(α) est un autre paramètre de cette méthode.
def backward(self, da, learning_rate):
dz = ...
d_weights = ...
d_biases = ...
da_prev = ...
self.weights -= learning_rate * d_weights
self.biases -= learning_rate * d_biases
return da_prev
L’opérateur *
effectue une multiplication élément par élément, tandis que la fonction np.dot()
réalise un produit scalaire dans NumPy. L’attribut .T
transpose un tableau.
Merci pour vos commentaires !