본문 바로가기
Data Tech/DataScience(데이터과학)

[딥러닝] 1. MNIST 카테고리 분류

by SuperDev 2024. 5. 19.

Tensorflow를 통해 MNIST 데이터셋을 분류할 예정 입니다.

수기로 표현된 다양한 형태의 숫자를 기계학습으로 추청하고 성능을 검토해봅시다.

MNIST 이미지


Tensorflow 라이브러리에서 mnist 데이터셋을 불러옵시다.

이미지 데이터가 픽셀값(0~255)으로 나타나므로, 데이터를 255로 나누어 0~1 사이로 정규화를 하는 것이 좋은데

Gradient Descent와 같은 최적화 알고리즘은 데이터가 정규화 되었을 때 더 빠르게 수렴할 수 있기 때문입니다.

# 데이터셋 준비
import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
X_train, X_test = x_train/255, x_test/255

keras를 활용해 모델의 layer를 구성해봅시다.

현재 데이터셋은 2차원 벡터이므로 Flatten을 사용해 1차원 벡터로 변환하여 입력층을 구성합니다.

그 다음 입력값에 활성화 함수  ReLU를 사용하여 1000개의 뉴런이 발생하는 은닉층을 구성합니다.

출력층은 활성화 함수 SoftMax를 사용하여 10개의 뉴런으로 구성합니다. (결과값이 0~9 중 하나이므로)

 

모델의 최적화 알고리즘은 'adam'을 사용합니다.

loss함수는 'sparse_categorical_crossentropy'를 사용하고 모델 평가를 위해 Accuracy도 설정합니다.

# 모델 생성
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)), # Flatten으로 1차원 벡터로 변환
    tf.keras.layers.Dense(1000, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

모델 훈련 시, 여러가지 파라미터를 설정하게 됩니다.

먼저 훈련 데이터인 X_train, y_train을 입력하고, 검증 데이터(validation_data)는 X_test, y_test를 넣어줍니다.

epochs=10와 batch_size=100으로 조정, 전체 데이터셋를 100개로 나눈 샘플 데이터셋을 사용하여 총 10회 훈련하도록 설정합니다. verbose는 훈련 과정의 출력을 얼마나 상세히 표시할지 지정합니다. (손실값, 정확도 확인 가능)

# 모델 훈련
hist = model.fit(X_train, y_train, validation_data=(X_test, y_test),
                 epochs=10, batch_size=100, verbose=1)

아래 acc & loss 그래프에서 Accuracy는 모두 1에 가깝게 붙어있고, loss는 0에 가깝게 떨어져 있는 것을 볼 수 있습니다.

Last val_Acc : 0.9855   /    Last val_loss : 0.1105

# acc & loss 그래프
import matplotlib.pyplot as plt
%matplotlib inline

plot_target = ['loss', 'val_loss', 'accuracy', 'val_accuracy']
plt.figure(figsize=(12, 8))

for each in plot_target:
    plt.plot(hist.history[each], label=each)

plt.legend(); plt.grid(); plt.show()


어떤 이미지가 예측값과 틀렸는지 확인해봅시다.

모델의 예측값과 실제값을 비교해서 틀린값을 가진 인덱스를 리스트에 저장합니다.

그리고 해당 인덱스의 값을 reshape를 통해 2차원 벡터로 변환하고 이미지를 출력해봅시다.

# 틀린 인덱스 모으기
import numpy as np

predicted_result = model.predict(X_test)

# 배열에서 큰 값을 가진 요소의 인덱스를 반환
predicted_labels = np.argmax(predicted_result, axis=1)

wrong_result = []

for n in range(0, len(y_test)):
    if predicted_labels[n] != y_test[n]:
        wrong_result.append(n)

len(wrong_result)
import random

samples = random.choices(population=wrong_result, k=16)

plt.figure(figsize=(14, 12))
for idx, n in enumerate(samples):
    plt.subplot(4, 4, idx+1)
    plt.imshow(X_test[n].reshape(28, 28), cmap='Greys', interpolation='nearest')
    plt.title('label : ' + str(y_test[n]) + ' predict : ' + str(predicted_labels[n]))
    plt.axis('off')

728x90