Classification de chiffres à l'aide de caractéristiques RBM

Beginner

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

Introduction

Ce laboratoire se concentre sur l'utilisation de la Machine de Boltzmann Restreinte de Bernoulli (RBM) pour la classification de chiffres manuscrits. L'extrait de caractéristiques RBM est combiné avec un classifieur de régression logistique pour prédire les chiffres. L'ensemble de données utilisé est une donnée d'image en niveaux de gris où les valeurs des pixels peuvent être interprétées comme des degrés de noirceur sur un fond blanc.

Conseils sur la VM

Une fois le démarrage de la VM terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter pour pratiquer.

Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter.

Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous résoudrons rapidement le problème pour vous.

Préparation des données

Dans cette étape, nous préparons les données pour l'entraînement et les tests. Nous utilisons la fonction load_digits de sklearn.datasets pour obtenir l'ensemble de données. Nous générons ensuite artificiellement plus de données étiquetées en perturbant les données d'entraînement avec des décalages linéaires de 1 pixel dans chaque direction. Nous échellons les données entre 0 et 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):
    """
    Cette fonction produit un ensemble de données 5 fois plus grand que l'original,
    en déplaçant les images 8x8 de X d'un pixel vers la gauche, la droite, le bas ou le haut
    """
    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))  ## Mise à l'échelle de 0 à 1

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

Définition du modèle

Dans cette étape, nous définissons le pipeline de classification avec un extracteur de caractéristiques BernoulliRBM et un classifieur de régression logistique. Nous utilisons les classes BernoulliRBM et LogisticRegression respectivement des modules sklearn.neural_network et sklearn.linear_model. Nous créons ensuite un objet de pipeline rbm_features_classifier pour combiner les deux modèles.

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)])

Entraînement

Dans cette étape, nous entraînons le modèle de pipeline défini dans l'étape précédente. Nous définissons les hyperparamètres du modèle (taux d'apprentissage, taille de la couche cachée, régularisation), puis ajustons les données d'entraînement au modèle.

from sklearn.base import clone

## Hyper-paramètres. Ces paramètres ont été définis par validation croisée,
## en utilisant GridSearchCV. Ici, nous ne réalisons pas de validation croisée pour
## gagner du temps.
rbm.learning_rate = 0.06
rbm.n_iter = 10

## Plus de composants tendent à donner une meilleure performance de prédiction, mais une
## durée d'ajustement plus longue
rbm.n_components = 100
logistic.C = 6000

## Entraînement du pipeline RBM-Logistique
rbm_features_classifier.fit(X_train, Y_train)

Evaluation

Dans cette étape, nous évaluons les performances du modèle sur l'ensemble de données de test. Nous utilisons la fonction classification_report du module sklearn.metrics pour générer le rapport de classification pour le modèle de pipeline et le modèle de régression logistique.

from sklearn import metrics

Y_pred = rbm_features_classifier.predict(X_test)
print(
    "Régression logistique utilisant les caractéristiques RBM :\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

## Entraînement du classifieur de régression logistique directement sur les pixels
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(
    "Régression logistique utilisant les caractéristiques de pixel brute :\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

Traçage

Dans cette étape, nous traçons les 100 composants extraits par la RBM. Nous utilisons le module matplotlib.pyplot pour tracer les images.

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 composants extraits par RBM", fontsize=16)
plt.subplots_adjust(0.08, 0.02, 0.92, 0.85, 0.08, 0.23)

plt.show()

Sommaire

Dans ce laboratoire, nous avons appris à utiliser la Machine de Boltzmann Restreinte Bernoulli (RBM) avec une régression logistique pour la classification de chiffres manuscrits. Nous avons également appris à évaluer les performances du modèle à l'aide d'un rapport de classification et à tracer les composants extraits par la RBM.