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.