Kettenregel -- Die Zerlegungstechnik zum Differenzieren zusammengesetzter Funktionen
Die Kettenregel ist die mathematische Seele des Backpropagation-Algorithmus.Äußere Ableitung × innere Ableitung, Schicht für Schicht weitergegeben.
Konzeptanalyse
Univariate Kettenregel
Wenn y = g(x), z = f(y), dann:
\[ \frac{dz}{dx} = \frac{dz}{dy} \cdot \frac{dy}{dx} \]Backpropagation = Kettenregel, angewendet in umgekehrter Richtung entlang des Rechengraphen
Während der Backpropagation pflanzt sich der GradientSchicht für Schicht von der Ausgabe zur Eingabe fort: Der "lokale Gradient" × "Upstream-Gradient" jeder Schicht = der Gradient der Parameter dieser Schicht in Bezug auf den Verlust.
Praxisbeispiel
Gaspedal → Kraftstoffverbrauch
Der Kraftstoffverbrauch hängt von der Geschwindigkeit ab, und die Geschwindigkeit hängt davon ab, wie tief das Gaspedal gedrückt wird.
"Wenn Sie das Gaspedal etwas mehr drücken, um wie viel steigt der Kraftstoffverbrauch?" = (Änderungsrate des Kraftstoffverbrauchs in Bezug auf die Geschwindigkeit) × (Änderungsrate der Geschwindigkeit in Bezug auf das Gaspedal).
Das ist die Kettenregel:Änderungen Schicht für Schicht weitergeben, multiplizieren, um den Gesamteffekt zu erhalten.。
Praktische Python-Übung
Beispiel
x = sp.Symbol('x')
# f(g(x)): sin(x^2), äußeres sin, inneres x^2
d_direct = sp.diff(sp.sin(x**2), x)
d_chain = sp.cos(x**2) * 2*x
print(f"direkte Differentiation: {d_direct}")
print(f"Kettenregel: cos(x^2)·2x = {d_chain}")
print(f"konsistent: {sp.simplify(d_direct-d_chain)==0}")
# Backpropagation für ein zweischichtiges Netz
w, xi, yi = sp.symbols('w x_i y_i')
a = sp.Symbol('a') # Zwischenvariablen separat als Symbole definieren
a_expr = w * xi # Der konkrete Ausdruck von a in Bezug auf w
loss = (a - yi)**2 # loss ist als Funktion des symbolischen a definiert
dL_da = sp.diff(loss, a) # ∂L/∂a
da_dw = sp.diff(a_expr, w) # ∂a/∂w
dL_dw_chain = dL_da.subs(a, a_expr) * da_dw # Kettenregel: a=w*x_i einsetzen und multiplizieren
loss_direct = loss.subs(a, a_expr) # loss vollständig als Funktion von w ausmultiplizieren
dL_dw_direct = sp.diff(loss_direct, w)
print(f"\n"Kettenregel ∂L/∂w: {sp.simplify(dL_dw_chain)}")
print(fDirekt ∂L/∂w: {sp.simplify(dL_dw_direct)})
print(fKonsistent: {sp.simplify(dL_dw_chain-dL_dw_direct)==0})
Ausgabe:
直接求导: 2*x*cos(x**2) 链式法则: cos(x^2)·2x = 2*x*cos(x**2) 一致: True 链式 ∂L/∂w: 2*x_i*(w*x_i - y_i) 直接 ∂L/∂w: 2*x_i*(w*x_i - y_i) 一致: True
Anwendungsszenarien in der KI
Backpropagation = Systematische Anwendung der Kettenregel auf Rechengraphen
Die Autograd-Engine von PyTorch zeichnet bei jeder Tensoroperation automatisch den Rechengraphen auf. Wenn loss.backward() aufgerufen wird, startet sie vom Loss-Knoten und durchläuft den Graphen in umgekehrter Richtung, wobei sie die Kettenregel auf jeden Knoten anwendet: lokaler Gradient × Upstream-Gradient = Downstream-Gradient. Entwickler müssen keinen Ableitungscode von Hand schreiben.
Gradientenprüfung
Wenn Sie eine benutzerdefinierte Schicht oder Verlustfunktion von Hand schreiben, wie überprüfen Sie, dass die Backpropagation-Gradientenberechnung korrekt ist? Verwenden Sie den numerischen Gradienten \( (f(x+h)-f(x-h))/2h \) als "Ground Truth" und vergleichen Sie ihn mit dem von autograd berechneten Gradienten. Der relative Fehler sollte kleiner als 1e-5 sein. Das ist das Prinzip von torch.autograd.gradcheck in PyTorch.
Optimierung von Rechengraphen
Compiler für Deep Learning (wie TensorRT, XLA) optimieren Rechengraphen: benachbarte Operationen zusammenführen (Operator-Fusion), um Speicherlese- und -schreibzugriffe zu reduzieren. Es muss jedoch sichergestellt werden, dass die Gradientenberechnung unter der Kettenregel korrekt bleibt – dies ist eine wichtige Einschränkung der Graphoptimierung.
Weitere Erweiterungen