Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow. Aurélien Géron
Sie sehr lange um das Minimum herum und erhalten eine suboptimale Lösung, wenn Sie das Trainieren zu früh anhalten.
Abbildung 4-9: Mit dem stochastischen Gradientenverfahren ist jeder Trainingsschritt viel schneller, aber auch viel zufälliger als beim Einsatz des Batch-Gradientenverfahren.
Im folgenden Codebeispiel ist das stochastische Gradientenverfahren mit einem einfachen Learning Schedule implementiert:
n_epochs = 50
t0, t1 = 5, 50 # Hyperparameter für den Learning Schedule
def learning_schedule(t):
return t0 / (t + t1)
theta = np.random.randn(2,1) # zufällige Initialisierung
for epoch in range(n_epochs):
for i in range(m):
random_index = np.random.randint(m)
xi = X_b[random_index:random_index+1]
yi = y[random_index:random_index+1]
gradients =2*xi.T.dot(xi.dot(theta) -yi)
eta = learning_schedule(epoch * m + i)
theta = theta - eta * gradients
Standardmäßig iterieren wir in Runden mit je m Iterationen; jede Runde nennt man Epoche. Der Code für das Batch-Gradientenverfahren hat den gesamten Trainingsdatensatz 1.000 Mal durchlaufen. Dieser Code durchläuft die Trainingsdaten nur 50 Mal und erzielt eine recht gute Lösung:
>>> theta
array([[4.21076011],
[2.74856079]])
Abbildung 4-10 zeigt die ersten 20 Schritte beim Trainieren (achten Sie darauf, wie unregelmäßig die Schritte sind).
Abbildung 4-10: Die ersten 20 Schritte des stochastischen Gradientenverfahrens
Da die Datenpunkte zufällig ausgewählt werden, werden manche Datenpunkte innerhalb einer Epoche mehrmals selektiert, andere dagegen gar nicht. Wenn Sie sichergehen möchten, dass jeder Datenpunkt in jeder Epoche abgearbeitet wird, können Sie die Trainingsdaten durchmischen (und sicherstellen, dass die Eingabemerkmale und die Labels zusammenbleiben) und dann Eintrag für Eintrag durchgehen. Anschließend mischen Sie die Daten erneut und so weiter. Allerdings konvergiert dieses Verfahren im Allgemeinen langsamer.
|
Beim Einsatz des stochastischen Gradientenverfahren müssen die Trainingsinstanzen unabhängig und gleichverteilt sein (Independent and Identically Distributed, IID), um sicherzustellen, dass die Parameter im Durchschnitt in Richtung des globalen Optimums gedrängt werden. Eine einfache Möglichkeit ist, die Instanzen während des Trainings zu durchmischen (zum Beispiel jede Instanz zufällig auszuwählen oder zu Beginn jeder Epoche den Trainingsdatensatz zu mischen). Vermischen Sie die Instanzen nicht – beispielsweise wenn sie anhand ihres Labels geordnet sind –, wird das stochastische Gradientenverfahren damit beginnen, erst für ein Label zu optimieren, dann für das nächste und so weiter. Dabei wird es aber nicht nahe an das globale Minimum gelangen. |
Um eine lineare Regression mit dem stochastischen Gradientenverfahren in Scikit-Learn durchzuführen, verwenden Sie die Klasse SGDRegressor, die den quadratischen Fehler als Kostenfunktion minimiert. Das folgende Codebeispiel führt 1.000 Epochen aus, oder es läuft, bis der Verlust während einer Epoche um weniger als 0,001 sinkt (max_iter=1000, tol=1e-3). Der Code beginnt mit einer Lernrate von 0,1 (eta0=0.1), verwendet den voreingestellten Learning Schedule (einen anderen als den oben vorgestellten) und keinerlei Regularisierung (penalty=None, Details dazu folgen in Kürze):
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=1000, tol=1e-3, penalty=None, eta0=0.1)
sgd_reg.fit(X, y.ravel())
Die erzielte Lösung liegt erneut nah an der von der Normalengleichung gefundenen:
>>> sgd_reg.intercept_, sgd_reg.coef_
(array([ 4.16782089]), array([ 2.72603052]))
Mini-Batch-Gradientenverfahren
Als letzten Algorithmus unter den Gradientenverfahren sehen wir uns das Mini-Batch- Gradientenverfahren an. Es ist recht einfach nachzuvollziehen, wenn Sie mit dem Batch- und dem stochastischen Gradientenverfahren vertraut sind: Anstatt die Gradienten bei jedem Schritt auf dem gesamten Trainingsdatensatz (wie beim Batch-Gradientenverfahren) oder nur auf einem Datenpunkt (wie beim stochastischen Gradientenverfahren) zu berechnen, berechnet das Mini-Batch-Gradientenverfahren die Gradienten auf kleinen, zufälligen Teilmengen, den Mini-Batches. Der Hauptvorteil des Mini-Batch-Gradientenverfahrens gegenüber dem stochastischen Verfahren ist, dass Sie die Leistung durch für Matrizenoperationen optimierte Hardware steigern können, besonders beim Verwenden von GPUs.
Die Fortschritte des Algorithmus im Parameterraum sind weniger abrupt als beim SGD, besonders bei größeren Mini-Batches. Daher wandert das Mini-Batch-Gradientenverfahren etwas näher um das Minimum herum als das SGD. Andererseits kann es schwieriger sein, lokale Minima zu verlassen (im Fall von Aufgaben, bei denen lokale Minima eine Rolle spielen; lineare Regression gehört nicht dazu). Abbildung 4-11 zeigt die Pfade durch den Parameterraum beim Trainieren mit den drei Algorithmen. Alle erreichen das Minimum, aber das Batch-Gradientenverfahren hält dort auch an, während sich sowohl das stochastische als auch das Mini-Batch-Gradientenverfahren weiter um das Minimum herumbewegen.
Abbildung 4-11: Pfade von Gradientenverfahren im Parameterraum
Allerdings benötigt das Batch-Gradientenverfahren für jeden Schritt eine Menge Zeit, und auch das stochastische und das Mini-Batch-Gradientenverfahren würden mit einem guten Learning Schedule das Minimum erreichen.
Vergleichen wir die bisher besprochenen Algorithmen zur linearen Regression6 (dabei ist m die Anzahl der Trainingsdatenpunkte und n die Anzahl der Merkmale); siehe Tabelle 4-1.
Tabelle 4-1: Vergleich von Algorithmen zur linearen Regression
|
Nach dem Trainieren gibt es kaum noch einen Unterschied: Alle diese Algorithmen führen zu sehr ähnlichen Modellen und treffen Vorhersagen in der gleichen Art und Weise. |
Polynomielle Regression
Wie sieht es aus, wenn Ihre Daten komplexer als eine gerade Linie sind? Überraschenderweise können wir auch nichtlineare Daten mit einem linearen Modell fitten. Dazu können wir einfach Potenzen jedes Merkmals als neue Merkmale hinzufügen und dann ein lineares