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 entgegen, 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 für die Rückwärtspropagation Ableitungen von Aktivierungsfunktionen benötigt werden, sollten Aktivierungsfunktionen wie ReLU und Sigmoid als Klassen und nicht als eigenständige Funktionen strukturiert werden. Dies ermöglicht die Definition von:
- Der Aktivierungsfunktion selbst (implementiert über die Methode
__call__()
), sodass sie direkt in der KlasseLayer
mitself.activation(z)
angewendet werden kann; - Ihrer Ableitung (implementiert über die Methode
derivative()
), was eine effiziente Rückwärtspropagation ermöglicht und in der KlasseLayer
alsself.activation.derivative(z)
verwendet wird.
Durch die Strukturierung von Aktivierungsfunktionen als Objekte können diese einfach an die Klasse Layer
übergeben und dynamisch verwendet werden.
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)
Für beide dieser Aktivierungsfunktionen gilt, dass sie auf den gesamten Vektor z angewendet werden, ebenso wie deren Ableitungen. NumPy führt die Operation intern für jedes Element des Vektors aus. Enthält der Vektor z beispielsweise 3 Elemente, ergibt sich die Ableitung wie folgt:
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 activation function's derivative in backpropagation?
Could you provide an example of how to use these activation function classes in a neural network layer?
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 entgegen, 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 für die Rückwärtspropagation Ableitungen von Aktivierungsfunktionen benötigt werden, sollten Aktivierungsfunktionen wie ReLU und Sigmoid als Klassen und nicht als eigenständige Funktionen strukturiert werden. Dies ermöglicht die Definition von:
- Der Aktivierungsfunktion selbst (implementiert über die Methode
__call__()
), sodass sie direkt in der KlasseLayer
mitself.activation(z)
angewendet werden kann; - Ihrer Ableitung (implementiert über die Methode
derivative()
), was eine effiziente Rückwärtspropagation ermöglicht und in der KlasseLayer
alsself.activation.derivative(z)
verwendet wird.
Durch die Strukturierung von Aktivierungsfunktionen als Objekte können diese einfach an die Klasse Layer
übergeben und dynamisch verwendet werden.
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)
Für beide dieser Aktivierungsfunktionen gilt, dass sie auf den gesamten Vektor z angewendet werden, ebenso wie deren Ableitungen. NumPy führt die Operation intern für jedes Element des Vektors aus. Enthält der Vektor z beispielsweise 3 Elemente, ergibt sich die Ableitung wie folgt:
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!