Wann darf man einem Optimierer trauen?
Ein Optimierer ist ein fertiges Programm, das den kleinsten Wert einer Funktion sucht, zum Beispiel minimize aus der Bibliothek SciPy. Wer weiß, wo ein Abstieg hängen bleibt, erkennt, wann ein Ergebnis nicht stimmt.
Ein Optimierer liefert immer eine Antwort. Ob sie das beste Ergebnis ist, hängt vom Startpunkt und von der Form der Funktion ab.
Am Ende dieser Lektion
Notiz
Ich kann den Optimierer von SciPy nutzen und sagen, wann ein Abstieg hängen bleibt.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Optimierer | ein Programm, das den kleinsten Wert einer Funktion sucht |
| Startwert | der Punkt, an dem die Suche beginnt |
| Lokales Minimum | ein Tal, das nur in seiner Nähe am tiefsten ist |
| Globales Minimum | der tiefste Punkt der ganzen Funktion |
| Plateau | eine flache Stelle, an der der Gradient null ist |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
minimize braucht eine Funktion und einen Startwert
Die Funktion minimize aus scipy.optimize nimmt Ihre Funktion und einen Startwert und steigt von dort ab. Ihre Funktion bekommt eine Liste p mit allen Eingaben.
Im Beispiel ist der Fehler (p[0] - 3) ** 2 + (p[1] + 1) ** 2. Sein tiefster Punkt liegt bei p[0] = 3 und p[1] = -1. Der Optimierer findet ihn ohne Lernrate, die er selbst wählt.
Zwei Eingaben mit minimize minimieren
docker exec jupyter python3 -c "from scipy.optimize import minimize; r = minimize(lambda p: (p[0]-3)**2 + (p[1]+1)**2, [0, 0]); print(r.x.round(3))"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Eine Eingabe mit minimize_scalar minimieren
docker exec jupyter python3 -c "from scipy.optimize import minimize_scalar; r = minimize_scalar(lambda x: (x - 3) ** 2 + 1); print(round(r.x, 3), round(r.fun, 3))"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Bei mehreren Tälern entscheidet der Startwert
Manche Funktionen haben mehrere Täler. Ein Abstieg läuft in das Tal, das vom Start aus bergab liegt, und bleibt dort. Ein lokales Minimum ist nur in seiner Nähe am tiefsten.
Das globale Minimum ist der tiefste Punkt der ganzen Funktion. Die Funktion x ** 4 - 3 * x ** 2 + x hat zwei Täler, ein tieferes links und ein flacheres rechts.
Beispiel: zwei Täler, zwei Ergebnisse
| Startwert | Tal, in das der Abstieg läuft | Ort des Tals | Wert der Funktion dort |
|---|---|---|---|
| 2 | rechts, das flachere | 1,13 | -1,07 |
| -2 | links, das tiefere | -1,3 | -3,514 |
| 0 | links, weil die Steigung dort positiv ist | -1,3 | -3,514 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Zwei Starts, zwei Ergebnisse
def ableitung(x):
return 4 * x ** 3 - 6 * x + 1 # Ableitung von x**4 - 3*x**2 + x
for start in [2.0, -2.0]:
x = start
for schritt in range(1000):
x = x - 0.01 * ableitung(x)
print("Start", start, "-> x =", round(x, 3))
# Probieren Sie den Start 0.0. In welches Tal laufen Sie?
Dieselben Täler mit SciPy
docker exec jupyter python3 -c "from scipy.optimize import minimize; f = lambda p: p[0]**4 - 3*p[0]**2 + p[0]; print(minimize(f, [2.0]).x.round(2), minimize(f, [-2.0]).x.round(2))"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 Werte in beiden Tälern
docker exec jupyter python3 -c "from scipy.optimize import minimize; f = lambda p: p[0]**4 - 3*p[0]**2 + p[0]; print(round(minimize(f, [2.0]).fun, 3), round(minimize(f, [-2.0]).fun, 3))"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, ein Optimierer finde immer den tiefsten Punkt. Er findet ein Tal. Ob es das tiefste ist, sagt er nicht. Starten Sie deshalb von mehreren Punkten und nehmen Sie das beste Ergebnis.
Plateau und große Lernrate stoppen den Abstieg
Auf einem Plateau ist der Gradient null, und der Abstieg macht keinen Schritt mehr, obwohl tiefer noch etwas liegen kann. Der Startwert entscheidet auch hier.
Bei zu großer Lernrate divergiert der Abstieg: Die Werte wachsen immer weiter. Erkennen Sie das daran, dass x eine große Grenze überschreitet, und brechen Sie dann ab.
Ein Start auf einem Plateau
docker exec jupyter python3 -c "from scipy.optimize import minimize; f = lambda p: max(0, abs(p[0]) - 1) ** 2; r = minimize(f, [0.5]); print(r.x.round(3))"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Divergenz erkennen und abbrechen
def ableitung(x):
return 2 * (x - 3)
x = 0.0
for schritt in range(1, 41):
x = x - 1.1 * ableitung(x)
if abs(x) > 1000:
print("Abbruch nach", schritt, "Schritten, x =", round(x))
break
print("Letztes x:", round(x))
# Ändern Sie 1.1 in 0.9. Was gibt das Programm jetzt aus?
Beispiel: Anzeichen, Ursache und Gegenmittel
| Anzeichen | Wahrscheinliche Ursache | Gegenmittel |
|---|---|---|
| Die Werte wachsen immer weiter | Lernrate zu groß | Lernrate verkleinern |
| Der Ergebnispunkt hängt vom Start ab | Mehrere lokale Minima | Von mehreren Punkten starten |
| Der Abstieg bewegt sich nicht | Plateau, Gradient gleich null | Anderen Startwert wählen |
| Sehr langsamer Fortschritt | Lernrate zu klein | Lernrate vorsichtig vergrößern |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.