TigerCow.Door


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

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

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

이에 따라서 텐서플로우 공식 홈페이지에 나와있는 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)
블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


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

이번 포스팅에서는 Tensorflow에서 CNN을 다루는 기본적인 내용에 대해서 알아보도록 하겠습니다.


* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.

관련한 상세 내용은 아래 링크를 참고해주세요.

https://hunkim.github.io/ml/



1. CNN


CNN은 이미지 분류나 텍스트 분류 등 다양한 분야에서 굉장히 좋은 성능을 내고 있습니다. 이에 대한 이론적인 내용은 ML&DL 카테고리에서 다루었습니다.

CNN에서는 크게 3가지로 나눠볼 수 있는데, 첫번째로는 입력되는 이미지, 입력되는 벡터와 같은 것을 convoultion을 통해 filter를 사용하는 방법. 그리고 뽑아낸 값에 대해 데이터를 작게 만드는 subsampling 과정. 그리고 이미지나 벡터에서의 특징을 뽑아내는 feature extraction 과정이 있습니다. 그리고 이렇게 뽑아진 특징들은 우리가 이전에 일반적으로 사용했던 일반적인 Neural Network을 이용하여 classification 등을 하게 됩니다.


CNN이 이미지에 큰 기여를 하고 있는데, 그 중 하나의 예가 위와 같은, CT이미지를 분석하는 것 입니다.



CNN은 우리가 이론에서 알아보았던 것처럼 주어진 이미지에 filter를 통해 stride 만큼 움직이면서 각각 하나의 값을 추출합니다. 그리고 이렇게 얻은 값들을 통해 sampling을 진행합니다.

이러한 것들을 우리가 직접 tensorflow로 진행해볼텐데, 처음인 만큼 간단한 이미지를 통해 진행해보도록 하겠습니다.


위와 같이 3x3 이미지에 2x2 filter를 이용하고 이때 stride 는 1x1로 진행합니다.

이러한 과정을 통하면 총 2x2의 데이터가 나올 것 입니다.


2. TensorFlow 실습


그럼 먼저 image를 만들어보도록 하겠습니다.

실습은 jupyter notebook으로 진행합니다.



위와 같이 필요한 라이브러리를 import 하고 이미지를 만들었습니다.

아래에서 출력된 이미지와 함께 비교해보면 높은 값일수록 어두운 색을 내도록 하는 라이브러리를 이용했음을 알 수 있습니다.



위 그림에서 제일 좌측에 있는 입력이미지를 방금 만들었습니다.

그리고 filter는 2x2로 만들것이고 하나의 색상을 가지고, 1개의 필터를 만들 것이기 때문에 Filter: 2,2,1,1 로 표현되었습니다.

그리고 필터의 값이 이미지에서 대응되는 값과 곱해지고 그 합이 출력되는 값에 입력될 것 입니다. 즉 출력되는 2x2 에서 제일 상단 왼쪽의 값은, 1*1+2*1+4*1+5*1 = 12 가 될 것입니다.


이제 이것을 직접 tensorflow에서 구현해보면 아래와 같습니다.



코드의 가운데에서 사용되는 conv2d 함수가 바로 우리가 위에서 계산했던 것들을 손쉽게 해결해주는 함수입니다.

image와 weight를 알맞게 설정하여 strides와 함께 해당 함수에 넣어주면 위에서 볼 수 있는 올바른 결과가 출력되는 것을 볼 수 있습니다.


이때 우리가 padding을 valid로 주었는데, padding 을 same으로 두면 우리의 결과가 입력의 shape과 일치하도록 텐서플로우에서 자동으로 필요한 모서리를 0으로 채우게 됩니다.



즉 우리의 입력이미지에 대해서 padding을 SAME으로 둔다면 위의 왼쪽그림과 같이 0이 채워질 것입니다.


그리고 이를 코드로 구현해본다면,

위와 같이 padding 을 SAME으로 설정해주고 for 문에서 진행하는 reshape을 3,3으로 설정해주면 올바른 결과가 나오는 것을 볼 수 있습니다.


이제 이렇게 우리가 convolution을 진행해보았는데 다음으로는 pooling이라는 작업을 할 수 있습니다.


물론 pooling 또한 convoultion에 대해 이해를 하셨으면 쉽게 진행할 수 있습니다.

우리가 주어지는 입력 이미지에 대해서 filter 사이즈를 정하고, stride와 padding을 정해주면 됩니다.

그리고 많이 사용하는 max_pooling을 사용해볼 것 입니다.

위의 내용을 코드로 구현해보면 아래와 같습니다.


3. MNIST data


이번에는 예전에 다루어보었던 mnist데이터를 다뤄보도록 하겠습니다.


위와 같이 코드를 구현하면 그 결과와 같이 mnist이미지가 나옵니다.

그리고 이를 convolution layer에 통과시킬 수 있습니다.


코드를 대략적으로 살펴보면, 우리의 입력 imgsms 28x28 크기의 한가지 색상을 갖는 이미지이고 n개의 이미지이기 때문에 그 갯수는 정해져 있지 않습니다. 따라서 -1의 값을 주었습니다.

그리고 strides에서는 2x2를 주었는데, 이렇게 되면 출력은 14x14가 될 것입니다.

그리고 아래의 코드는 단지 이미지를 출력하기 위한 코드이니 아직은 대략적으로 넘기시면 됩니다.


그리고 결과에서 볼 수 있듯이 하나의 이미지에서 약간씩 다른 결과 5개를 확인할 수 있습니다.


그리고 이어서 pooling 을 진행해보도록 하겠습니다.



이또한 strides를 2x2로 하였기 때문에 그 크기가 줄어들어 결과에서 7x7로 나타나는 것을 볼 수 있습니다.


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요