Standardgradientenabstieg berechnet den Gradienten für den gesamten Trainingsdatensatz.
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
Für eine vordefinierte Anzahl von Epochen berechnen wir zunächst den Gradientenvektor Weight_Grad der Verlustfunktion für den gesamten Datensatz mit unseren Parametervektorparametern.
Im Gegensatz dazu führt der stochastische Gradientenabstieg eine Parameteraktualisierung für jedes Trainingsbeispiel x (i) und Etikett y (i) durch.
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
SGD soll viel schneller sein. Ich verstehe jedoch nicht, wie viel schneller es sein kann, wenn wir immer noch eine Schleife über alle Datenpunkte haben. Ist die Berechnung des Gradienten in GD viel langsamer als die Berechnung von GD für jeden Datenpunkt einzeln?
Code kommt von hier .
Antworten:
Kurze Antwort:
Lange Antwort:
Meine Notation folgt Andrew NGs Coursera-Kurs zum maschinellen Lernen. Wenn Sie damit nicht vertraut sind, können Sie die Vorlesungsreihe hier nachlesen .
Nehmen wir an, die Regression auf den Quadratverlust ist die Kostenfunktion
und der gradient ist
Für Gradient Decent (GD) aktualisieren wir den Parameter um
Für den stochastischen Gradienten anständig werden die Summe und die Konstante entfernt, aber der Gradient für den aktuellen Datenpunkt , wo Zeit gespart wird.1 / m x( i ), y( i )
Deshalb sparen wir Zeit:
Angenommen, wir haben 1 Milliarde Datenpunkte.
Um in GD die Parameter einmal zu aktualisieren, müssen wir den (genauen) Gradienten haben. Dies erfordert die Summe dieser 1 Milliarde Datenpunkte, um 1 Aktualisierung durchzuführen.
In SGD können wir uns vorstellen, dass wir versuchen, einen approximierten Gradienten anstelle eines exakten Gradienten zu erhalten . Die Annäherung kommt von einem Datenpunkt (oder mehreren Datenpunkten, die als Minibatch bezeichnet werden). Daher können wir in SGD die Parameter sehr schnell aktualisieren. Wenn wir alle Daten "durchlaufen" (eine Epoche genannt), haben wir tatsächlich 1 Milliarde Aktualisierungen.
Der Trick ist, dass Sie in SGD nicht 1 Milliarde Iterationen / Aktualisierungen benötigen, sondern viel weniger Iterationen / Aktualisierungen, z.
Ich schreibe einen Code, um die Idee zu demonstrieren. Wir lösen das lineare System zuerst durch eine normale Gleichung und lösen es dann mit SGD. Dann vergleichen wir die Ergebnisse in Bezug auf Parameterwerte und endgültige Zielfunktionswerte. Um es später zu visualisieren, müssen wir 2 Parameter einstellen.
Die Ergebnisse:
Beachten Sie, dass die Verlustwerte und sehr nahe liegen , obwohl die Parameter nicht zu nahe liegen.124.1343 123.0355
Hier sind die Kostenfunktionswerte über Iterationen. Wir können sehen, dass sie den Verlust effektiv verringern können, was die Idee veranschaulicht: Wir können eine Teilmenge von Daten verwenden, um den Gradienten zu approximieren und "gut genug" -Ergebnisse zu erhalten.
Lassen Sie uns nun den Rechenaufwand zwischen zwei Ansätzen überprüfen. In dem Experiment haben wir Datenpunkte, die mit Hilfe von SD den Gradienten auswerten, sobald die Daten über diesen summiert werden müssen. ABER in SGD summiert die Funktion nur 1 Datenpunkt, und insgesamt sehen wir, dass der Algorithmus weniger als Iterationen konvergiert (Anmerkung, nicht Iterationen). Dies ist die Rechenersparnis.300 10001000 300 1000
sq_loss_gr_approx
quelle