Gradientenabstieg
Nicht mehr blind probieren, sondern bei jedem Schritt berechnen, in welche Richtung und wie stark die Parameter zu ändern sind. Von der Steigung zur Ableitung, Gradienten von Hand berechnen, die Schleife des Gradientenabstiegs schreiben und mit eigenen Augen sehen, was bei zu kleiner oder zu großer Lernrate und bei nicht standardisierten Daten passiert.
- Etwa 45 Minuten
- Niveau: Einsteiger
- Getestet: 2026-09-14 numpy 2.5, fester Zufallsstartwert
Code und Programmausgaben stehen genau so da, wie sie gelaufen sind – Kommentare und Ausgaben sind daher auf Chinesisch.
Die vorige Lektion fand mit der Rastersuche die beste Gerade, zeigte aber auch ihre Sackgasse: Bei mehr Parametern wird die Zahl der Kombinationen astronomisch.
Stell dir vor, du stehst mit verbundenen Augen an einem Berghang und willst zum tiefsten Punkt des Tals. Den ganzen Berg siehst du nicht, aber mit den Füßen spürst du, wohin der Boden unter dir abfällt. Also machst du einen kleinen Schritt bergab, spürst wieder, machst noch einen Schritt. So gehst du immer weiter und kommst schließlich im Tal an.
Das ist der Gradientenabstieg (gradient descent). Der „Berg“ ist der Verlust, deine Position sind die aktuellen Parameter, und „wohin es abfällt“ ist der Gradient.
Die Ableitung: einfach die Steigung
Zuerst betrachten wir nur einen Parameter w und halten b = 0 fest. Schiebt man w ein kleines Stück nach rechts, wie stark ändert sich der Verlust? Die Änderung geteilt durch die Verschiebung ist die Steigung des Verlusts an diesem Punkt. Wir messen sie direkt numerisch:
def mse(w, b, x=area, y=price):
return np.mean((w * x + b - y) ** 2)
w, b = 1.0, 0.0
for h in [0.1, 0.01, 0.001]:
slope = (mse(w + h, b) - mse(w, b)) / h
print(f" w 往右挪 {h:<6},损失变化 / 挪动距离 = {slope:10.2f}")
== 1. 在 w=1.0, b=0 这一点,损失对 w 的斜率
w 往右挪 0.1 ,损失变化 / 挪动距离 = -7300.21
w 往右挪 0.01 ,损失变化 / 挪动距离 = -8256.23
w 往右挪 0.001 ,损失变化 / 挪动距离 = -8351.83
Je kleiner die Verschiebung, desto stabiler die gemessene Steigung; sie nähert sich allmählich einem festen Wert. Diese „Steigung bei unendlich kleiner Verschiebung“ ist die Ableitung. Sie sagt uns zweierlei:
- Vorzeichen: Hier ist sie negativ, also wird der Verlust kleiner, wenn man
wnach rechts schiebt (vergrößert). Man solltewalso vergrößern. - Betrag: Der Betrag ist groß, der Hang ist hier also steil, und der Verlust reagiert sehr empfindlich auf
w.
Der Gradient: eine Ableitung pro Parameter
Wir haben zwei Parameter, w und b. Für jeden Parameter wird einzeln abgeleitet (beim Ableiten nach w gilt b als Konstante und umgekehrt); die beiden Zahlen zusammen heißen Gradient.
Numerisch zu messen ist zu langsam und ungenau. Zum Glück lässt sich die Ableitung der mittleren quadratischen Abweichung direkt als Formel hinschreiben. Der Verlust ist Mittelwert((w×x + b - y)²), und nach den Ableitungsregeln gilt:
损失对 w 的导数 = 平均( 2 × (w×x + b - y) × x )
损失对 b 的导数 = 平均( 2 × (w×x + b - y) )
Die Herleitung muss man sich nicht merken; es genügt zu wissen, dass sie „das obige Messen der Steigung algebraisch auf einmal exakt ausrechnet“. Als Code:
def gradients(w, b, x=area, y=price):
error = w * x + b - y
dw = np.mean(2 * error * x) # 损失对 w 的导数
db = np.mean(2 * error) # 损失对 b 的导数
return dw, db
== 2. 公式算出的梯度:dw=-8362.45,db=-79.98
dw = -8362.45 liegt sehr nah am numerisch gemessenen Ergebnis oben (-8351,83 bei einer Verschiebung von 0,001). Das ist eine gute Gewohnheit: Eine selbst hergeleitete Gradientenformel numerisch gegenprüfen, das deckt viele Fehler auf. Beim Schreiben der Backpropagation in der nächsten Lektion machen wir es wieder so.
Die Schleife des Gradientenabstiegs
Der Gradient zeigt in die Richtung, in der der Verlust am schnellsten zunimmt. Wir wollen ihn verringern, also machen wir einen kleinen Schritt in die Gegenrichtung des Gradienten:
w = w - 学习率 × dw
b = b - 学习率 × db
Die Lernrate (learning rate) bestimmt, wie groß jeder Schritt ist. Von w = 0, b = 0 aus wird dieser Schritt wiederholt:
def descend(lr, steps, x=area, y=price, report=()):
"""从 w=0, b=0 出发走 steps 步。发散时返回 None。"""
w, b = 0.0, 0.0
for step in range(1, steps + 1):
dw, db = gradients(w, b, x, y)
w -= lr * dw
b -= lr * db
if abs(w) > 1e6: # 越走越远,已经发散了
print(f" 第 {step} 步:w 已经变成 {w:.3g},发散了")
return None
if step in report:
print(f" 第 {step:5d} 步:w={w:7.4f} b={b:7.3f} 损失 {mse(w, b, x, y):10.2f}")
return w, b
Das ist die gesamte Kernlogik des Trainings. Beim Training von GPT in Modul 09 hat die Schleife genau diese Struktur, nur mit mehr Parametern und mit der Backpropagation der nächsten Lektion zur Gradientenberechnung.
Losgehen: nicht ganz so glatt
Mit Lernrate 0,00005 und 20.000 Schritten:
== 3. 学习率 0.00005,走 20000 步
第 1 步:w= 1.4804 b= 0.014 损失 244.38
第 10 步:w= 1.3935 b= 0.014 损失 164.22
第 100 步:w= 1.3934 b= 0.027 损失 164.18
第 1000 步:w= 1.3922 b= 0.155 损失 163.81
第 5000 步:w= 1.3871 b= 0.711 损失 162.27
第 20000 步:w= 1.3695 b= 2.615 损失 157.43
Schon im ersten Schritt fällt der Verlust von einigen Tausend auf 244, nach 10 Schritten auf 164. Dann bewegt er sich kaum noch: Nach 20.000 Schritten ist er erst bei 157, während die Rastersuche der vorigen Lektion einen minimalen Verlust von 143 fand. b ist sogar erstaunlich langsam; in 20.000 Schritten bewegt es sich nur von 0 auf 2,6, weit weg vom besten Wert (etwa 14,5).
Woran liegt das? Die zwei folgenden Experimente zeigen es.
Lernrate: zu klein ist zu langsam, zu groß explodiert
Einige andere Lernraten, jeweils 1000 Schritte:
== 4. 不同的学习率(都走 1000 步)
学习率 1e-05 :w=1.3932 b=0.041 损失 164.14
学习率 5e-05 :w=1.3922 b=0.155 损失 163.81
学习率 9e-05 :w=1.3912 b=0.268 损失 163.50
第 115 步:w 已经变成 1.03e+06,发散了
学习率 0.0001 :发散
Je größer die Lernrate, desto schneller geht es und desto weiter kommt b. Doch von 0,00009 auf 0,0001, nur ein winziger Unterschied, und alles explodiert: Bei Schritt 115 ist w über eine Million.
Die Divergenz entsteht so: In Richtung w ist der Hang zu steil (oben gemessen: Steigung -8362); ist der Schritt etwas zu groß, springt man mit einem Schritt über den Talboden hinweg und landet gegenüber höher; dort ist der Hang noch steiler, der nächste Schritt springt noch weiter … Jeder Schritt ist weiter vom Talboden entfernt als der vorige, die Werte werden immer größer, bis sie überlaufen.
Die Wurzel des Problems: In Richtung w ist der Hang zu steil, in Richtung b zu flach. dw ist -8362, db nur -80, ein Unterschied um das Hundertfache. Ist die Lernrate klein genug, damit w nicht divergiert, bewegt sich b nur extrem langsam. Eine einzige Lernrate kann nicht beide Richtungen zugleich bedienen.
Standardisierung: in jeder Richtung ungefähr gleich steil
Warum ist der Hang in Richtung w so steil? Weil die Flächenwerte groß sind, einige Dutzend bis über hundert Quadratmeter. In der Gradientenformel ist dw = Mittelwert(2 × Fehler × x); je größer x, desto größer dw.
Die Lösung: Die Fläche in Zahlen mit „Mittelwert 0, Standardabweichung 1“ umrechnen. Das heißt Standardisierung:
mean, std = area.mean(), area.std()
area_n = (area - mean) / std
Nach der Standardisierung liegen die Flächenwerte etwa zwischen -2 und 2, und die Hänge in Richtung w und b sind ungefähr gleich steil. Jetzt kann man ruhig die Lernrate 0,1 nehmen, nur 100 Schritte:
== 5. 面积标准化之后(均值 98.0,标准差 32.1),学习率 0.1 只走 100 步
第 1 步:w= 8.0605 b= 27.588 损失 13360.27
第 10 步:w=35.9749 b=123.129 损失 381.15
第 50 步:w=40.3018 b=137.939 损失 143.05
第 100 步:w=40.3023 b=137.941 损失 143.05
换算回原单位:w=1.2571 b=14.806
Nach 50 Schritten ist der tiefste Punkt erreicht, Verlust 143,05, sogar etwas niedriger als die 143,1 der Rastersuche der vorigen Lektion (die Rastersuche probierte nur alle 0,01, der beste Punkt kann zwischen zwei Rasterpunkten liegen). In die ursprünglichen Einheiten zurückgerechnet: w = 1.2571, b = 14.806.
Was vorher in 20.000 Schritten nicht gelang, schafft es nach der Standardisierung in 50 Schritten. Das ist eine sehr praktische Erfahrung beim Training neuronaler Netze: Die Wertebereiche der Eingaben sollten ähnlich sein. Die verschiedenen „Normalisierungen“, die dir später begegnen (LayerNorm, BatchNorm), gehen vom selben Gedanken aus.
Zusammenfassung des Gradientenabstiegs
- Die Ableitungen des Verlusts nach allen Parametern zusammen heißen Gradient; er zeigt in die Richtung, in der der Verlust am schnellsten zunimmt.
- Jeder Schritt geht ein kleines Stück in Gegenrichtung des Gradienten; die Schrittweite bestimmt die Lernrate.
- Ist die Lernrate zu klein, geht es langsam; ist sie zu groß, divergiert es. Sie ist die Zahl, die man beim Training am meisten einstellen muss.
- Unterscheiden sich die Wertebereiche der Eingaben stark, ist das Training schwer einzustellen; zuerst standardisieren.
Unsere Gerade hat nur zwei Parameter, die Gradientenformel lässt sich von Hand herleiten. Ein neuronales Netz aber hat Hunderte oder Tausende Parameter, Schicht um Schicht verschachtelt; die Ableitung jedes Parameters von Hand herzuleiten ist unmöglich. Die nächste Lektion zeigt, wie der Computer die Gradienten aller Parameter automatisch berechnet: die Backpropagation.
Übungen
- Setz auf den standardisierten Daten die Lernrate auf 0,5, 1,0 und 1,1, jeweils 100 Schritte, und sieh dir die Ergebnisse an. Wo ungefähr liegt die kritische Lernrate?
- Ohne Standardisierung, nur mit Lernrate 0,00009: Wie viele Schritte braucht es, bis der Verlust unter 144 fällt? Schätz es, dann führ es zur Prüfung aus.
- Ist beim numerischen Ableiten ein möglichst kleines
ham besten? Setzhauf1e-10und1e-15und sieh dir die gemessene Steigung an. Wird das Ergebnis sogar schlechter? Überleg, warum (Hinweis: Die Genauigkeit von Dezimalzahlen im Computer ist begrenzt).
Selbsttest
1. Warum geht der Gradientenabstieg in die „Gegenrichtung“ des Gradienten?
Der Gradient zeigt in die Richtung, in der der Verlust am schnellsten zunimmt. Unser Ziel ist, den Verlust zu verringern, also gehen wir in die entgegengesetzte Richtung.
2. Die Lernrate stieg nur von 0,00009 auf 0,0001, und das Training divergierte. Was ist passiert?
In Richtung w ist der Hang des Verlusts sehr steil. Ist die Lernrate etwas zu groß, springt man mit einem Schritt über den tiefsten Punkt hinweg und landet gegenüber höher, wo der Hang noch steiler ist, und der nächste Schritt springt noch weiter. Jeder Schritt ist weiter vom tiefsten Punkt entfernt als der vorige, die Werte werden immer größer, bis sie überlaufen.
3. Warum wurde das Training nach der Standardisierung der Fläche um das Hundertfache schneller?
Ohne Standardisierung sind die Flächenwerte groß, und der Gradient in Richtung w ist hundertmal größer als in Richtung b. Die Lernrate muss sich nach der steilen w-Richtung richten und sehr klein sein, deshalb kommt b nur extrem langsam voran. Nach der Standardisierung sind beide Hänge ungefähr gleich steil, man kann eine viel größere Lernrate nehmen, und beide Parameter erreichen schnell den tiefsten Punkt.
Fragen und Diskussion
Hängst du in dieser Lektion fest? Frag hier. Und wenn du die Frage von jemandem beantworten kannst, tu es gern.
Eine Frage bringt 3 Punkte, eine Antwort 6. Beiträge erscheinen nach der Prüfung.
Diskussion wird geladen…