Wie findet ein Programm den kleinsten Fehler?
Der Gradientenabstieg sucht den kleinsten Wert einer Funktion, indem er immer einen kleinen Schritt bergab geht. So trainieren Programme ihre Modelle: Sie senken Schritt für Schritt einen Fehler.
Stellen Sie sich eine Wanderung im Nebel vor. Sie sehen nur den Boden unter Ihren Füßen und gehen dorthin, wo er am steilsten abfällt. Irgendwann liegt vor Ihnen kein Gefälle mehr.
Am Ende dieser Lektion
Notiz
Ich kann eine Funktion durch kleine Schritte bergab minimieren.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Gradientenabstieg | wiederholt einen kleinen Schritt gegen den Gradienten gehen |
| Lernrate | der Faktor, der die Länge jedes Schritts bestimmt |
| Minimum | der kleinste Wert einer Funktion |
| Abbruchbedingung | die Regel, die sagt, wann man aufhört |
| Divergenz | die Schritte führen immer weiter weg vom Ziel |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Schritt zieht Steigung mal Lernrate ab
Der Gradientenabstieg wiederholt eine Zeile: neues x gleich altes x minus Lernrate mal Steigung. Bei einer Eingabe ist die Steigung die Ableitung.
Ist die Steigung negativ, geht es nach rechts bergab, und das Minus wird zum Plus. Ist sie nahe 0, wird der Schritt klein, und Sie bremsen vor dem Minimum von selbst.
Beispiel: fünf Schritte bei der Lernrate 0,1
| Schritt | x vorher | Steigung 2 * (x - 3) | x nachher |
|---|---|---|---|
| 1 | 0 | -6 | 0,6 |
| 2 | 0,6 | -4,8 | 1,08 |
| 3 | 1,08 | -3,84 | 1,464 |
| 4 | 1,464 | -3,072 | 1,7712 |
| 5 | 1,7712 | -2,4576 | 2,017 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Fünf Schritte in Python
def steigung(x):
return 2 * (x - 3) # Ableitung von (x - 3) ** 2 + 1
x = 0.0
lernrate = 0.1
for schritt in range(5):
x = x - lernrate * steigung(x)
print("Schritt", schritt + 1, ": x =", round(x, 4))
# Ändern Sie die Lernrate in 0.5. Wo landen Sie nach dem ersten Schritt?
Dieselben Zahlen aus einer Formel
docker exec jupyter python3 -c "print([round(3 - 3 * 0.8 ** n, 4) for n in range(1, 6)])"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Lernrate entscheidet, ob der Abstieg gelingt
Eine kleine Lernrate führt sicher, aber langsam. Eine zu große Lernrate springt über das Minimum hinaus, und jeder Sprung landet weiter weg als der vorige. Das heißt Divergenz.
Die Tabelle startet immer bei 0. Das Minimum liegt bei 3. Bei Lernrate 0,5 ist es nach einem Schritt erreicht, bei 1,0 pendelt x zwischen 0 und 6, bei 1,1 wächst der Abstand.
Beispiel: drei Lernraten ab x = 0
| Lernrate | Schritt 1 | Schritt 2 | Schritt 3 | Schritt 4 | Verhalten |
|---|---|---|---|---|---|
| 0,1 | 0,6 | 1,08 | 1,464 | 1,7712 | nähert sich langsam 3 |
| 0,5 | 3 | 3 | 3 | 3 | trifft 3 sofort |
| 1,0 | 6 | 0 | 6 | 0 | pendelt, kommt nie an |
| 1,1 | 6,6 | -1,32 | 8,184 | -3,2208 | divergiert |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Schritte bei Lernrate 1,1
docker exec jupyter python3 -c "print([round(3 - 3 * (-1.2) ** n, 2) for n in range(1, 5)])"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein häufiger Fehler
Warnung
Viele denken, eine größere Lernrate führe schneller zum Ziel. Das gilt nur bis zu einer Grenze. Darüber springt der Abstieg über das Minimum hinaus und entfernt sich immer weiter. Beginnen Sie klein und vergrößern Sie die Lernrate vorsichtig.
Eine Abbruchbedingung beendet die Schleife
Der Abstieg erreicht das Minimum nie ganz genau. Deshalb brauchen Sie eine Abbruchbedingung: Hören Sie auf, wenn die Steigung klein genug ist, zum Beispiel unter 0,01.
Zusätzlich setzen Sie eine Höchstzahl von Schritten. So endet die Schleife auch dann, wenn der Abstieg divergiert.
Abstieg mit Abbruch
def steigung(x):
return 2 * (x - 3)
x = 0.0
lernrate = 0.1
schritte = 0
while abs(steigung(x)) > 0.01 and schritte < 1000:
x = x - lernrate * steigung(x)
schritte = schritte + 1
print("Schritte:", schritte)
print("x:", round(x, 3))
# Ändern Sie die Grenze 0.01 in 0.0001. Wie viele Schritte brauchen Sie jetzt?