Lernpfad
Stell dir vor, du willst mit verbundenen Augen den tiefsten Punkt in einer Hügellandschaft finden. Du kannst nur den Boden direkt um dich herum ertasten, um herauszufinden, wo es bergab geht. Genau so verhalten sich Machine-Learning-Algorithmen, wenn sie die beste Lösung für ein Problem suchen.
Sie übersetzen das Problem in eine mathematische Funktion, deren Eingaben und Ausgaben einer hügeligen Oberfläche entsprechen. Das Minimum dieser Funktion zu finden, bedeutet, die beste Lösung erreicht zu haben. Einer der beliebtesten Algorithmen dafür ist Stochastic Gradient Descent (SGD).
In diesem Tutorial lernst du alles Wichtige über den Algorithmus: erst ein Gefühl ohne Formeln, dann die mathematischen Details und schließlich die Umsetzung in Python.
Was ist Stochastic Gradient Descent? Die Kurzfassung
Stochastic Gradient Descent (SGD) ist eine Optimierungstechnik im Machine Learning, mit der Fehler in Vorhersagemodellen minimiert werden. Anders als beim klassischen Gradient Descent, der den Gradienten über den gesamten Datensatz berechnet und damit die Modellparameter aktualisiert, passt SGD die Parameter jeweils anhand eines einzelnen Datenpunkts an. Das macht SGD bei großen Datensätzen schneller und effizienter, allerdings auch rauschbehafteter und weniger stabil. SGD hilft, optimale Parameterwerte zu finden, sodass Vorhersagen genauer werden.
Was bedeutet Optimierung im Machine Learning?
Zuerst eine wichtige Klarstellung: Stochastic Gradient Descent (SGD) ist kein eigener Machine-Learning-Algorithmus. Es ist eine Optimierungstechnik, die auf ML-Algorithmen angewendet werden kann.
Was heißt Optimierung? Gehen wir dazu vom Problemstatement im Machine Learning aus.
Angenommen, wir wollen Diamantpreise anhand des Karatwerts vorhersagen (ein Karat sind 0,2 Gramm). Das ist ein Regressionsproblem, weil das Modell Zahlenwerte ausgibt.
Zur Lösung stehen uns viele Algorithmen zur Verfügung, aber wir wählen Einfache Lineare Regression mit der Formel f(x) = mx + b, wobei:
bder Basispreis des Diamanten istmdie Preissteigerung pro Karat istxder Karatwert des Diamanten istf(x)der vorhergesagte Preis des Diamanten ist
Diese lineare Gleichung ist unser Modell. Unser Ziel ist es, die besten Werte für m und b zu finden, damit die Vorhersagen über alle Diamanten im Datensatz möglichst präzise sind.
Hätten wir ein weiteres Merkmal im Datensatz, zum Beispiel das Volumen des Diamanten, würde sich unsere Formel zu f(x1, x2) = m1*x1 + m2*x2 + b ändern, wobei:
bder Basispreis des Diamanten istm1die Preissteigerung pro Karat istm2die Preissteigerung pro Volumeneinheit istx1der Karatwert des Diamanten istx2das Volumen des Diamanten istf(x)der vorhergesagte Preis des Diamanten ist
Nun müssten wir die optimalen Werte für m1, m2 und b finden.
Im Allgemeinen haben alle Machine-Learning-Modelle Gleichungen wie oben mit einem oder mehreren Parametern. Die Definition von Optimierung lautet hier also: „Gegeben ein Modell und ein Datensatz, finde die optimalen Parameterwerte in der Gleichung.“
Es gibt viele Optimierungsalgorithmen für diese Aufgabe, etwa Stochastic Gradient Descent — darauf konzentriert sich dieses Tutorial. Um SGD voll zu verstehen, schauen wir uns zuerst die Grundideen dahinter an.
Das Fehlerkonzept im Machine Learning
Um SGD zu verstehen, sollten wir zunächst den klassischen Gradient-Descent-Algorithmus (GD) betrachten, der viele Grundideen mit der stochastischen Variante teilt. Einfacher Gradient Descent beginnt mit dem Konzept des Fehlers im Machine Learning.
Was ist Fehler oder Loss?
ML-Algorithmen raten in der Regel die richtige Antwort auf ein Problem. Diese Antwort nennen wir Vorhersage, und sie ist nicht immer korrekt. Daher führen wir die Begriffe „Fehler“ oder „Loss“ ein, die die Differenz zwischen dem tatsächlichen Wert und der Modellvorhersage beschreiben. Unser Ziel ist ein Modell, das diesen Fehler minimiert.
Wenn unser Modell f(x) 10.000 $ für einen Diamanten schätzt, der tatsächlich 12.000 $ kostet, beträgt der Fehler 2.000 $. Wir sollten unser Modell so anpassen, dass dieser Fehler kleiner wird. Die Vorhersagen müssen aber für alle Diamanten gut sein, nicht nur für einen. Wir brauchen also eine Möglichkeit, alle Fehler im Datensatz zusammenzufassen. Hier kommen Kostenfunktionen ins Spiel.
Eine Kostenfunktion fasst alle Einzelfehler zu einer Zahl zusammen, die die Gesamtleistung des Modells repräsentiert. Je geringer diese Gesamtkosten, desto besser die Vorhersagen.
Kostenfunktionen im Machine Learning
Kostenfunktionen variieren je nach Problemtyp.
Bei Regressionsproblemen sagt das Modell Zahlenwerte vorher, etwa den Preis eines Diamanten oder die Zeit für eine Schwimmbahn. Bei der Klassifikation ordnet das Modell einer Kategorie zu: Ist ein Pilz essbar oder nicht? Ist das Objekt im Bild eine Katze, ein Hund oder ein Pferd?
Es gibt weitere Problemtypen, doch entscheidend ist: Jeder benötigt andere Kostenfunktionen. In diesem Tutorial konzentrieren wir uns auf die Mittlere Quadratische Abweichung (Mean Squared Error, MSE), die oft in der Regression verwendet wird.
Die Differenz zwischen den echten Werten (Ground Truth) und den Modellvorhersagen nennt man Fehler oder Loss. Eine Funktion, die all diese Fehler zusammenfasst, heißt entsprechend Fehlerfunktion, Loss-Funktion oder Kostenfunktion. Unterschiedliche Quellen nutzen die Begriffe teils synonym; in diesem Tutorial verwenden wir ab jetzt den Begriff Loss-Funktion.
Mean Squared Error
Bei Regressionsproblemen sieht man häufig folgende Grafik, die echte Werte (Ground Truth) gegen Modellvorhersagen aufträgt.

Je näher die Punkte an der Geraden liegen, desto besser sind die Vorhersagen. Daher versuchen die meisten Regressionsalgorithmen, den durchschnittlichen Abstand der Punkte zur idealen Linie zu minimieren. Wie erwähnt, geschieht diese Minimierung über eine Kostenfunktion wie die Mean Squared Error (MSE).
MSE nimmt echte und vorhergesagte Werte als Eingabe und liefert die quadrierte durchschnittliche Distanz zur perfekten Linie.

Warum quadrieren statt den Betrag zu nehmen? Erstens ist die Ableitung einer Quadratfunktion sehr einfach zu bestimmen. Zweitens betont das Quadrieren große Fehler stärker und bestraft damit die schlechtesten Vorhersagen stärker.
Deshalb wird MSE oft gegenüber Alternativen wie der Mean Absolute Error (MAE) bevorzugt, die zwar einfacher wirkt, aber sich schwerer ableiten lässt.
Der Gradient
Das nächste Puzzleteil bei Gradient Descent ist der Gradient selbst. Kehren wir zur „den Hügel hinunter“-Analogie zurück.
Gradient als steilster Pfad
Wir stehen mit verbundenen Augen auf einem Hügel und wollen so schnell wie möglich ins Tal. Wenn wir Wasser zu unseren Füßen ausgießen, in welche Richtung fließt es? Den Hang hinab, entlang der steilsten Abwärtsrichtung.
Genau das zeigt der Gradient an – allerdings in die Gegenrichtung. Der Gradient zeigt bergauf, also in die Richtung des steilsten Anstiegs. Wollen wir den Fehler minimieren, gehen wir einfach in die entgegengesetzte Richtung des Gradienten, um am schnellsten nach unten zu gelangen.
Mathematisch sagt der Gradient, wie sich die Ausgabe einer Funktion ändert, wenn wir ihre Eingaben ändern. Konkret zeigt er in die Richtung, in der die Funktion am schnellsten zunimmt.
Im ML-Kontext, in dem wir den Fehler über eine Loss-Funktion minimieren wollen, dient uns der Gradient als Wegweiser, um den Fehler am schnellsten zu senken.
Der Gradient ist ein Vektor — je einer für jeden Eingabeparameter der Funktion. Jede Zahl im Vektor gibt an, wie stark sich der Funktionswert ändert, wenn wir den entsprechenden Parameter minimal anpassen.
Wie man den Gradienten einer Funktion findet
Wie findet man also den Gradienten einer Funktion?
Bei Funktionen mit nur einer Variablen wie f(x) = x ** 2 ist der Gradient die Ableitung der Funktion, als Vektor mit einem Element: [2x].
Bei mehrvariablen Funktionen wie f(x1, x2) = x1 ** 3 - x2 ** 2 enthält der Gradient die partiellen Ableitungen der Funktion nach jeder Eingabe. Für die zweite Funktion ist der Gradientenvektor also [3x1 ** 2, 2*x2].
Zurück zur MSE mit folgender Formel:
MSE = (1/n) * Σ(y - f(x))², wobei:
f(x)mx + bistmund b die Variablen der Funktion sindxder Karatwert der Diamanten istndie Anzahl der Datenpunkte istyder tatsächliche Preis der Diamanten ist
Ihr Gradient sind also die partiellen Ableitungen der MSE nach m und b:
∂/∂m (MSE) = (-2/n) * Σ(x * (y - (mx + b)))
∂/∂b (MSE) = (-2/n) * Σ(y - (mx + b))
The gradient = [∂/∂m (MSE), ∂/∂b (MSE)]
Mach dir über die Formeln nicht zu viele Gedanken. Wichtig ist: Sie sagen uns, wie sich die mittlere quadratische Abweichung ändert, wenn wir m oder b minimal verändern.
Gradient Descent: In Schritten zur Lösung
Learning Rate: die Schrittweite steuern
Jetzt haben wir alles, um Gradient Descent auszuführen – sprich, so effizient wie möglich ins Tal zu kommen. Springen wir in diese Richtung oder machen wir kleine Schritte? Das legt doch der Gradient fest, oder? Seine Größe bestimmt, wie weit wir pro Schritt gehen.
Aber was, wenn der Gradient so groß ist, dass wir statt im Tal auf dem nächsten Hügel landen – in nur einem Schritt? Überraschenderweise passiert das oft. Deshalb führen wir einen Parameter ein, die Schrittweite, die die Wirkung des Gradienten steuert.
Vor jedem Schritt multiplizieren wir den Gradienten einfach mit der Schrittweite, um seine Größe zu verringern. Sagt der Gradient zum Beispiel „3,56 bergab“, macht eine Schrittweite von 0,1 daraus 0,356.
So brauchen wir zwar länger bis zum Tal, laufen aber nicht mehr Gefahr, daran vorbeizuschießen.
Die Schrittweite heißt im Machine Learning üblicherweise Learning Rate und liegt typischerweise zwischen 0,001 und 0,3.
Schauen wir uns die mathematische Version an.
Mathematisch kleine Schritte gehen
Zuerst geben wir den Parametern m und b Zufallswerte:
m = 0.215 # Generated randomly
b = 0.059
Damit berechnen wir die initiale MSE über den gesamten Datensatz:
MSE = (1/n) * Σ(y - (0.215 * x + 0.059))² = ...
Um diesen Fehler zu senken, machen wir nun einen kleinen Schritt entgegen der Gradientenrichtung, sprich: Wir aktualisieren m und b mithilfe des Gradienten und der Learning Rate:
m_new = 0.215 - alpha * (∂/∂m (MSE))
b_new = 0.059 - alpha * (∂/∂b (MSE))
Meist wird alpha bzw. α (griechischer Buchstabe) für die Learning Rate verwendet.
Mit den neuen Werten für m und b berechnen wir die MSE erneut:
MSE_new = (1/n) * Σ(y - (m_new * x + b_new))²
Dann berechnen wir wieder den Gradienten und machen so weiter, bis eine Abbruchbedingung erfüllt ist.
Sieh dir in diesem Artikel zu Gradient Descent visuell an, wie die Learning Rate das Training beeinflusst.
Wann hören wir auf?
Mit verbundenen Augen sehen wir nicht, wann wir unten angekommen sind – vor allem bei kleinen Schritten.
Wir brauchen also Stoppkriterien. Typisch sind:
- Eine vorher festgelegte Schrittanzahl (Maximalzahl an Iterationen)
- Die MSE-Änderung pro Schritt wird sehr klein (unterhalb eines Schwellwerts)
- Der Gradient nähert sich stark der Null (wir sind am oder nahe am Talboden)
- Die MSE steigt statt zu fallen
Diese Regeln legst du als ML Engineer fest. Python-Implementierungen bieten dafür meist Parameter – mehr dazu später.
Vorteile und Herausforderungen von Gradient Descent
Vorteile:
- Einfach und intuitiv
- Funktioniert für viele Problemklassen gut
- Rechnerisch effizient bei vielen Parametern
Herausforderungen:
- Kann bei sehr großen Datensätzen langsam sein
- Kann bei nicht-konvexen Problemen in lokalen Minima steckenbleiben
- Die richtige Learning Rate zu wählen ist nicht trivial
Im nächsten Abschnitt siehst du, wie Stochastic Gradient Descent vor allem bei großen Datensätzen einige dieser Punkte adressiert.
Stochastic Gradient Descent
Wenn du Gradient Descent verstanden hast, ist SGD leicht nachzuvollziehen.
Das Problem des klassischen Gradient Descent
So elegant Gradient Descent ist, bei großen Datensätzen hat es einen Nachteil. Erinnere dich: In jedem Schritt berechnen wir den Gradienten über alle Datenpunkte im Datensatz:
∂/∂m (MSE) = (-2/n) * Σ(x * (y - (mx + b)))
∂/∂b (MSE) = (-2/n) * Σ(y - (mx + b))
Hier sind x und y Arrays mit allen Karatwerten bzw. echten Preisen. Das heißt, in jedem Schritt fließen alle Diamanten in die Parameteraktualisierung ein.
Das wird bei Millionen Datenpunkten teuer und langsam. In Zeiten von Big Data ist klassischer Gradient Descent oft unpraktisch für reale ML-Probleme.
Der stochastische Ansatz: Zufall ins Spiel bringen
„Stochastisch“ bedeutet „zufallsbestimmt“ – genau das macht SGD: Es bringt Zufall in den Optimierungsprozess.
Statt alle Datenpunkte für den Gradienten zu verwenden, wählt SGD in jedem Schritt zufällig einen einzelnen Punkt. Auf Basis dieses einen Punkts wird der Gradienten-Schätzer berechnet und die Parameter werden aktualisiert.
Weil SGD jeweils nur einen Datenpunkt betrachtet, erfolgen Aktualisierungen häufiger. So kann die Fehlerfläche (der „Hügel“) schneller durchschritten werden – besonders bei großen Datensätzen.
Diese Geschwindigkeit hat ihren Preis: Da der Gradienten-Schätzer nur auf einem Punkt basiert, ist er deutlich rauschiger. Unser Weg über die Fehlerfläche ist daher unruhiger und zackiger.
Die Mathematik hinter Stochastic Gradient Descent
Für SGD definieren wir zunächst eine stochastische Kostenfunktion.
Statt die MSE über alle Datenpunkte zu berechnen, betrachten wir den quadrierten Fehler für einen zufällig ausgewählten Punkt:
Cost = (y - f(x))²
Dabei ist y der echte Preis des zufällig gewählten Diamanten und f(x) = mx + b unser vorhergesagter Preis.
Dann berechnen wir den stochastischen Gradienten dieser Kostenfunktion bezüglich unserer Parameter m und b:
∂/∂m (Cost) = -2x(y - (mx + b))
∂/∂b (Cost) = -2(y - (mx + b))
The stochastic gradient = [∂/∂m (Cost), ∂/∂b (Cost)]
Mit diesem stochastischen Gradienten aktualisieren wir unsere Parameter wie beim klassischen Gradient Descent:
m_new = m_old - learning_rate * ∂/∂m (Cost)
b_new = b_old - learning_rate * ∂/∂b (Cost)
Der zentrale Punkt bei SGD: Jeder Schritt basiert auf einem zufällig gewählten Datenpunkt. Die Stoppregeln bleiben dieselben wie bei Gradient Descent.
Varianten von SGD und wann du sie einsetzt
In der Praxis wird „pures“ SGD mit Parameterupdates pro Trainingsbeispiel selten verwendet. Grund: Die Updates haben eine hohe Varianz, wodurch die Loss-Funktion stark schwanken kann und die Konvergenz zum Minimum erschwert wird.
Klassisches Gradient Descent ist stabiler, nutzt aber in jedem Schritt alle Datenpunkte und ist damit für heutige Datensätze oft unpraktisch.
Den Mittelweg zwischen Stabilität und Geschwindigkeit bietet Mini-Batch Gradient Descent, besonders in neuronalen Netzen. Dabei werden statt eines einzelnen Beispiels Batches mit mehreren Beispielen verwendet. Gängige Batchgrößen sind 16, 32, 64 usw.
Batchgröße 1 entspricht SGD. Ist die Batchgröße gleich der Datensatzgröße, ist es klassisches Gradient Descent. Alles dazwischen ist Mini-Batch Gradient Descent.
Hier eine Tabelle mit den Unterschieden und Einsatzempfehlungen:
| Typ | Update-Frequenz | Rechenaufwand | Speicherbedarf | Konvergenzstabilität | Beste Einsatzszenarien |
| Gradient Descent (GD) | Gesamter Datensatz pro Update | Am langsamsten, da kompletter Datensatz genutzt wird | Erfordert gesamten Datensatz im Speicher | Am stabilsten, aber langsam | Kleine Datensätze, bei denen Stabilität Priorität hat |
| Stochastic Gradient Descent (SGD) | Ein Beispiel pro Update | Am schnellsten, verarbeitet ein Beispiel nach dem anderen | Geringer Speicherbedarf | Hohe Varianz, kann schwanken | Große Datensätze mit Bedarf an schnellen Updates |
| Mini-Batch Gradient Descent | Batch mit Beispielen pro Update | Guter Kompromiss, effizienter als GD, langsamer als SGD | Benötigt Speicher für einen Batch | Stabiler als SGD, weniger stabil als GD | Große Datensätze mit Bedarf an Balance aus Stabilität und Effizienz |
Epochen in Gradient-Descent-Algorithmen
Ein wichtiger Begriff in jedem Optimierungsalgorithmus ist die Epoche. Sie bezeichnet einen vollständigen Durchlauf durch den Trainingsdatensatz.
In einer Epoche verarbeitet der Algorithmus jedes Trainingsbeispiel genau einmal. Für jedes Beispiel (oder jeden Mini-Batch) erstellt das Modell Vorhersagen, berechnet die Loss und aktualisiert die Gewichte gemäß dem Gradienten. Eine Epoche markiert also einen Verbesserungszyklus. Nach jeder Epoche kannst du typischerweise sehen, wie sich die Modellleistung verändert hat.
Trainingsläufe umfassen meist mehrere Epochen (mindestens 10 sind empfehlenswert). Die Anzahl der Epochen ist ein Hyperparameter. Häufig wird der Datensatz vor jeder Epoche neu gemischt, damit das Modell nicht die Reihenfolge der Beispiele „lernt“.
In unserer Hügel-Analogie ist eine Epoche eine vollständige Erkundung der Landschaft. Pro Epoche:
- Tastest du den Boden an vielen Stellen ab (verarbeitest Trainingsbeispiele)
- Machst du kleine Schritte bergab, basierend auf der lokalen Steigung (aktualisierst Modellparameter)
Nach jeder kompletten Erkundung startest du vom neuen Standort. Mehrere Epochen geben dem Modell wiederholt die Chance, die Loss-Landschaft zu erkunden und ein gutes Minimum zu finden.
Mehrere Epochen garantieren jedoch kein globales Minimum. Startpunkt und Komplexität der Loss-Landschaft können den Prozess beeinflussen.
SGD in Aktion: Ein Walkthrough-Beispiel
In diesem Abschnitt implementieren wir SGD mit Unterstützung für Batchgrößen (Mini-Batch GD) ausschließlich mit Numpy.
Zuerst importieren wir die benötigten Bibliotheken:
import seaborn as sns
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
np.random.seed(42)
Wir verwenden 10.000 Datenpunkte aus dem Diamonds-Datensatz von Seaborn. Wir nehmen nur das Merkmal carat und die Spalte price als Zielvariable:
# Load the data
dataset_size = 10_000
diamonds = sns.load_dataset('diamonds')
# Extract the target and the feature
xy = diamonds[['carat', 'price']].values
np.random.shuffle(xy) # Shuffle the data
xy = xy[:dataset_size]
xy.shape
(10000, 2)
Jetzt teilen wir die Daten in Trainings- und Testset auf, wobei das Training 80 % umfasst.
# Split the data
np.random.shuffle(xy)
train_size = int(0.8 * dataset_size)
train_xy, test_xy = xy[:train_size], xy[train_size:]
train_xy.shape
(8000, 2)
Dann definieren wir unsere Modellfunktion:
def model(m, x, b):
"""Simple linear model"""
return m * x + b
Wir führen eine einfache lineare Regression mit nur zwei unabhängigen Parametern durch: m und b.
Als Loss-Funktion definieren wir die MSE:
def loss(y_true, y_pred):
"""Mean squared error"""
return np.mean((y_true - y_pred) ** 2)
Nun definieren wir eine Funktion namens stochastic_gradient_descent mit sechs Argumenten:
xundysind Merkmal und Zielvariableepochsgibt an, wie oft wir den Abstieg durchführen (mehr dazu gleich)learning_rateist die Schrittweitebatch_sizesteuert, wie häufig Parameterupdates erfolgenstopping_thresholdlegt fest, um wie viel sich die Loss pro Schritt mindestens verringern soll
def stochastic_gradient_descent(
x, y, epochs=100, learning_rate=0.01, batch_size=32, stopping_threshold=1e-6
):
"""
SGD with support for mini-batches.
"""
Zum Start initialisieren wir die zu optimierenden Parameter zufällig und setzen die Loss auf unendlich:
# Initialize the model parameters randomly
m = np.random.randn()
b = np.random.randn()
n = len(x) # The number of data points
previous_loss = np.inf
Dann starten wir eine for-Schleife über die epochs. Darin mischen wir die Daten neu, um die Berechnungen robuster zu machen:
for i in range(epochs):
# Shuffle the data
indices = np.random.permutation(n)
x = x[indices]
y = y[indices]
Die eigentliche Gradientenberechnung beginnt dann in einer weiteren for-Schleife.
for j in range(0, n, batch_size):
x_batch = x[j:j + batch_size]
y_batch = y[j:j + batch_size]
Wir extrahieren den Batch aus x und y und berechnen die Gradienten:
# Compute the gradients
y_pred = model(m, x_batch, b)
m_gradient = -2 * np.mean(x_batch * (y_batch - y_pred))
b_gradient = -2 * np.mean(y_batch - y_pred)
Wir nutzen die oben definierte model-Funktion, um mit den aktuellen Werten von m und b vorherzusagen. Dann bestimmen wir die partiellen Ableitungen, die den Gradienten bilden – gemäß der oben angegebenen Formel.
Mit den partiellen Ableitungen und der Learning Rate aktualisieren wir die Parameter:
# Update the model parameters
m -= learning_rate * m_gradient
b -= learning_rate * b_gradient
Hier ist der bisherige vollständige Code:
def stochastic_gradient_descent(
x, y, epochs=100, learning_rate=0.01, batch_size=32, stopping_threshold=1e-6
):
"""
SGD with support for mini-batches.
"""
# Initialize the model parameters randomly
m = np.random.randn()
b = np.random.randn()
n = len(x)
previous_loss = np.inf
for i in range(epochs):
# Shuffle the data
indices = np.random.permutation(n)
x = x[indices]
y = y[indices]
for j in range(0, n, batch_size):
x_batch = x[j:j + batch_size]
y_batch = y[j:j + batch_size]
# Compute the gradients
y_pred = model(m, x_batch, b)
m_gradient = -2 * np.mean(x_batch * (y_batch - y_pred))
b_gradient = -2 * np.mean(y_batch - y_pred)
# Update the model parameters
m -= learning_rate * m_gradient
b -= learning_rate * b_gradient
Außerhalb der inneren Schleife berechnen wir die Loss für die Epoche:
# Compute the loss
y_pred = model(m, x, b)
current_loss = loss(y, y_pred)
Ist die Differenz previous_loss - current_loss kleiner als der stopping_threshold, beenden wir den Prozess:
if previous_loss - current_loss < stopping_threshold:
break
previous_loss = current_loss
Andernfalls setzen wir previous_loss auf current_loss. Am Ende geben wir die optimierten Parameter m und b zurück:
return m, b
Den gesamten Code findest du in diesem GitHub-Gist, um den Überblick zu behalten.

Testen wir die gefundenen Parameter, indem wir das Modell auf dem Testset ausführen:
# Find the optimal parameters
m, b = stochastic_gradient_descent(train_xy[:, 0], train_xy[:, 1])
# Make predictions
y_preds = model(m, test_xy[:, 0], b)
# Compute and print the loss
mean_squared_error = loss(test_xy[:, 1], y_preds)
mean_squared_error ** 0.5
1595.3955619759456
Die Quadratwurzel der MSE liegt bei etwa 1.600 $, das heißt, unser Modell liegt im Schnitt um 1.600 $ daneben. Um den Fehler zu verbessern, können wir die Anzahl der Epochen erhöhen oder einen größeren Datensatz verwenden.
SGD in realen Projekten einsetzen
Die obige Implementierung von SGD ist grob und ineffizient. Sie dient nur dazu, die Intuition aus den vorherigen Abschnitten mit einem Coding-Walkthrough zu festigen.
In der Praxis implementierst du SGD fast nie selbst, sondern nutzt vorhandene Implementierungen in gängigen Frameworks.
Scikit-learn bietet zum Beispiel die Estimatoren SGDRegressor und SGDClassifier, um verschiedene ML-Algorithmen zu trainieren, darunter:
- Lineare Regression
- Logistische Regression
- Ridge Regression
- SVMs
mit SGD als Optimierungsalgorithmus.
from sklearn.linear_model import SGDRegressor, SGDClassifier
# SGD for Linear Regression with 1000 epochs
regressor = SGDRegressor(loss='squared_loss', max_iter=1000)
In PyTorch ist er als Klasse SGD im Modul optim verfügbar:
import torch.optim as optim
optimizer = optim.SGD(model.parameters(), lr=0.01)
Wenn du lernen willst, wie man Modelle in PyTorch trainiert und optimiert, schau dir den DataCamp-Kurs Introduction to PyTorch an.
In Keras heißt der Optimierer ebenfalls SGD:
from tensorflow.keras.optimizers import SGD
optimizer = SGD(learning_rate=0.01)
Für Training und Optimierung in TensorFlow empfehle ich DataCamps Kurs „Introduction to TensorFlow“.
Praktische Tipps und Tricks für SGD
Es gibt viele Best Practices und Tipps für den Einsatz von SGD und ähnlichen Algorithmen. Hier einige davon:
1. Daten durchmischen
- Reihenfolge der Trainingsbeispiele vor jeder Epoche zufällig mischen
- Verhindert Zyklen in der Optimierung, sorgt für vielfältige Batches
2. Mini-Batches verwenden
- Balance zwischen purem SGD und Batch Gradient Descent
- Übliche Batchgrößen: 32 bis 256
3. Eingaben normalisieren
- Features auf Mittelwert 0 und Varianz 1 skalieren
- Sichert gleichen Beitrag der Features, schnellere Konvergenz
4. Geeignete Learning Rate wählen
- Klein starten (z. B. 0,1, 0,01, 0,001)
- Abhängig von der Performance anpassen
5. Learning-Rate-Schedules einsetzen
- Learning Rate über die Zeit verringern
- Optionen: Step Decay, Exponential Decay, 1/t-Decay
6. Momentum nutzen
- Momentum-Term zu den Updates hinzufügen
- Beschleunigt SGD und dämpft Oszillationen
7. Adaptive Methoden erwägen
- Adam, RMSprop oder Adagrad ausprobieren
- Passen Learning Rates pro Parameter automatisch an
8. Gradient Clipping anwenden
- Hilfreich bei explodierenden Gradienten (z. B. in RNNs)
- Gradienten-Normen auf Maximalwert begrenzen
9. Validierungsleistung überwachen
- Regelmäßig auf dem Validierungsset prüfen
- Bei Bedarf Early Stopping einsetzen
10. Regularisierung nutzen
- L1/L2-Regularisierung oder Dropout einsetzen
- Verhindert Overfitting, insbesondere bei großen Modellen
Fazit
Heute hast du einen der wichtigsten Optimierungsalgorithmen im Machine Learning kennengelernt: Stochastic Gradient Descent.
Zuerst haben wir Intuition und Grundideen über klassischen Gradient Descent aufgebaut – mit der Hügel-Analogie, bei der wir mit verbundenen Augen den Talboden suchen.
Wir haben gelernt, dass sich SGD und klassisches GD dadurch unterscheiden, wie viele Datenpunkte pro Parameterupdate genutzt werden. Um das Verständnis zu festigen und die Mathematik greifbar zu machen, haben wir SGD in Numpy implementiert.
Beachte, dass SGD nur ein Teil des gesamten ML-Trainingsprozesses ist. Um mehr über seinen Kontext zu erfahren, sieh dir diese Ressourcen an:
Stochastic Gradient Descent: FAQs
Was sind die Hauptunterschiede zwischen Stochastic Gradient Descent (SGD) und Mini-Batch Gradient Descent?
SGD aktualisiert Parameter anhand eines einzelnen Datenpunkts, was zu häufigeren Updates, aber höherer Varianz führt. Mini-Batch Gradient Descent nutzt einen kleinen Batch von Datenpunkten, balanciert Update-Frequenz und Stabilität und ist bei großen Datensätzen oft effizienter.
Wie wählt man die richtige Learning Rate für SGD?
Die passende Learning Rate wählst du über Tests und Tuning. Starte typischerweise klein, etwa bei 0,01 oder 0,001, und passe basierend auf der Modellleistung an. Learning-Rate-Schedules oder adaptive Verfahren wie Adam oder RMSprop helfen ebenfalls, eine geeignete Rate zu finden.
Welche typischen Probleme treten bei SGD auf und wie kann man sie beheben?
Häufige Probleme sind hohe Varianz der Updates und erschwerte Konvergenz. Abhilfe schaffen Mini-Batches, Momentum, Learning-Rate-Schedules sowie Techniken wie Gradient Clipping.
Eignet sich Stochastic Gradient Descent für alle Arten von Machine-Learning-Problemen?
SGD ist vielseitig und für viele Problemtypen einsetzbar, spielt seine Stärken aber vor allem in großskaligen Szenarien aus. Für Aufgaben, die sehr hohe Präzision erfordern, ist es aufgrund der rauschigen Updates nicht immer ideal.
Welche beliebten Bibliotheken oder Frameworks implementieren SGD für Machine Learning in Python?
Beliebte Bibliotheken sind Scikit-learn (SGDRegressor, SGDClassifier), TensorFlow (SGD Optimizer) und PyTorch (optim.SGD). Sie bieten effiziente und leicht nutzbare Implementierungen von SGD.
Ich bin Content-Creator im Bereich Data Science mit über zwei Jahren Erfahrung und zähle zu den größten Stimmen auf Medium. Ich schreibe gern ausführliche Artikel über KI und ML – mit einer Prise Sarkasmus, damit das Ganze nicht zu trocken wird. Bisher habe ich über 130 Artikel veröffentlicht und einen DataCamp-Kurs produziert, ein weiterer ist in Arbeit. Meine Inhalte wurden von über 5 Millionen Menschen gelesen, 20.000 davon folgen mir auf Medium und LinkedIn.
