본문 바로가기

데이터사이언스/데이터사이언티스트4기

딥러닝 Fashion MNIST

🧵 Fashion MNIST 모델 정리

1. 데이터셋 개요

  • 총 이미지 수: 70,000장
    • 훈련 이미지: 60,000장
    • 테스트 이미지: 10,000장
  • 이미지 크기: 28 x 28 픽셀 (흑백)
  • 클래스 수: 10개

클래스 인덱스 클래스 이름

0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot
  • 각 클래스별 이미지 수: 7,000장 (균등 분포)

2. 데이터 로드 및 전처리

from tensorflow.keras.datasets import fashion_mnist

# 데이터셋 로드: 훈련/테스트 데이터를 한 줄로 분할
(x_train_full, y_train_full), (x_test, y_test) = fashion_mnist.load_data()
  • x_train_full: 훈련용 이미지 데이터 (60,000장, 각 이미지 28x28 픽셀)
  • y_train_full: 훈련용 정답 레이블 (60,000개)
  • x_test: 테스트용 이미지 데이터 (10,000장)
  • y_test: 테스트용 정답 레이블 (10,000개)
# 정규화: 픽셀 값을 0~1 범위로 조정
x_train = x_train_full / 255.0
x_test = x_test / 255.0

# CNN 입력 형태로 reshape
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)

※ 완전연결 신경망(Dense)을 사용할 경우에는 아래와 같이 1D 벡터 형태로 변환:

x_train = x_train.reshape(-1, 28 * 28)
x_val = x_val.reshape(-1, 28 * 28)
x_test = x_test.reshape(-1, 28 * 28)
  • reshape(-1, 28 * 28)은 이미지(28x28)를 1차원 벡터(784)로 바꿈
  • -1은 첫 번째 차원을 자동으로 계산하라는 의미 (예: 60000장 → 자동으로 60000이 들어감)

3. Dense 모델 구성 (L2 정규화 + Dropout + BatchNormalization 포함)

from tensorflow.keras import models, layers, regularizers

model = models.Sequential()
model.add(layers.Input(shape=(784,)))  # 입력층: 784차원 벡터
model.add(layers.Dense(512, kernel_regularizer=regularizers.l2(0.001)))  # L2 정규화 포함
model.add(layers.BatchNormalization())  # 배치 정규화 추가
model.add(layers.Activation('relu'))  # 활성화 함수 분리 적용
model.add(layers.Dropout(0.5))  # 드롭아웃: 과적합 방지
model.add(layers.Dense(10, activation='softmax'))   # 출력층: 10개 노드, softmax 함수
model.summary()  # 모델 구조 요약 출력
  • kernel_regularizer=regularizers.l2(0.001): 가중치 크기를 줄이는 방향으로 학습하여 과적합 방지
  • L2 정규화는 모델의 복잡도를 억제하고 일반화 성능 향상에 도움

4. 최적화된 모델로 예측 결과 시각화 (랜덤 테스트 샘플)

import numpy as np
import matplotlib.pyplot as plt

# class name 매핑 리스트가 있어야 함
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat", 
               "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]

# 테스트 세트에서 무작위로 5장 선택
num_samples = 5
random_idxs = np.random.randint(len(x_test), size=num_samples)

# 예측 수행
pred_ys = model.predict(x_test)
arg_pred_y = np.argmax(pred_ys, axis=1)

plt.figure(figsize=(15, 5))
for i, idx in enumerate(random_idxs):
    image = x_test[idx].reshape(28, 28)
    true_label = class_names[y_test[idx]]
    pred_label = class_names[arg_pred_y[idx]]

    plt.subplot(1, num_samples, i + 1)
    plt.imshow(image, cmap='gray')
    plt.title(f"True: {true_label}\nPred: {pred_label}")
    plt.axis('off')

plt.tight_layout()
plt.show()
  • 무작위로 선택된 테스트 이미지 5장을 예측하고, 정답과 함께 시각화함
  • 잘못 분류된 경우 눈으로 확인 가능하여 모델 성능을 직관적으로 점검할 수 있음

5. 클래스별 분류 성능 지표 출력

from sklearn.metrics import classification_report

# 예측값 (argmax로 다중 클래스 분류 결과 얻기)
pred_ys = model.predict(x_test)
y_pred = np.argmax(pred_ys, axis=1)

# 클래스별 정확도, 정밀도, 재현율, F1-score 출력
print(classification_report(y_test, y_pred, target_names=class_names))
  • classification_report는 다음을 포함한 성능 지표 제공:
    • precision: 정밀도 (예측이 맞을 확률)
    • recall: 재현율 (정답을 잘 찾아낸 비율)
    • f1-score: 정밀도와 재현율의 조화 평균
    • support: 각 클래스의 실제 샘플 수

이 보고서를 통해 어떤 클래스가 특히 어렵게 분류되었는지 확인 가능함


6. 혼동 행렬 (Confusion Matrix) 시각화

from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt

# 혼동 행렬 계산
y_pred = np.argmax(model.predict(x_test), axis=1)
cm = confusion_matrix(y_test, y_pred)

# 시각화
plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
            xticklabels=class_names, yticklabels=class_names)
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.title('Confusion Matrix')
plt.tight_layout()
plt.show()
  • 혼동 행렬은 각 클래스 간의 예측 정확도를 정리해줌
  • 행: 실제 클래스, 열: 예측 클래스
  • 대각선이 선명할수록 정확도가 높은 것, 오분류는 대각선 외부에서 발생함