12  Gradient Descent als numerisches Minimierungsverfahren

In vielen technischen Anwendungen ist eine Funktion gegeben, deren Minimum bestimmt werden soll.
Eine analytische Bestimmung dieses Minimums ist jedoch nicht immer möglich oder praktikabel.
Stattdessen wird das Minimum numerisch, also schrittweise, angenähert.

Wir betrachten eine reellwertige Funktion

\[ f(x) \]

und setzen voraus, dass ihre Ableitung

\[ f'(x) \]

existiert und bekannt ist.

12.1 Die Rolle der Ableitung

Die Ableitung \(f'(x)\) gibt die momentane Änderungsrate der Funktion an der Stelle \(x\) an:

\[ \begin{aligned} f'(x) > 0 \quad &\Rightarrow \quad \text{Die Funktion steigt} \\ f'(x) < 0 \quad &\Rightarrow \quad \text{Die Funktion fällt} \\ f'(x) = 0 \quad &\Rightarrow \quad \text{Maximum, Minimum oder Wendepunkt} \end{aligned} \]

Um ein Minimum zu erreichen, muss \(x\) in die Richtung abnehmender Funktionswerte bewegt werden – also entgegen der lokalen Steigung:

\[ \text{Bewegungsrichtung} = -f'(x) \]

12.2 Die Update-Regel des Gradient Descent

Der Gradient Descent passt den Wert \(x\) in jedem Schritt wie folgt an:

\[ x_{k+1} \leftarrow x_k - \eta \cdot f'(x_k) \]

Symbol Bedeutung
\(f'(x_k)\) Ableitung der Funktion \(f\) an der aktuellen Stelle \(x_k\) (lokale Steigung)
\(\eta\) Schrittweite (im Kontext von neuronalen Netzen auch Lernrate genannt)

Die Lernrate \(\eta > 0\) bestimmt, wie groß jeder einzelne Korrekturschritt ist.

12.3 Abbruchkriterien

Der Algorithmus wird iterativ ausgeführt, bis eines der folgenden Kriterien erfüllt ist:

  • Die absolute Änderung des Funktionswerts unterschreitet einen Schwellwert:
    \[ |f(x_{k+1}) - f(x_k)| < \varepsilon \]
  • Der Betrag der Ableitung wird sehr klein:
    \[ |f'(x_k)| < \varepsilon_g \]
  • Eine maximale Anzahl von Iterationen ist erreicht.

Diese Bedingungen verhindern unnötig lange Rechenläufe.

12.4 Numerisches Beispiel (Python)

Das folgende Beispiel minimiert die Funktion \(f(x) = (x-3)^2\), deren Minimum bei \(x=3\) liegt.

Code
def f(x):
    return (x - 3)**2

def df_dx(x):
    return 2 * (x - 3)

x = 8.0          # Startwert
eta = 0.1        # Lernrate
max_steps = 12

for step in range(max_steps):
    x_new = x - eta * df_dx(x)
    print(f"Schritt {step+1:2d}:  x = {x_new:8.4f},  f(x) = {f(x_new):10.6f}")
    x = x_new

12.5 Erweiterung auf mehrere Dimensionen: Der Gradient

In vielen praktischen Anwendungen hängt die zu minimierende Funktion nicht von einer einzelnen Variablen ab, sondern von mehreren Parametern gleichzeitig.

12.5.1 Vom Skalar zum Vektor

Anstelle einer einzelnen Zahl \(x\) wird nun ein Parametervektor \(\mathbf{x}\) betrachtet:

\[\mathbf{x} = \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{pmatrix}\]

Die zu minimierende Funktion ist nun eine Funktion mehrerer Veränderlicher:

\[f(\mathbf{x}) = f(x_1, x_2, \ldots, x_n)\]

An die Stelle der einfachen Ableitung tritt der Gradient, symbolisiert durch das Nabla-Symbol \(\nabla\).

12.5.2 Das Konzept des Gradienten

Der Gradient \(\nabla f(\mathbf{x})\) ist ein Vektor, der die partiellen Ableitungen nach allen Variablen enthält:

\[\nabla f(\mathbf{x}) = \begin{pmatrix} \frac{\partial f}{\partial x_1} \\ \frac{\partial f}{\partial x_2} \\ \vdots \\ \frac{\partial f}{\partial x_n} \end{pmatrix}\]

Geometrisch hat dieser Vektor zwei entscheidende Eigenschaften:

  • Er zeigt in jedem Punkt in die Richtung des steilsten Anstiegs der Funktion.
  • Seine Länge gibt an, wie stark die Funktion in dieser Richtung ansteigt.

Für das Minimierungsverfahren gilt analog zum eindimensionalen Fall: Um den steilsten Abstieg zu erreichen, erfolgt die Bewegung entgegen der Richtung des Gradienten.

12.5.3 Die verallgemeinerte Update-Regel

Die mathematische Struktur der Anpassung bleibt erhalten, wird jedoch auf Vektoren angewendet:

\[\mathbf{x}_{k+1} = \mathbf{x}_k - \eta \cdot \nabla f(\mathbf{x}_k)\]

Symbol Bedeutung
\(\mathbf{x}_k\) Parametervektor zum Iterationsschritt \(k\)
\(\nabla f(\mathbf{x}_k)\) Gradient der Funktion \(f\) an der Stelle \(\mathbf{x}_k\) (Richtung des steilsten Anstiegs)
\(\eta\) Schrittweite

Diese vektorielle Form des Gradient Descent ermöglicht die gleichzeitige Optimierung aller Parameter. Jede Komponente des Parametervektors wird proportional zur entsprechenden partiellen Ableitung angepasst.

12.6 Numerisches Beispiel in mehreren Dimensionen (Python)

Das folgende Beispiel minimiert die Funktion \(f(\mathbf{x}) = (x_1-2)^2 + (x_2+1)^2\), deren Minimum bei \(\mathbf{x} = (2, -1)\) liegt.

Code
import numpy as np

def f(x):
    return (x[0] - 2)**2 + (x[1] + 1)**2

def gradient_f(x):
    df_dx1 = 2 * (x[0] - 2)
    df_dx2 = 2 * (x[1] + 1)
    return np.array([df_dx1, df_dx2])

x = np.array([5.0, 3.0])  # Startwert
eta = 0.1                  # Lernrate
max_steps = 12

for step in range(max_steps):
    grad = gradient_f(x)
    x_new = x - eta * grad
    print(f"Schritt {step+1:2d}: x = [{x_new[0]:7.4f}, {x_new[1]:7.4f}], f(x) = {f(x_new):10.6f}")
    x = x_new

Die Ausgabe zeigt, wie sich der Parametervektor schrittweise dem Minimum annähert, während der Funktionswert kontinuierlich abnimmt.

12.7 Grenzen des klassischen Gradient Descent

Obwohl der klassische Gradient Descent die theoretische Basis bildet, stößt er in der Praxis auf drei wesentliche Probleme:

  1. Lokale Minima und Sattelpunkte: Das Verfahren ist “kurzsichtig”. Es folgt stur dem lokalen Gefälle. In einer zerklüfteten Funktionslandschaft kann es in einem lokalen Minimum stecken bleiben, während das globale Minimum unerreichbar bleibt.

  2. Plateaus und flache Regionen: Ist die Steigung sehr gering, werden die Korrekturschritte verschwindend klein. Das Verfahren kommt praktisch zum Stillstand und benötigt extrem viele Iterationen, um voranzukommen.

  3. Wahl der Lernrate: Ein festes \(\eta\) ist oft problematisch. Ist es zu groß, springt das Verfahren über das Ziel hinaus; ist es zu klein, dauert die Optimierung zu lange.

12.8 Ein moderner Optimierer: Der ADAM-Algorithmus

Zur Überwindung der beschriebenen Schwächen des klassischen Gradient Descent werden in der Praxis weiterentwickelte Optimierungsverfahren eingesetzt. Ein weit verbreiteter Algorithmus ist ADAM (Adaptive Moment Estimation).

ADAM kombiniert zwei Erweiterungen des Standard-Gradient-Descent, die zu einer stabileren und effizienteren Optimierung führen.

12.8.1 1. Momentum (Trägheit)

Beim klassischen Gradient Descent basiert jedes Update ausschließlich auf der aktuellen Steigung der Funktion.

ADAM berücksichtigt zusätzlich Informationen aus vorherigen Iterationen, indem gleitende Mittelwerte der Gradienten gebildet werden.

Zur Veranschaulichung kann dieser Effekt mit einer Kugel verglichen werden, die eine geneigte Fläche hinabrollt. Durch ihre Trägheit setzt sie ihre Bewegung in einer bevorzugten Richtung fort, selbst wenn lokale Unebenheiten oder kleine Gegensteigungen auftreten.

Übertragen auf das Optimierungsverfahren bedeutet dies, dass konsistente Gradientenrichtungen verstärkt werden, während kurzzeitige Schwankungen im Gradientenverlauf abgeschwächt werden.

12.8.2 2. Adaptive Lernrate

Im Standard-Gradient-Descent wird für alle Parameter dieselbe feste Schrittweite verwendet.

ADAM passt die effektive Lernrate für jeden Parameter individuell an, basierend auf der Größe der beobachteten Gradienten.

Parameter mit großen Gradienten werden mit kleineren Schritten angepasst, während Parameter mit kleinen Gradienten größere relative Anpassungen erhalten. Dies trägt zu einer stabileren und effizienteren Optimierung bei.


In der praktischen Anwendung erweist sich ADAM häufig als robust gegenüber der Wahl der initialen Lernrate und zeigt eine schnelle Konvergenz bei komplexen, hochdimensionalen Zielfunktionen.