Implementierung der Backpropagation
Allgemeiner Ansatz
Bei der Vorwärtspropagation nimmt jede Schicht l die Ausgaben der vorherigen Schicht, al−1, als Eingaben und berechnet ihre eigenen Ausgaben. Daher nimmt die Methode forward() der Klasse Layer den Vektor der vorherigen Ausgaben als einzigen Parameter, während die restlichen benötigten Informationen innerhalb der Klasse gespeichert werden.
Bei der Rückwärtspropagation benötigt jede Schicht l nur dal, um die jeweiligen Gradienten zu berechnen und dal−1 zurückzugeben. Die Methode backward() nimmt daher den Vektor dal als Parameter. Die übrigen erforderlichen Informationen sind bereits in der Klasse Layer gespeichert.
Ableitungen von Aktivierungsfunktionen
Da die Ableitungen von Aktivierungsfunktionen für die Rückwärtspropagation benötigt werden, sollten Aktivierungsfunktionen wie ReLU und Sigmoid als Klassen und nicht als eigenständige Funktionen implementiert werden. Diese Struktur ermöglicht es, beide Komponenten klar zu definieren:
- Die Aktivierungsfunktion selbst — implementiert über die Methode
__call__(), sodass sie direkt in der KlasseLayermitself.activation(z)angewendet werden kann; - Ihre Ableitung — implementiert über die Methode
derivative(), was eine effiziente Berechnung während der Rückwärtspropagation überself.activation.derivative(z)ermöglicht.
Die Darstellung von Aktivierungsfunktionen als Objekte erleichtert es, sie an verschiedene Schichten zu übergeben und sowohl während der Vorwärts- als auch der Rückwärtspropagation dynamisch anzuwenden.
ReLU
Die Ableitung der ReLU-Aktivierungsfunktion ist wie folgt, wobei zi ein Element des Vektors der Voraktivierungen z ist:
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)
Sigmoid
Die Ableitung der Sigmoid-Aktivierungsfunktion lautet:
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)
Bei beiden Aktivierungsfunktionen wird die Operation auf den gesamten Vektor z sowie auf dessen Ableitung angewendet. NumPy führt die Berechnung dabei elementweise durch, das heißt, jedes Element des Vektors wird unabhängig voneinander verarbeitet.
Enthält der Vektor z beispielsweise drei Elemente, wird die Ableitung wie folgt berechnet:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)Die backward()-Methode
Die Methode backward() ist verantwortlich für das Berechnen der Gradienten anhand der folgenden Formeln:
a^{l-1} und zl werden in der Klasse inputs als die Attribute outputs bzw. Layer gespeichert. Die Aktivierungsfunktion f wird als Attribut activation gespeichert.
Sobald alle benötigten Gradienten berechnet wurden, können Gewichte und Biases aktualisiert werden, da sie für weitere Berechnungen nicht mehr benötigt werden:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDaher ist learning_rate (α) ein weiterer Parameter dieser Methode.
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
Der *-Operator führt eine elementweise Multiplikation durch, während die Funktion np.dot() das Skalarprodukt in NumPy berechnet. Das Attribut .T transponiert ein Array.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
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
Implementierung der Backpropagation
Swipe um das Menü anzuzeigen
Allgemeiner Ansatz
Bei der Vorwärtspropagation nimmt jede Schicht l die Ausgaben der vorherigen Schicht, al−1, als Eingaben und berechnet ihre eigenen Ausgaben. Daher nimmt die Methode forward() der Klasse Layer den Vektor der vorherigen Ausgaben als einzigen Parameter, während die restlichen benötigten Informationen innerhalb der Klasse gespeichert werden.
Bei der Rückwärtspropagation benötigt jede Schicht l nur dal, um die jeweiligen Gradienten zu berechnen und dal−1 zurückzugeben. Die Methode backward() nimmt daher den Vektor dal als Parameter. Die übrigen erforderlichen Informationen sind bereits in der Klasse Layer gespeichert.
Ableitungen von Aktivierungsfunktionen
Da die Ableitungen von Aktivierungsfunktionen für die Rückwärtspropagation benötigt werden, sollten Aktivierungsfunktionen wie ReLU und Sigmoid als Klassen und nicht als eigenständige Funktionen implementiert werden. Diese Struktur ermöglicht es, beide Komponenten klar zu definieren:
- Die Aktivierungsfunktion selbst — implementiert über die Methode
__call__(), sodass sie direkt in der KlasseLayermitself.activation(z)angewendet werden kann; - Ihre Ableitung — implementiert über die Methode
derivative(), was eine effiziente Berechnung während der Rückwärtspropagation überself.activation.derivative(z)ermöglicht.
Die Darstellung von Aktivierungsfunktionen als Objekte erleichtert es, sie an verschiedene Schichten zu übergeben und sowohl während der Vorwärts- als auch der Rückwärtspropagation dynamisch anzuwenden.
ReLU
Die Ableitung der ReLU-Aktivierungsfunktion ist wie folgt, wobei zi ein Element des Vektors der Voraktivierungen z ist:
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)
Sigmoid
Die Ableitung der Sigmoid-Aktivierungsfunktion lautet:
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)
Bei beiden Aktivierungsfunktionen wird die Operation auf den gesamten Vektor z sowie auf dessen Ableitung angewendet. NumPy führt die Berechnung dabei elementweise durch, das heißt, jedes Element des Vektors wird unabhängig voneinander verarbeitet.
Enthält der Vektor z beispielsweise drei Elemente, wird die Ableitung wie folgt berechnet:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)Die backward()-Methode
Die Methode backward() ist verantwortlich für das Berechnen der Gradienten anhand der folgenden Formeln:
a^{l-1} und zl werden in der Klasse inputs als die Attribute outputs bzw. Layer gespeichert. Die Aktivierungsfunktion f wird als Attribut activation gespeichert.
Sobald alle benötigten Gradienten berechnet wurden, können Gewichte und Biases aktualisiert werden, da sie für weitere Berechnungen nicht mehr benötigt werden:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDaher ist learning_rate (α) ein weiterer Parameter dieser Methode.
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
Der *-Operator führt eine elementweise Multiplikation durch, während die Funktion np.dot() das Skalarprodukt in NumPy berechnet. Das Attribut .T transponiert ein Array.
Danke für Ihr Feedback!