Python DeepLearning

MNIST 손글씨 데이터셋을 이용한 숫자 분류 모델 만들기

PyExplorer 2025. 4. 27. 16:26
728x90

MNIST 손글씨 데이터셋을 이용한 숫자 분류 모델 만들기

1. 개요

MNIST는 손으로 쓴 숫자(0~9)를 포함하는 유명한 이미지 데이터셋으로, 딥러닝을 처음 배우는 사람들에게 널리 사용되는 데이터셋입니다. 이 글에서는 TensorFlow와 Keras를 이용해 MNIST 데이터를 학습하고 숫자를 분류하는 신경망 모델을 만들어 보겠습니다.

2. MNIST 데이터셋 소개

MNIST 데이터셋은 28x28 크기의 흑백 이미지로 구성되어 있으며, 총 70,000개의 이미지가 포함됩니다. 이 중 60,000개는 학습 데이터(training set)로, 10,000개는 테스트 데이터(test set)로 사용됩니다.

데이터 로드 및 확인

TensorFlow의 tf.keras.datasets 모듈을 이용하면 간단하게 MNIST 데이터를 불러올 수 있습니다.

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# MNIST 데이터셋 로드
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# 데이터 크기 확인
print(f"학습 데이터: {x_train.shape}, 테스트 데이터: {x_test.shape}")

# 샘플 이미지 출력
plt.figure(figsize=(10,5))
for i in range(10):
    plt.subplot(2, 5, i+1)
    plt.imshow(x_train[i], cmap='gray')
    plt.axis('off')
plt.show()

3. 데이터 전처리

딥러닝 모델을 학습하기 전에 데이터를 적절히 변환하는 과정이 필요합니다.

  1. 정규화(Normalization): 픽셀 값(0255)을 01 범위로 조정합니다.
  2. Reshape: CNN 모델을 사용할 경우 4차원 입력 형태로 변환합니다.
  3. One-hot Encoding: 레이블(0~9)을 신경망에 적합한 형태로 변환합니다.
# 픽셀 값 정규화
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0

# 차원 변경 (CNN 모델을 사용할 경우 필요)
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)

# 레이블을 One-hot Encoding 변환
from tensorflow.keras.utils import to_categorical
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

4. 딥러닝 모델 설계

CNN(합성곱 신경망, Convolutional Neural Network)을 활용하여 숫자 이미지를 분류하는 모델을 구축합니다.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout

# CNN 모델 생성
model = Sequential([
    Conv2D(32, kernel_size=(3,3), activation='relu', input_shape=(28,28,1)),
    MaxPooling2D(pool_size=(2,2)),
    Conv2D(64, kernel_size=(3,3), activation='relu'),
    MaxPooling2D(pool_size=(2,2)),
    Flatten(),
    Dense(128, activation='relu'),
    Dropout(0.5),
    Dense(10, activation='softmax')
])

# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 모델 요약 정보 출력
model.summary()

5. 모델 학습

모델을 학습시키고 정확도를 평가합니다.

# 모델 학습
history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_data=(x_test, y_test))

학습 과정에서 손실(loss)과 정확도(accuracy)가 어떻게 변하는지 시각화할 수도 있습니다.

import matplotlib.pyplot as plt

# 학습 결과 시각화
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

6. 모델 평가 및 테스트

테스트 데이터로 모델의 최종 성능을 확인합니다.

# 모델 평가
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=0)
print(f"테스트 정확도: {test_acc * 100:.2f}%")

7. 새로운 이미지 예측하기

모델이 실제로 숫자를 잘 인식하는지 확인하기 위해 테스트 데이터 중 일부를 예측해 보겠습니다.

import numpy as np

# 테스트 데이터에서 샘플 선택
sample_idx = np.random.choice(len(x_test), 10)
sample_images = x_test[sample_idx]
sample_labels = np.argmax(y_test[sample_idx], axis=1)
predictions = np.argmax(model.predict(sample_images), axis=1)

# 결과 시각화
plt.figure(figsize=(10,5))
for i in range(10):
    plt.subplot(2, 5, i+1)
    plt.imshow(sample_images[i].reshape(28, 28), cmap='gray')
    plt.title(f"실제: {sample_labels[i]}, 예측: {predictions[i]}")
    plt.axis('off')
plt.show()

8. 결론

이번 포스팅에서는 MNIST 손글씨 숫자 데이터셋을 활용하여 딥러닝 모델을 구축하고 학습하는 과정을 살펴보았습니다. CNN을 활용하여 높은 정확도의 분류 모델을 만들 수 있었으며, 학습한 모델을 사용하여 실제 이미지에 대한 예측을 수행할 수 있었습니다.

728x90