데이터 다루기/Vision (Tensorflow)

[Vision] 이미지 분류

분석벌레 2021. 3. 13. 03:17
728x90

1. 사용할 패키지 불러오기.

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

import를 활용하여 사용할 패키지를 불어왔습니다.

2. 데이터 불러오기.

fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

저희는 이번 실습에서 굉장히 유명한 Open dataset 중에 하나인 패션 MNIST를 활용하겠습니다.

패션 MNIST 일반적인 숫자로 알려져 있는 기본 MNIST보다 어려운 과제입니다.

그림 1. 패션-MNIST 샘플 (Zalando, MIT License).

코드를 한 줄 씩 살펴보겠습니다.

fashion_mnist = keras.datasets.fashion_mnist

keras.datasets에는 여러가지 open data가 저장되어있습니다.

저희는 그중에서 fashion_mnist를 사용하는 것입니다.

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

fashion_mnist에 대해서 load_data()를 입력하면 총 4개의 numpy array가 반환됩니다.

이들은 정의된 바와 같이 train dataset에 해당하는 이미지와 라벨, 그리고 test dataset에 해당하는 이미지와 라벨입니다.

Fashion_mnist는 다음과 같은 라벨을 가지고 있습니다.

https://www.researchgate.net/figure/Examples-from-the-Fashion-MNIST-dataset_fig6_333997546

3. 데이터 전처리

데이터 분석 프로세스에 있어서 모델링 전에 반드시 진행해야 하는 절차가 있습니다.

바로 데이터 전처리입니다.

train_images.shape

(60000, 28, 28)

가져온 데이터의 구조를 보도록 하겠습니다.

train 데이터 셋의 이미지는 총 60,000장으로 확인됩니다.

또환 이러한 이미지들은 모두 28 x 28 pixel로 만들어집니다.

test_images.shape

(10000, 28, 28)

반면에 test 데이터 셋의 이미지는 총 10,000장이면서 이미지의 pixel 크기는 같습니다.

plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

위의 그래프를 보시면 각 픽셀의 크기가 0~255의 범위를 가지는 것을 보실 수 있습니다.

하지만 신경망 모델의 특성상 입력값은 -1~1 사이의 범위를 가지거나 0~1 사이의 범위를 가지게 하는 것이 효율적입니다.

train_images = train_images / 255.0

test_images = test_images / 255.0

저희는 0~1 사이의 값을 가지게 하기 위해서 255로 나누었습니다.

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

총 25개의 이미지를 가지고 온 결과 데이터가 잘 불러와졌다는 것을 보실 수 있습니다.

4. 분류 모델 생성

이번 포스팅에서는 이미지 데이터를 활용해서 DNN 모델로 분류해보겠습니다.

CNN 모델은 다음 포스팅에서 다루어 보도록 할게요.

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

keras에서는 Sequential로 층을 쌓을 수 있습니다.

이미지를 Fully-connected layer에 넣기 위해서 28 * 28 피처 맵을 펼쳐 줄 필요가 있습니다.

그 역할을 하는 것이 Flatten layer 입니다.

그리고 펼쳐 진 feature를 Fully-connected layer에 넣어줍시다.

Dense라는 함수가 Fully-connected layer를 의미합니다. 첫번째 인자로는 output dimension을 의미합니다.

즉 첫번째 layer는 28 * 28개의 feature를 128개로 압축합니다.

그리고 활성 함수로 relu를 사용하였습니다.

두 번째 layer는 128개의 feature를 10개로 압축합니다.

왜냐하면 class가 10개있기 때문이죠!

활성 함수는 분류 문제이기 때문에 softmax를 사용합니다.

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

다음으로 모델을 훈련하기 위한 Optimizer와 Loss를 설정합니다.

Adam과 Sparse categorical crossentropy를 사용합니다.

model.fit(train_images, train_labels, epochs=5)

fit 함수를 통해서 모델을 훈련시킬 수있습니다. epoch는 간단하게 5회만 입력하였습니다.

5. 분류 예측

위에서 훈련된 분류 모델로 Test 데이터셋에 대한 예측을 해보겠습니다.

predictions = model.predict(test_images)

훈련된 모델을 활용해서 .predict를 붙여주면 예측이 진행됩니다.

num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions, test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions, test_labels)
plt.show()

위의 코드로 예측에 대한 신뢰도를 측정해볼 수 있습니다.

epoch가 적었음에도 불구하고 꽤나 좋은 성능을 보이네요.