AI & BigData/TensorFlow

텐서플로우(tensor flow) 튜토리얼 #1_Basic Classification

Tigercow.Door 2018. 8. 4. 20:50


안녕하세요. 문범우입니다.

오랜만에 텐서플로우에 관련된 포스팅을 진행하게 되었습니다.

최근 기계학습과 관련되서 공부를 하며 텐서플로우를 다루는 방법에 대해서 좀 더 공부해야겠다는 필요성을 느껴서, 아예 처음부터 시작해보려 합니다.

이에 따라서 텐서플로우 공식 홈페이지에 나와있는 tutorial을 하나씩 따라해 가면서 필요한 부분들을 추가적으로 공부해 볼 예정입니다.


https://www.tensorflow.org/tutorials/keras/basic_classification?hl=ko


위의 링크에서 overview 를 살펴보시면 아실 수 있듯이 해당 튜토리얼에서는 tensorflow내부의 keras 를 사용합니다.


먼저 오늘은 첫번째로 basic classification 에 대해서 진행해보도록 하겠습니다.




ㄱ. 데이터 준비하기

In [5]:
# TensorFlow and tf.keras
# 텐서플로우와 keras를 import한다. 이떄 tensorflow는 tf라는 별칭으로 사용할 것임.
import tensorflow as tf
from tensorflow import keras

# Helper libraries
# numpy와 matplotlib을 사용한다.
import numpy as np
import matplotlib.pyplot as plt
# jupyter notebook에서 matplotlib을 사용하기 위한 매직커맨드
%matplotlib inline

print("사용되는 tensorflow의 버전:",tf.__version__)
사용되는 tensorflow의 버전: 1.9.0

이제 Fashion MNIST data를 불러올 것이다.

Fashoin MNIST data는 아래와 같은 이미지들로 구성되어 있다.

하나의 이미지는 28x28 pixels 이다. 이전에는 보통 classic MNIST data로써 숫자 손글씨를 바탕으로 했지만 위와 같은 Fashion MNIST data를 통해 보다 도전적인 문제를 만들어 줄 것이다.

In [6]:
# Fashion MNIST data import
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 1s 28us/step
Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 21s 1us/step
Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz
8192/5148 [===============================================] - 0s 0us/step
Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 10s 2us/step

위에서 Fashion MNIST data를 가져왔다.

train_images와 train_labels가 train_data_set이고 test_images와 test_labels가 test_data_set이다.

우리가 만드는 학습모델에 train_data_set을 통해 학습시킬 것이고, test_images를 통해 예측값을 도출한 후 test_labels와 비교하여 오차를 측정할 것이다.

In [9]:
train_labels
Out[9]:
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)

위와 같이 label은 0~9까지의 값을 가지고 있다.

각 숫자가 의미하는 바는 다음과 같다.

Label: Class

0: T-shirt/top

1: Trouser

2: Pullover

3: Dress

4: Coat

5: Sandal

6: Shirt

7: Sneaker

8: Bag

9: Ankle boot

이를 실제로 표현해주기 위해 class_names를 정의한다.

In [10]:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

ㄴ. 데이터 살펴보기

이제 위에서 가져온 데이터가 실제로 어떻게 생겼는지 살펴보도록 한다.

In [11]:
train_images.shape
Out[11]:
(60000, 28, 28)
In [12]:
test_images.shape
Out[12]:
(10000, 28, 28)

먼저 train와 test image모두 위에서 말한바와 같이 28x28 크기를 가지고 있으며 각각 6만개, 1만개의 이미지를 가지고 있음을 확인할 수 있다.

ㄷ. 데이터 전처리

모델에 데이터를 학습시키기 위해 먼저 데이터 전처리를 진행한다.

In [15]:
# matplotlib을 통해 그림을 그린다.
plt.figure()
# train_images의 첫번째 요소를 그린다.
plt.imshow(train_images[0])
plt.colorbar()
# 점자선을 False로 둠으로써 없앤다.
plt.gca().grid(False)

이미지를 모델에 학습시키기 전에 모든 요소가 0~1의 값을 갖도록 모든 값을 255로 나눠준다.

In [16]:
train_images = train_images / 255.0
test_images = test_images / 255.0

위와 같은 그림을 확인해보면 그림은 그대로 지만 모든 요소가 0~1 사이의 값을 갖도록 변한 것을 확인할 수 있다.

In [18]:
# matplotlib을 통해 그림을 그린다.
plt.figure()
# train_images의 첫번째 요소를 그린다.
plt.imshow(train_images[0])
plt.colorbar()
# 점자선을 False로 둠으로써 없앤다.
plt.gca().grid(False)

보다 많은 이미지를 확인해보자.

위에서 정의했던 class_names를 적용해서 어떤 사진인지 label과 함께 확인해본다.

In [19]:
plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid('off')
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
/Users/doorbw/.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Passing one of 'on', 'true', 'off', 'false' as a boolean is deprecated; use an actual boolean (True/False) instead.
  warnings.warn(message, mplDeprecation, stacklevel=1)

ㄹ. 모델 구성하기

이제 실제로 Fashion MNIST data를 예측하는 모델을 만들어본다.

neural network의 기본 구성 단위는 layer이다.

먼저 아래의 코드를 확인해보자.

In [20]:
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])

위의 코드를 확인해보면 model은 총 3개의 layer를 갖는 것을 확인할 수 있다.

첫번째 layer, Flatten 에서는 28x28로 되어있는 2차원 값을 1차원으로 만들어준다.

두번째 layer, Dense 에서는 128개의 노드를 가지며 relu라는 activation function을 수행한다.

세번째 lyaer, Dense 에서는 10개의 노드를 가지며 softmax함수를 통해 classification하는 작업을 수행한다.

그리고 해당 모델을 실제로 학습시키기 이전에 추가적인 요소들을 아래와 같이 설정한다.

In [21]:
model.compile(optimizer=tf.train.AdamOptimizer(), 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

모델이 사용하는 optimizer를 선택해주고, loss function을 선택한다.

그리고 metrics는 측정항목을 적어준다.

ㅁ. 모델 학습시키기

keras를 통해 모델을 학습시키는 것은 매우 간단하다.

fit 함수를 이용해서 학습시킬 images와 labels를 넣어주고 epoch를 설정한다.

In [22]:
model.fit(train_images, train_labels, epochs=5)
Epoch 1/5
60000/60000 [==============================] - 4s 65us/step - loss: 0.4992 - acc: 0.8261
Epoch 2/5
60000/60000 [==============================] - 3s 43us/step - loss: 0.3746 - acc: 0.8659
Epoch 3/5
60000/60000 [==============================] - 2s 41us/step - loss: 0.3401 - acc: 0.8759
Epoch 4/5
60000/60000 [==============================] - 2s 40us/step - loss: 0.3140 - acc: 0.8863
Epoch 5/5
60000/60000 [==============================] - 3s 44us/step - loss: 0.2951 - acc: 0.8919
Out[22]:
<tensorflow.python.keras.callbacks.History at 0xb4045b358>

ㅂ. 모델 평가하기

모델을 평가하는 것 또한 간단하다.

먼저 전체적인 accuracy를 확인해보자.

아래와 같이 model의 evaluate함수를 이용하여 test images와 labels를 인자로 주면된다.

이때 loss와 accuracy가 결과로 나오게 된다.

In [23]:
test_loss, test_acc = model.evaluate(test_images, test_labels)

print('Test accuracy:', test_acc)
10000/10000 [==============================] - 0s 35us/step 
Test accuracy: 0.8719

개별적으로는, 실제 모델이 어떻게 예측하는지 이미지와 함께 확인해볼 수 있다.

먼저 아래와 같이 model의 predict 함수에 test_images를 인자로 넣어준다.

In [24]:
predictions = model.predict(test_images)

이때 predictions는 리스트 값으로써 test_images의 순서와 동일하게, 각각에 대한 예측값을 갖고있다.

In [25]:
predictions[0]
Out[25]:
array([9.0106724e-08, 3.2413985e-10, 1.7162860e-08, 2.0211715e-09,
       8.9574826e-08, 1.1119398e-03, 2.9414159e-07, 9.4250463e-02,
       5.5220462e-06, 9.0463161e-01], dtype=float32)

우리는 해당 10개의 값중 가장 큰 값을 정답이라고 생각할 것이기 때문에 numpy의 argmax함수를 통해 가장 큰 값을 갖는 인덱스를 뽑아보면 다음과 같다.

In [27]:
np.argmax(predictions[0])
Out[27]:
9

실제로 이는 test_labels의 0번째 값과 동일하다.

In [28]:
test_labels[0]
Out[28]:
9

위와 같은 방식으로 총 25개의 test_images에 대한 이미지와 예측결과를 비교해보자.

In [29]:
plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid('off')
    plt.imshow(test_images[i], cmap=plt.cm.binary)
    # predictions에서 가장 큰 값을 predicted_label 로 가져온다.
    predicted_label = np.argmax(predictions[i])
    true_label = test_labels[i]
    # 이때 실제 test_label과 일치하면 초록색 글씨로,
    if predicted_label == true_label:
      color = 'green'
    # 일치하지 않으면 빨간색 글씨로 출력한다.
    else:
      color = 'red'
    plt.xlabel("{} ({})".format(class_names[predicted_label], 
                                  class_names[true_label]),
                                  color=color)
/Users/doorbw/.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Passing one of 'on', 'true', 'off', 'false' as a boolean is deprecated; use an actual boolean (True/False) instead.
  warnings.warn(message, mplDeprecation, stacklevel=1)
728x90