RBM 기반 숫자 이미지 분류

Beginner

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

소개

이 실험실은 손글씨 숫자 분류를 위해 베르누이 제한 볼츠만 머신 (RBM) 을 사용하는 데 중점을 둡니다. RBM 특징 추출기는 로지스틱 회귀 분류기와 결합하여 숫자를 예측합니다. 사용되는 데이터는 흑백 배경에서 픽셀 값을 흑색 정도로 해석할 수 있는 회색조 이미지 데이터입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 연습을 위해 Jupyter Notebook에 접근할 수 있는 Notebook 탭으로 전환합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업 검증을 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터 준비

이 단계에서는 훈련 및 테스트 데이터를 준비합니다. sklearn.datasetsload_digits 함수를 사용하여 데이터 세트를 가져옵니다. 그런 다음 각 방향으로 1 픽셀씩 선형 이동을 통해 훈련 데이터를 변형하여 레이블이 지정된 데이터를 인공적으로 5 배 더 생성합니다. 데이터를 0 과 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):
    """
    이 함수는 X 의 8x8 이미지를 좌, 우, 하, 상으로 1 픽셀씩 이동하여 원본 데이터보다 5 배 큰 데이터 세트를 생성합니다.
    """
    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 범위로 스케일링

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

모델 정의

이 단계에서는 베르누이 RBM 특징 추출기와 로지스틱 회귀 분류기를 사용하여 분류 파이프라인을 정의합니다. sklearn.neural_network 모듈의 BernoulliRBM 클래스와 sklearn.linear_model 모듈의 LogisticRegression 클래스를 사용합니다. 그런 다음 두 모델을 결합하기 위해 파이프라인 객체 rbm_features_classifier를 생성합니다.

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

훈련

이 단계에서는 이전 단계에서 정의된 파이프라인 모델을 훈련합니다. 모델의 하이퍼파라미터 (학습률, 은닉층 크기, 정규화) 를 설정하고 훈련 데이터를 모델에 맞춥니다.

from sklearn.base import clone

## 하이퍼파라미터. 이 값들은 교차 검증 (cross-validation) 을 통해 설정되었습니다.
## 여기서는 시간 절약을 위해 교차 검증을 수행하지 않습니다.
rbm.learning_rate = 0.06
rbm.n_iter = 10

## 더 많은 구성 요소는 일반적으로 더 나은 예측 성능을 제공하지만, 훈련 시간이 더 길어집니다.
rbm.n_components = 100
logistic.C = 6000

## RBM-로지스틱 파이프라인 훈련
rbm_features_classifier.fit(X_train, Y_train)

평가

이 단계에서는 테스트 데이터 세트에 대한 모델의 성능을 평가합니다. sklearn.metrics 모듈의 classification_report 함수를 사용하여 파이프라인 모델과 로지스틱 회귀 모델 모두에 대한 분류 보고서를 생성합니다.

from sklearn import metrics

Y_pred = rbm_features_classifier.predict(X_test)
print(
    "RBM 특징을 사용한 로지스틱 회귀:\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

## 픽셀 데이터 자체로 로지스틱 회귀 분류기를 직접 훈련
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(
    "원본 픽셀 특징을 사용한 로지스틱 회귀:\n%s\n"
    % (metrics.classification_report(Y_test, Y_pred))
)

시각화

이 단계에서는 RBM 으로 추출된 100 개의 구성 요소를 시각화합니다. 이미지를 그리기 위해 matplotlib.pyplot 모듈을 사용합니다.

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("RBM 으로 추출된 100 개의 구성 요소", fontsize=16)
plt.subplots_adjust(0.08, 0.02, 0.92, 0.85, 0.08, 0.23)

plt.show()

요약

이 실험에서는 숫자 이미지 분류를 위해 베르누이 제한 볼츠만 머신 (RBM) 과 로지스틱 회귀를 사용하는 방법을 배웠습니다. 또한 분류 보고서를 사용하여 모델의 성능을 평가하고 RBM 으로 추출된 구성 요소를 시각화하는 방법을 학습했습니다.