Frühes Stoppen des Stochastic Gradient Descent

Machine LearningMachine LearningBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Der stochastische Gradientenabstieg ist eine beliebte Optimierungsmethode, die zur Minimierung einer Verlustfunktion verwendet wird. Die Methode führt den Gradientenabstieg schrittweise auf stochastische Weise durch, d. h., indem für jede Iteration zufällig Proben ausgewählt werden. Die Methode ist effizient, insbesondere für die Anpassung linearer Modelle. Allerdings wird die Konvergenz bei jeder Iteration nicht gewährleistet, und die Verlustfunktion muss nicht notwendigerweise bei jeder Iteration abnehmen. In diesem Fall kann es schwierig sein, die Konvergenz der Verlustfunktion zu überwachen. In diesem Lab werden wir die Early-Stopping-Strategie untersuchen, die ein Ansatz zur Überwachung der Konvergenz auf einer Validierungsscore ist. Wir werden das SGDClassifier-Modell aus der scikit-learn-Bibliothek und den MNIST-Datensatz verwenden, um zu veranschaulichen, wie Early Stopping verwendet werden kann, um fast die gleiche Genauigkeit wie ein ohne Early Stopping gebautes Modell zu erzielen und die Trainingszeit erheblich zu reduzieren.

VM-Tipps

Nachdem der VM-Start abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.

Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/model_selection("Model Selection") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/utils("Utilities") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/exceptions("Exceptions and Warnings") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/model_selection -.-> lab-49287{{"Frühes Stoppen des Stochastic Gradient Descent"}} sklearn/utils -.-> lab-49287{{"Frühes Stoppen des Stochastic Gradient Descent"}} sklearn/datasets -.-> lab-49287{{"Frühes Stoppen des Stochastic Gradient Descent"}} sklearn/exceptions -.-> lab-49287{{"Frühes Stoppen des Stochastic Gradient Descent"}} ml/sklearn -.-> lab-49287{{"Frühes Stoppen des Stochastic Gradient Descent"}} end

Lade die erforderlichen Bibliotheken und den MNIST-Datensatz

Der erste Schritt besteht darin, die erforderlichen Bibliotheken und den Datensatz zu laden. Wir werden die Bibliotheken pandas, numpy, matplotlib und scikit-learn verwenden. Wir werden auch die fetch_openml-Funktion aus scikit-learn verwenden, um den MNIST-Datensatz zu laden.

import time
import sys
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.utils._testing import ignore_warnings
from sklearn.exceptions import ConvergenceWarning
from sklearn.utils import shuffle

## Lade den MNIST-Datensatz
def load_mnist(n_samples=None, class_0="0", class_1="8"):
    """Lade MNIST, wähle zwei Klassen, mische und gib nur n_samples zurück."""
    ## Lade Daten von http://openml.org/d/554
    mnist = fetch_openml("mnist_784", version=1, as_frame=False, parser="pandas")

    ## Nimm nur zwei Klassen für die binäre Klassifizierung
    mask = np.logical_or(mnist.target == class_0, mnist.target == class_1)

    X, y = shuffle(mnist.data[mask], mnist.target[mask], random_state=42)
    if n_samples is not None:
        X, y = X[:n_samples], y[:n_samples]
    return X, y

X, y = load_mnist(n_samples=10000)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

Definiere den Schätzer und die Early-Stopping-Strategie

Der nächste Schritt besteht darin, den Schätzer und die Early-Stopping-Strategie zu definieren. Wir werden das SGDClassifier-Modell aus scikit-learn verwenden. Wir werden drei verschiedene Stoppkriterien definieren: Kein Stoppkriterium, Trainingsverlust und Validierungsscore. Wir werden die fit_and_score-Funktion verwenden, um den Schätzer auf dem Trainingssatz anzupassen und ihn auf beiden Sätzen zu bewerten.

@ignore_warnings(category=ConvergenceWarning)
def fit_and_score(estimator, max_iter, X_train, X_test, y_train, y_test):
    """Passe den Schätzer auf dem Trainingssatz an und bewerte ihn auf beiden Sätzen"""
    estimator.set_params(max_iter=max_iter)
    estimator.set_params(random_state=0)

    start = time.time()
    estimator.fit(X_train, y_train)

    fit_time = time.time() - start
    n_iter = estimator.n_iter_
    train_score = estimator.score(X_train, y_train)
    test_score = estimator.score(X_test, y_test)

    return fit_time, n_iter, train_score, test_score

## Definiere den Schätzer zum Vergleich
estimator_dict = {
    "Kein Stoppkriterium": linear_model.SGDClassifier(n_iter_no_change=3),
    "Trainingsverlust": linear_model.SGDClassifier(
        early_stopping=False, n_iter_no_change=3, tol=0.1
    ),
    "Validierungsscore": linear_model.SGDClassifier(
        early_stopping=True, n_iter_no_change=3, tol=0.0001, validation_fraction=0.2
    ),
}

Trainiere und bewerte den Schätzer

Der nächste Schritt besteht darin, den Schätzer unter Verwendung jedes Stoppkriteriums zu trainieren und zu bewerten. Wir werden eine Schleife verwenden, um über jeden Schätzer und jedes Stoppkriterium zu iterieren, und wir werden eine weitere Schleife verwenden, um über verschiedene maximale Iterationen zu iterieren. Anschließend werden wir die Ergebnisse in einem pandas-DataFrame speichern, um eine einfache Visualisierung zu ermöglichen.

results = []
for estimator_name, estimator in estimator_dict.items():
    print(estimator_name + ": ", end="")
    for max_iter in range(1, 50):
        print(".", end="")
        sys.stdout.flush()

        fit_time, n_iter, train_score, test_score = fit_and_score(
            estimator, max_iter, X_train, X_test, y_train, y_test
        )

        results.append(
            (estimator_name, max_iter, fit_time, n_iter, train_score, test_score)
        )
    print("")

## Transformiere die Ergebnisse in einen pandas-DataFrame für eine einfache Visualisierung
columns = [
    "Stoppkriterium",
    "max_iter",
    "Fit-Zeit (sec)",
    "n_iter_",
    "Trainingsscore",
    "Testscore",
]
results_df = pd.DataFrame(results, columns=columns)

Zeichne die Ergebnisse

Der letzte Schritt besteht darin, die Ergebnisse zu zeichnen. Wir werden zwei Teilplots verwenden, um die Trainings- und Testscores sowie die Anzahl der Iterationen und die Fit-Zeit zu zeichnen. Wir werden verschiedene Linienstile für jeden Schätzer und jedes Stoppkriterium verwenden.

## Definiere, was geplottet werden soll
lines = "Stoppkriterium"
x_axis = "max_iter"
styles = ["-.", "--", "-"]

## Erster Plot: Trainings- und Testscores
fig, axes = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(12, 4))
for ax, y_axis in zip(axes, ["Trainingsscore", "Testscore"]):
    for style, (criterion, group_df) in zip(styles, results_df.groupby(lines)):
        group_df.plot(x=x_axis, y=y_axis, label=criterion, ax=ax, style=style)
    ax.set_title(y_axis)
    ax.legend(title=lines)
fig.tight_layout()

## Zweiter Plot: n_iter und Fit-Zeit
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 4))
for ax, y_axis in zip(axes, ["n_iter_", "Fit-Zeit (sec)"]):
    for style, (criterion, group_df) in zip(styles, results_df.groupby(lines)):
        group_df.plot(x=x_axis, y=y_axis, label=criterion, ax=ax, style=style)
    ax.set_title(y_axis)
    ax.legend(title=lines)
fig.tight_layout()

plt.show()

Zusammenfassung

In diesem Lab haben wir die Early-Stopping-Strategie untersucht, um die Konvergenz bei der Verwendung des Stochastic Gradient Descent zur Minimierung einer Verlustfunktion anhand eines Validierungsscores zu überwachen. Wir haben das SGDClassifier-Modell aus scikit-learn und den MNIST-Datensatz verwendet, um zu veranschaulichen, wie Early Stopping verwendet werden kann, um fast die gleiche Genauigkeit wie ein Modell ohne Early Stopping zu erreichen und die Trainingszeit erheblich zu reduzieren. Wir haben drei verschiedene Stoppkriterien definiert: Kein Stoppkriterium, Trainingsverlust und Validierungsscore, und eine Schleife verwendet, um den Schätzer unter Verwendung jedes Stoppkriteriums zu trainieren und zu bewerten. Anschließend haben wir die Ergebnisse mit unterschiedlichen Linienstilen für jeden Schätzer und jedes Stoppkriterium geplottet.