Classificação de Dígitos Manuscritos com Recursos RBM

Beginner

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

Introdução

Este laboratório foca no uso da Máquina de Boltzmann Restrita de Bernoulli (RBM) para classificação de dígitos manuscritos. O extrator de características RBM é combinado com um classificador de regressão logística para prever os dígitos. O conjunto de dados utilizado é um conjunto de dados de imagens em escala de cinza, onde os valores dos pixels podem ser interpretados como graus de negrura num fundo branco.

Dicas da Máquina Virtual

Após o arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para praticar.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante a aprendizagem, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Preparação dos Dados

Nesta etapa, preparamos os dados para treino e teste. Usamos a função load_digits de sklearn.datasets para obter o conjunto de dados. Em seguida, geramos artificialmente mais dados rotulados perturbando os dados de treino com deslocamentos lineares de 1 pixel em cada direção. Escalamos os dados entre 0 e 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):
    """
    Isto produz um conjunto de dados 5 vezes maior que o original,
    deslocando as imagens 8x8 em X para a esquerda, direita, baixo, cima por 1px
    """
    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))  ## Escala de 0 a 1

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

Definição do Modelo

Nesta etapa, definimos o pipeline de classificação com um extrator de características BernoulliRBM e um classificador de regressão logística. Usamos as classes BernoulliRBM e LogisticRegression dos módulos sklearn.neural_network e sklearn.linear_model, respetivamente. Em seguida, criamos um objeto de pipeline rbm_features_classifier para combinar os dois modelos.

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

Treino

Nesta etapa, treinamos o modelo de pipeline definido na etapa anterior. Definimos os hiperparâmetros do modelo (taxa de aprendizagem, tamanho da camada oculta, regularização) e, em seguida, ajustamos os dados de treino ao modelo.

from sklearn.base import clone

## Hiperparâmetros. Estes foram definidos por validação cruzada,
## usando um GridSearchCV. Aqui não estamos a realizar validação cruzada para
## poupar tempo.
rbm.learning_rate = 0.06
rbm.n_iter = 10

## Mais componentes tendem a dar um melhor desempenho de previsão, mas com um tempo de ajuste maior.
rbm.n_components = 100
logistic.C = 6000

## Treinamento do Pipeline RBM-Regressão Logística
rbm_features_classifier.fit(X_train, Y_train)

Avaliação

Nesta etapa, avaliamos o desempenho do modelo no conjunto de dados de teste. Usamos a função classification_report do módulo sklearn.metrics para gerar o relatório de classificação tanto para o modelo de pipeline quanto para o modelo de regressão logística.

from sklearn import metrics

Y_pred = rbm_features_classifier.predict(X_test)
print(
    "Regressão logística usando características RBM:\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

## Treinando o classificador de regressão logística diretamente nas 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(
    "Regressão logística usando características de pixel bruto:\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

Plotagem

Nesta etapa, plotamos os 100 componentes extraídos pelo RBM. Usamos o módulo matplotlib.pyplot para plotar as imagens.

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 componentes extraídos pelo RBM", fontsize=16)
plt.subplots_adjust(0.08, 0.02, 0.92, 0.85, 0.08, 0.23)

plt.show()

Resumo

Neste laboratório, aprendemos a utilizar a Máquina de Boltzmann Restrita Bernoulliana (RBM) com regressão logística para classificação de dígitos manuscritos. Também aprendemos a avaliar o desempenho do modelo utilizando o relatório de classificação e como plotar os componentes extraídos pelo RBM.