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 telles que ReLU et sigmoïde doivent être implémentées sous forme de classes plutôt que de fonctions autonomes. Cette structure permet de définir clairement les deux composants :
- La fonction d'activation elle-même — implémentée via la méthode
__call__(), afin qu'elle puisse être appliquée directement dans la classeLayeravecself.activation(z); - Sa dérivée — implémentée via la méthode
derivative(), permettant un calcul efficace lors de la rétropropagation viaself.activation.derivative(z).
Représenter les fonctions d'activation sous forme d'objets facilite leur passage à différentes couches et leur application dynamique lors de la propagation avant et arrière.
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 les deux fonctions d'activation, l'opération est appliquée à l'ensemble du vecteur z, ainsi qu'à sa dérivée. NumPy effectue automatiquement le calcul élément par élément, ce qui signifie que chaque élément du vecteur est traité indépendamment.
Par exemple, si le vecteur z contient trois éléments, la dérivée est calculée comme suit :
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 les 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
Can you explain how the backward() method uses the stored attributes in the Layer class?
What is the purpose of the derivative() method in the activation function classes?
Could you provide an example of how forward and backward propagation work together in a simple neural network?
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 telles que ReLU et sigmoïde doivent être implémentées sous forme de classes plutôt que de fonctions autonomes. Cette structure permet de définir clairement les deux composants :
- La fonction d'activation elle-même — implémentée via la méthode
__call__(), afin qu'elle puisse être appliquée directement dans la classeLayeravecself.activation(z); - Sa dérivée — implémentée via la méthode
derivative(), permettant un calcul efficace lors de la rétropropagation viaself.activation.derivative(z).
Représenter les fonctions d'activation sous forme d'objets facilite leur passage à différentes couches et leur application dynamique lors de la propagation avant et arrière.
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 les deux fonctions d'activation, l'opération est appliquée à l'ensemble du vecteur z, ainsi qu'à sa dérivée. NumPy effectue automatiquement le calcul élément par élément, ce qui signifie que chaque élément du vecteur est traité indépendamment.
Par exemple, si le vecteur z contient trois éléments, la dérivée est calculée comme suit :
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 les 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 !