Zifferklassifizierung mit RBM-Features

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

In diesem Lab geht es um die Verwendung der Bernoulli Restricted Boltzmann Machine (RBM) zur Klassifizierung von handschriftlichen Ziffern. Der RBM-Feature-Extraktor wird mit einem logistischen Regressionsklassifizierer kombiniert, um die Ziffern vorherzusagen. Der verwendete Datensatz ist ein Graustufen-Bild-Datensatz, wobei die Pixelwerte als Schwarzgrad auf einem weißen Hintergrund interpretiert werden können.

Tipps für die VM

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 der 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/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/linear_model("Linear Models") sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/neural_network("Neural Network Models") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/preprocessing("Preprocessing and Normalization") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/pipeline("Pipeline") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/model_selection("Model Selection") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/metrics("Metrics") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/base("Base Classes and Utility Functions") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/linear_model -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/neural_network -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/preprocessing -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/pipeline -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/model_selection -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/metrics -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/base -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} sklearn/datasets -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} ml/sklearn -.-> lab-49259{{"Zifferklassifizierung mit RBM-Features"}} end

Datenvorbereitung

In diesem Schritt bereiten wir die Daten für das Training und die Tests vor. Wir verwenden die Funktion load_digits aus sklearn.datasets, um den Datensatz zu erhalten. Anschließend erzeugen wir künstlich mehr markierte Daten, indem wir die Trainingsdaten um eine lineare Verschiebung von 1 Pixel in jeder Richtung stören. Wir skalieren die Daten zwischen 0 und 1.

import numpy as np
from scipy.ndimage import convolve
from sklearn import datasets
from sklearn.preprocessing import minmax_scale
from sklearn.model_selection import train_test_split

def nudge_dataset(X, Y):
    """
    Dies erzeugt einen Datensatz, der 5-mal größer als der ursprüngliche ist,
    indem die 8x8-Bilder in X um 1 Pixel nach links, rechts, unten, oben verschoben werden
    """
    direction_vectors = [
        [[0, 1, 0], [0, 0, 0], [0, 0, 0]],
        [[0, 0, 0], [1, 0, 0], [0, 0, 0]],
        [[0, 0, 0], [0, 0, 1], [0, 0, 0]],
        [[0, 0, 0], [0, 0, 0], [0, 1, 0]],
    ]

    def shift(x, w):
        return convolve(x.reshape((8, 8)), mode="constant", weights=w).ravel()

    X = np.concatenate(
        [X] + [np.apply_along_axis(shift, 1, X, vector) for vector in direction_vectors]
    )
    Y = np.concatenate([Y for _ in range(5)], axis=0)
    return X, Y

X, y = datasets.load_digits(return_X_y=True)
X = np.asarray(X, "float32")
X, Y = nudge_dataset(X, y)
X = minmax_scale(X, feature_range=(0, 1))  ## 0-1 Skalierung

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)

Modelldefinition

In diesem Schritt definieren wir die Klassifizierungs-Pipeline mit einem BernoulliRBM-Feature-Extraktor und einem logistischen Regressionsklassifizierer. Wir verwenden die Klassen BernoulliRBM und LogisticRegression aus den Modulen sklearn.neural_network und sklearn.linear_model respective. Anschließend erstellen wir ein Pipeline-Objekt rbm_features_classifier, um die beiden Modelle zu kombinieren.

from sklearn import linear_model
from sklearn.neural_network import BernoulliRBM
from sklearn.pipeline import Pipeline

logistic = linear_model.LogisticRegression(solver="newton-cg", tol=1)
rbm = BernoulliRBM(random_state=0, verbose=True)

rbm_features_classifier = Pipeline(steps=[("rbm", rbm), ("logistic", logistic)])

Training

In diesem Schritt trainieren wir das in dem vorherigen Schritt definierte Pipeline-Modell. Wir setzen die Hyperparameter des Modells (Lernrate, Größe der versteckten Schicht, Regularisierung) und passen dann die Trainingsdaten an das Modell an.

from sklearn.base import clone

## Hyperparameter. Diese wurden durch Kreuzvalidierung festgelegt,
## unter Verwendung eines GridSearchCV. Hier führen wir keine Kreuzvalidierung durch,
## um Zeit zu sparen.
rbm.learning_rate = 0.06
rbm.n_iter = 10

## Mehr Komponenten tendieren dazu, eine bessere Vorhersageleistung zu liefern, aber eine längere
## Anpassungszeit
rbm.n_components = 100
logistic.C = 6000

## Training des RBM-Logistic-Pipelines
rbm_features_classifier.fit(X_train, Y_train)

Evaluation

In diesem Schritt evaluieren wir die Leistung des Modells auf dem Testdatensatz. Wir verwenden die Funktion classification_report aus dem Modul sklearn.metrics, um den Klassifikationsbericht sowohl für das Pipeline-Modell als auch für das logistische Regressionsmodell zu generieren.

from sklearn import metrics

Y_pred = rbm_features_classifier.predict(X_test)
print(
    "Logistische Regression mit RBM-Features:\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

## Direktes Training des logistischen Regressionsklassifizierers auf den Pixeln
raw_pixel_classifier = clone(logistic)
raw_pixel_classifier.C = 100.0
raw_pixel_classifier.fit(X_train, Y_train)

Y_pred = raw_pixel_classifier.predict(X_test)
print(
    "Logistische Regression mit rohen Pixel-Features:\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

Plotting

In diesem Schritt plotten wir die 100 Komponenten, die von der RBM extrahiert wurden. Wir verwenden das Modul matplotlib.pyplot, um die Bilder zu plotten.

import matplotlib.pyplot as plt

plt.figure(figsize=(4.2, 4))
for i, comp in enumerate(rbm.components_):
    plt.subplot(10, 10, i + 1)
    plt.imshow(comp.reshape((8, 8)), cmap=plt.cm.gray_r, interpolation="nearest")
    plt.xticks(())
    plt.yticks(())
plt.suptitle("100 Komponenten, die von der RBM extrahiert wurden", fontsize=16)
plt.subplots_adjust(0.08, 0.02, 0.92, 0.85, 0.08, 0.23)

plt.show()

Zusammenfassung

In diesem Lab haben wir gelernt, wie man die Bernoulli Restricted Boltzmann Machine (RBM) mit logistischer Regression für die Klassifizierung von handschriftlichen Ziffern verwendet. Wir haben auch gelernt, wie man die Leistung des Modells mit Hilfe des Klassifikationsberichts计算 und wie man die von der RBM extrahierten Komponenten plotten kann.