본문 바로가기
딥러닝

MNIST 데이터를 활용한 딥러닝 기초

by 볼록티 2020. 5. 16.
728x90
반응형
딥러닝1

딥러닝을 입문할 때 바이블 데이터인 MNIST를 가지고 딥러닝을 배워보자 !

tensorflow 모듈을 불러오고, 버전을 확인한다. tensorflow의 경우 2.1.0, 그 안의 keras의 경우 2.2.4 인 환경에서 실행한다.

In [24]:
import tensorflow as tf
tf.__version__
Out[24]:
'2.1.0'
In [25]:
tf.keras.__version__
Out[25]:
'2.2.4-tf'

이제 tensorflow에 속한 keras에서 mnist를 불러와보자. 아래의 형식대로 불러오게 되면 train set과 test셋을 불러오게 된다.

In [7]:
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images,test_labels) = mnist.load_data() 

아래의 링크를 통해 mnist data에 대해 자세히 알아볼 수 있다.

API reference -> https://keras.io/datasets/#mnist-database-of-handwritten-digits

mnist 데이터는 손글씨로 숫자 0~9를 쓴 것을 28x28좌표에 array형태로 나타낸 데이터이다.

데이터는 numpy array형식으로 불러와지고, 라벨(label)값은 0~9 값을 가진다. 이미지와 라벨은 일대일 대응이다.

In [8]:
print(type(train_images))
<class 'numpy.ndarray'>

아래의 코드를 통해 train/test 데이터의 shape를 확인한다.

In [9]:
print('Shape of train_images array: ', train_images.shape)
print('# of training samples: ', len(train_images))

print('Shape of test_images array: ', test_images.shape)
print('# of test samples: ', len(test_images))
Shape of train_images array:  (60000, 28, 28)
# of training samples:  60000
Shape of test_images array:  (10000, 28, 28)
# of test samples:  10000

train 셋의 경우 60000x28x28로 구성이 되어 있다. 즉 하나의 데이터가 28x28 행렬로 표현된다.

train 데이터의 10000번째 데이터를 살펴보자. 0 이 많고, 이미지로 봤을 때, 검은 잉크가 들어간 부분에 숫자가 표시된 것이다.

In [10]:
train_images[10000] # 0-255 까지의  integer
Out[10]:
array([[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  29, 150, 195, 254,
        255, 254, 176, 193, 150,  96,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,  48, 166, 224, 253, 253, 234,
        196, 253, 253, 253, 253, 233,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,  93, 244, 249, 253, 187,  46,  10,   8,
          4,  10, 194, 253, 253, 233,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0, 107, 253, 253, 230,  48,   0,   0,   0,
          0,   0, 192, 253, 253, 156,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   3,  20,  20,  15,   0,   0,   0,   0,
          0,  43, 224, 253, 245,  74,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0, 249, 253, 245, 126,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  14, 101,
        223, 253, 248, 124,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  11, 166, 239, 253,
        253, 253, 187,  30,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  16, 248, 250, 253,
        253, 253, 253, 232, 213, 111,   2,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  43,  98,
         98, 208, 253, 253, 253, 253, 187,  22,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   9,  51, 119, 253, 253, 253,  76,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   1, 183, 253, 253, 139,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0, 182, 253, 253, 104,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,  85, 249, 253, 253,  36,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,  60, 214, 253, 253, 173,  11,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,  98, 247, 253, 253, 226,   9,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  42,
        150, 252, 253, 253, 233,  53,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,  42, 115,  42,  60, 115, 159, 240,
        253, 253, 250, 175,  25,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0, 187, 253, 253, 253, 253, 253, 253,
        253, 197,  86,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0, 103, 253, 253, 253, 253, 253, 232,
         67,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
          0,   0]], dtype=uint8)

이미지 데이터인 만큼 데이터를 시각화하여 살펴보자.

In [12]:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
plt.style.use('default') # set the same default style as jupyter notebook

def visualize_mnist(image, label):
    plt.imshow(image, cm.binary)
    plt.title(label)
    plt.show()

visualize_mnist(train_images[1000], train_labels[1000])

1000번째 데이터는 라벨값이 0이다. 즉 숫자 0을 나타내는 것이고, 이를 numpy array로 나타낸 것을 시각화하여 해당되는 셀에 0~255(8bit)로 표현하여 색을 입혀 시각화한 것이다.

In [ ]:
 

네트워크를 설계해보자.

필요한 모듈을 불러오기.

In [13]:
from tensorflow.keras import models # tensorflow 내의 keras를 사용해야 기존의 keras와 충돌을 방지할 수 있다.
from tensorflow.keras import layers

가운데에 히든 레이어를 한층만 두었다.

In [15]:
# 모델 틀 생성을 위한 클래스 호출.
network = models.Sequential()

# 512개의 output node를 생성, 활성화함수는 relu함수를 사용, input 데이터는 28x28 1차원을 활용.
network.add(layers.Dense(512, activation='relu', input_shape=(28*28,)))

# output node로는 10개의 클래스로 분류하고, 각 클래스별 속할 확률을 계산하는 활성화함수는 softmax를 활용
network.add(layers.Dense(10, activation='softmax'))

이제 학습을 시킬 준비가 모두 되었고, 3가지를 더 고려해야한다.

  1. A loss function(손실함수) <- 우리는 이거를 최소화하는게 목적이다. 즉 object function이다.

  2. An optimizer <- 최적화를 위한 방법

  3. Metrics to monitor during training and testing <- 학습 중의 모니터링

아래의 코드로써 위의 3가지를 적용시킨다. optimizer에서 rmsprop은 머신러닝에서 gradient descent 처럼 파라미터들의 최적점을 찾는 알고리즘 중 하나이다. loss function은 크로스엔트로피를 활용한다. 학습 모니터링은 모델의 accuracy를 관찰한다.

In [16]:
network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])

데이터를 학습하기전에 데이터를 reshaping, scaling 해야한다.

In [17]:
train_images.shape
Out[17]:
(60000, 28, 28)

케이스 별로 28x28 셀의 0~255 값들을 0 과 1 사이의 값으로 만들어 준다.

In [18]:
# 행렬을 하나의 열로 통합하는 것과 같다. 모든 셀을 일렬로 쭉 늘린 것과 같다. 1 dimension
train_images = train_images.reshape((60000, 28*28)) 
train_images = train_images.astype('float32') / 255 #maximum value 로 나누어 0-1로 변형.
test_images = test_images.reshape((10000, 28*28))
test_images = test_images.astype('float32') / 255

label 값은 one-hot 인코딩으로 변형시켜준다.

In [19]:
from tensorflow.keras.utils import to_categorical

train_labels = to_categorical(train_labels) # one-hot encoding
test_labels = to_categorical(test_labels)

one-hot 인코딩으로 변환된 10번째 데이터를 보면 잘 바뀐 것을 알 수 있다.

In [20]:
train_labels[10]
Out[20]:
array([0., 0., 0., 1., 0., 0., 0., 0., 0., 0.], dtype=float32)

이제 network.fit 함수를 사용하여 fitting을 한다. 훈련데이터에 대한 loss와 accuracy를 확인할 수 있다. epoch

In [21]:
import time

start = time.time()
network.fit(train_images, train_labels,
            epochs=10, #epochs:전체 데이터를 총 10번 보는 기간 동안 모델 업데이트, 
            batch_size=128 # batch_size:랜덤하게 128 개의 데이터를 추출하여 weight를 업데이트.
           ) 
elapsed = time.time() - start

print('Elapsed time: %.4f' % elapsed)
Train on 60000 samples
Epoch 1/10
60000/60000 [==============================] - 4s 64us/sample - loss: 0.2563 - accuracy: 0.9261
Epoch 2/10
60000/60000 [==============================] - 4s 68us/sample - loss: 0.1034 - accuracy: 0.9693
Epoch 3/10
60000/60000 [==============================] - 4s 71us/sample - loss: 0.0681 - accuracy: 0.9794
Epoch 4/10
60000/60000 [==============================] - 5s 83us/sample - loss: 0.0490 - accuracy: 0.9855
Epoch 5/10
60000/60000 [==============================] - 5s 76us/sample - loss: 0.0377 - accuracy: 0.9885
Epoch 6/10
60000/60000 [==============================] - 3s 55us/sample - loss: 0.0283 - accuracy: 0.9918
Epoch 7/10
60000/60000 [==============================] - 4s 61us/sample - loss: 0.0224 - accuracy: 0.9930
Epoch 8/10
60000/60000 [==============================] - 3s 58us/sample - loss: 0.0173 - accuracy: 0.9947
Epoch 9/10
60000/60000 [==============================] - 4s 58us/sample - loss: 0.0131 - accuracy: 0.9964
Epoch 10/10
60000/60000 [==============================] - 4s 64us/sample - loss: 0.0103 - accuracy: 0.9969
Elapsed time: 39.5666

테스트 셋에대해서도 똑같이 model performance를 체크해보자.

In [22]:
len(test_images)
Out[22]:
10000
In [23]:
test_loss, test_acc = network.evaluate(test_images, test_labels)
print('test_acc: ', test_acc) 
10000/10000 [==============================] - ETA: 0s - loss: 0.0689 - accuracy: 0.98 - 1s 65us/sample - loss: 0.0714 - accuracy: 0.9807
test_acc:  0.9807

train set에 비해 accuracy가 조금 떨어진 것을 알 수 있다. 이런 차이를 가지고 generalization 일반화를 한다.

In [ ]:
 
728x90
반응형

'딥러닝' 카테고리의 다른 글

multi class classification  (0) 2020.06.20
binary classification_multi perceptron  (0) 2020.06.20
4. How Deep learning work  (0) 2020.03.28
3. Generalization  (0) 2020.03.28
2. Machine learning  (0) 2020.03.28

댓글