Image dataset들 중 상대적으로 간단하여 연습하기 좋은 패션 MNIST Dataset을 통해 Image classification (티셔츠인지, 운동화인지 등 총 10가지 Category로 분류)을 진행해 보겠습니다.
먼저 Tensorflow와 keras를 import 합니다.
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
keras.datasets.fashion_mnist를 호출하면 패션 MNIST dataset을 받을 수 있습니다.
데이터를 받은 후 Train / test와 image / label을 나눕니다.
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
shape를 찍어보면 28 x 28 픽셀의 이미지이기 때문에 28 x 28 array 형태로 되어있음을 알 수 있고,
train은 60000장, test는 10000장이 있음을 알 수 있습니다.
print(train_images.shape)
print(train_labels.shape)
print(test_images.shape)
print(test_labels.shape)
모델 학습 전에, 데이터가 어떻게 생겼는지 확인을 해봐야겠습니다.
첫 번째 Index의 이미지를 확인하니 array가 0~255 사이의 값임을 확인했습니다.
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
여기서는 간단하게 0~1 사이의 값으로 Rescaling 합니다.
train_images = train_images / 255.0
test_images = test_images / 255.0
이제 이미지를 다시 찍어보겠습니다.
데이터에 10가지 label이 숫자로 들어가 있었으니 class의 name도 달아서 보기 좋게 시각화해보겠습니다.
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
plt.figure(figsize=(10,8))
for i in range(20):
plt.subplot(4,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()
드디어 전처리가 끝났습니다.
이제 아주 간단한 모델을 구성해보겠습니다.
첫 번째 층인 keras.layers.Flatten은 2차원 배열(28x28)의 이미지 포맷을 784 픽셀의 1차원 배열로 바꿔줍니다. 학습이 되는 층이 아니고 말 그대로 Flatten만 해줍니다.
두 번째 층인 keras.layer.Dense(128, activation = 'relu')은 128개의 Hidden unit을 가지고 있는 층입니다. activation 함수로는 (웬만해서는) relu를 적용해 줍니다.
마지막 층인 keras.layer.Dense(10, activation = 'softmax')는 10가지의 class의 속할 확률을 출력하는 아주 중요한 층입니다. 최종적으로 10가지로 분류할 것이기 때문에 activation 함수를 softmax로 적용해줍니다.
여기서 Tuning을 해보고 싶으시면 두 번째 층 위아래로 Hidden layer를 더 쌓거나, 128개의 Hidden unit을 64개 등으로 변경하셔도 무방합니다.
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
방금 만든 모델의 정보입니다. 총 train 되는 parameter의 수는 101,770개입니다.
model.summary()
다음은 model의 compile 단계입니다. 몇 가지를 설정해주셔야 합니다.
optimizer 기법과 손실 함수를 바탕으로 모델의 업데이트 방법을 결정해야 합니다.
주로 사용하는 adam과 crossentropy를 사용하겠습니다. (이 문제의 상황에서는 sparse를 사용하여야 합니다.)
모델 학습의 지표로 accuracy(맞춘 퍼센트 정도)를 사용하겠습니다.
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
드디어 준비가 다 끝났습니다.
아주 간단한 코드인 model.fit을 사용하여 epoch 20번 돌려보겠습니다. epoch을 진행할수록 loss가 떨어지는 게 잘 보이므로 학습이 잘 진행되고 있음을 알 수 있습니다.
train set의 accuracy는 20회 정도 했을 때 0.93 정도로 나왔습니다.
model.fit(train_images, train_labels, epochs=20)
이제 훈련된 모델이 test set에 얼마나 잘 맞는지 확인을 해봐야 합니다.
predictions = model.predict(test_images)
predictions의 첫 번째 index를 확인해보면 총 10가지의 class에 각각 속할 확률을 반환한 것을 알 수 있습니다.
predictions[0]
마지막 label의 확률이 가장 높습니다. 결과적으로 Ankle boot라고 예측하고 있습니다.
np.argmax(predictions[0])
test set에도 정답이 달려있어서 예측과 진짜 맞는지 확인해보니 정답입니다.
test_labels[0]
데이터를 시각화해서 확인하기 위해 plotting 하는 함수를 가져옵니다.
def plot_image(i, predictions_array, true_label, img):
predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
predictions_array, true_label = predictions_array[i], true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
15개 정도의 이미지를 시각화로 한번 살펴보았을 때, 대부분 학습이 잘 된 것을 확인할 수 있습니다.
Sneaker가 정답인데 Sandal이라고 93%의 확신을 가지고 예측한 이미지도 있습니다. 두 개가 비슷하게 생겼기 때문에 저런 결과가 나온 것 같고 학습 데이터가 좀 더 많거나 CNN 모델을 썼다면 저것도 맞출 수 있었을 것 같습니다.
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()
마지막으로, 예측과 test 결과가 어느 정도 맞는지를 확인해보겠습니다.
CNN도 적용하지 않은 아주 간단한 모델이고 Tuning을 하지 않았는데도 88% 정도의 성능을 내는 것을 확인할 수 있습니다.
from sklearn.metrics import accuracy_score
accuracy_score(tf.math.argmax(predictions, -1), test_labels)
아주 기본적인 Image Classification을 알아보았습니다.
여기서의 Deep learning을 적용하기 위한 과정 (데이터 로드 -> 전처리 -> 모델 구성 -> 컴파일 -> 학습 -> 평가)은
복잡한 문제에서도 유효하기 때문에 중요한 예제였습니다.
포스팅은 계속됩니다!
출처 : https://www.tensorflow.org/tutorials/keras/classification