스터디 포스트 >  실전문제로 배우는 머신러닝

패션 클래스 분류

오혜수 멘토
안녕하세요! 저는 머신러닝에 관심 있는 취준생입니다!

실전문제로 배우는 머신러닝 - 2주차

 
💡
딥러닝을 사용해 이미지 분류하기
 
세계 패션 산업은 3조 달러의 규모로 세계 GDP의 2%를 차지하고 있습니다.
패션 산업은 새로운 컴퓨터 비전과 머신러닝, 딥러닝 기술을 받아들이며 극적인 변화를 겪고 있는데요
 
이번 프로젝트에서는 고객의 인스타그램과 페이스북 이미지를 살펴보고, 고객이 착용한 가방, 드레스, 바지 등의 패션 카테고리를 분류해보겠습니다😎
 
프로젝트 목적
  • 패션 이미지를 보고 그 이미지가 어떤 옷인지 알려주는 모델을 만들기
  • 예) 이미지를 보고 반바지인지 가방인지 모자인지를 인식
 
적용할 수 있는 점
  • 패션 트렌드를 감지하고 예측해 적절한 마케팅 캠페인을 제시 가능
  • 특정 고객만을 타겟으로 한 마케팅 가능
 
데이터
  • 7만개의 패션 MNIST 데이터
  • 학습 데이터 세트 : 6만개, 테스트 데이터 세트 : 1만개
 
프로젝트 진행 방향
  • 흑백 이미지가 어떤 패션 아이템인지 분류
 
 
프로젝트를 진행하기에 앞서, 이미지를 데이터로 어떻게 표현할까요?
notion image
보통 분석을 할 때 흑백 이미지를 사용하는데, 흑백은 0~255 사이의 숫자로 색상을 나타낼 수 있습니다.
만약 검은 선이나 검은 점을 표현하고 싶다면 픽셀 안에 숫자 0을 넣으면 됩니다. 또한, 색상이 흰색임을 나타내고 싶다면 255를 넣으면 되는 식입니다.
따라서 이 위치가 이정도 색상을 가지고 있다면 이건 가방이구나! 이런식으로 학습을 하게 됩니다.
 
그럼 프로젝트를 시작해봅시다!
 
 


 

1️⃣ 라이브러리 불러오기

 
import pandas as pd
import numpy as np  
import matplotlib.pyplot as plt
import seaborn as sns
 

2️⃣ MNIST 데이터셋 불러오기

 
fashion_train_df = pd.read_csv('다운로드한 본인 파일 경로/fashion-mnist_train.csv', sep=',')
fashion_test_df = pd.read_csv('다운로드한 본인 파일 경로/fashion-mnist_test.csv', sep=',')
 

3️⃣ 데이터 시각화

 
  • 이미지들은 28X28 픽셀, 즉 784 픽셀로 표현이 된다 (column의 수)
  • 이미지를 평탄화해서 각 행이 이미지를 나타내도록 한 것이다
 
print(fashion_train_df.shape)
print(fashion_test_df.shape)
notion image
fashion_train_df.head()
notion image
 
training = np.array(fashion_train_df, dtype = 'float32')
testing = np.array(fashion_test_df, dtype = 'float32')
 
  • 하나의 이미지를 시각화
    • • plt.imshow 사용
plt.imshow(training[10,1:].reshape(28,28))
notion image
 
  • 무작위 값을 설정해서 테스트해보기
import random
i = random.randint(1,10000)
plt.imshow(training[i,1:].reshape(28,28))
label = training[i,0]
label
notion image
 
  • 데이터를 행렬 형태로 도식화
# 간단한 형태로 행렬(격자) 만들기
W_grid = 15
L_grid = 15

# 격자 차원으로 하위 그래프 생성
fig, axes = plt.subplots(L_grid, W_grid, figsize = (17,17))

# 배열과 축을 15x15로 평탄화
axes = axes.ravel()

# 학습 데이터 길이 정의
n_training = len(training)

# 도식화하고자하는 전체 이미지 출력
# 무작위 변수를 만들고 변수의 인덱스와 변수에 해당하는 이미지 출력
for i in np.arange(0, W_grid * L_grid):
    index = np.random.randint(0, n_training)
    axes[i].imshow(training[index,1:].reshape((28,28)))
    axes[i].set_title(training[index,0], fontsize = 8)
    axes[i].axis('off')

# 이미지 사이의 높이인 hspace 지정
plt.subplots_adjust(hspace=0.4)
notion image
 

4️⃣ 모델 학습

 
  • 이미지를 스캔하여 이미지의 특징을 추출
X_train = training[:, 1:]/255
y_train = training[:, 0]
X_test = testing[:, 1:]/255
y_test = testing[:, 0]

from sklearn.model_selection import train_test_split
X_train, X_validate, y_train, y_validate = train_test_split(X_train, y_train, 
                                                            test_size = 0.2, 
                                                            random_state = 12345)
X_train = X_train.reshape(X_train.shape[0], *(28,28, 1))
X_test = X_test.reshape(X_test.shape[0], *(28,28, 1))
X_validate = X_validate.reshape(X_validate.shape[0], *(28,28, 1))
print(X_test.shape)
print(X_train.shape)
print(X_validate.shape)
notion image
import keras

# 완전 연결 네트워크 구축
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout
from keras.optimizers import Adam
from keras.callbacks import TensorBoard
 
  • 모델 구축
    • 모델을 순차적인 형태로 구축
 
 
cnn_model = Sequential()
cnn_model.add(Conv2D(32, 3, 3, input_shape = (28, 28, 1), activation = 'relu'))
cnn_model.add(MaxPooling2D(pool_size = (2,2)))
cnn_model.add(Flatten())
cnn_model.add(Dense(32, activation = 'relu'))
cnn_model.add(Dense(10, activation = 'sigmoid'))

cnn_model.compile(loss = 'sparse_categorical_crossentropy', optimizer=Adam(lr=0.001), metrics = ['accuracy'])

epochs = 50

cnn_model.fit(X_train,
             y_train,
             batch_size = 512,
             epochs = epochs,
             verbose = 1,
             validation_data = (X_validate, y_validate))
notion image
→ 50회 epoch를 수행한 후 정확도가 87%에 도달했다. 꽤 높다
 
 

5️⃣ 모델 평가

evaluation = cnn_model.evaluate(X_test, y_test)
print('Test Accuracy : {:.3f}'.format(evaluation[1]))
notion image
 
  1. 예측 클래스 사용해서 모델 평가하기
predicted_classes = cnn_model.predict_classes(X_test)
predicted_classes
notion image
 
L = 5
W = 5
fig, axes = plt.subplots(L, W, figsize = (12, 12))
axes = axes.ravel()

for i in np.arange(0, L*W):
    axes[i].imshow(X_test[i].reshape(28,28))
    axes[i].set_title('Prediction Class = {:.1f}\n True Class = {:0.1f}'.format(predicted_classes[i], y_test[i]))
    axes[i].axis('off')

plt.subplots_adjust(wspace = 0.5)
notion image
 
  1. 혼동 행렬로 모델 평가하기
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, predicted_classes)
plt.figure(figsize = (14,10))
sns.heatmap(cm, annot = True)
notion image
→ 대각선 : 맞춘 개수 & 나머지 : 틀린 개수
 
from sklearn.metrics import classification_report

num_classes = 10
target_names = ['Class {}'.format(i) for i in range(num_classes)]

print(classification_report(y_test, predicted_classes, target_names = target_names))
notion image
 
Class별 옷 종류
0 : 티셔츠
1 : 바지
2 : 스웨터
3 : 원피스
4 : 코트
5 : 샌들
6 : 셔츠
7 : 운동화
8 : 가방
9 : 앵클 부츠
⇒ 셔츠의 분류 정확도가 가장 떨어진다는 것을 알 수 있다
 

6️⃣ 모델 개선

모델 개선을 위해서는 두 가지 방법이 있다.
 
  • 32x32 커널을 64x64 또는 128x128로 바꿔보자
  • 드롭 아웃
 
이 방법들은 본 프로젝트에서는 다루지 않습니다!
 
 
 
 

 
 
본 스터디는 Udemy의 <【한글자막】 Machine Learning 완벽 실습 : 6가지 실제 사례 직접 해결하기> 강의를 활용해 진행됐습니다. 강의에 대한 자세한 정보는 아래에서 확인하실 수 있습니다.
 
 
프밍 스터디는 Udemy Korea와 함께 합니다.
 
 

 
원하는 스터디가 없다면? 다른 스터디 개설 신청하기
누군가 아직 원하는 스터디를 개설하지 않았나요? 여러분이 직접 개설 신청 해 주세요!
이 포스트는
"실전문제로 배우는 머신러닝" 스터디의 진행 결과입니다
진행중인 스터디
실전문제로 배우는 머신러닝
머신러닝 실전 프로젝트를 매주 1개씩 진행하면서 실무 능력을 길러봅시다!
오혜수 멘토
안녕하세요! 저는 머신러닝에 관심 있는 취준생입니다!