[텐서플로2] MNIST 데이터를 훈련 데이터로 사용한 DNN 학습

TensorFlow 2에서 손글씨로 작성해 스캔한 MNIST 데이터를 DNN 모델 학습을 통해 분류하는 코드를 정리해 봅니다.

먼저 아래처럼 텐서플로 라이브러리를 임포트 해야 합니다.

import tensorflow as tf

텐서플로와 케라스가 매우 밀접하게 통합되었고, 다양한 데이터셋이 케라스 라이브러리를 통해 활용할 수 있습니다. 아래의 코드를 통해 MNIST 데이터셋을 인터넷을 통해 가져옵니다.

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

x_train에는 총 60000개의 28×28 크기의 이미지가 담겨 있으며, y_train에는 이 x_train의 60000개에 대한 값(0~9)이 담겨 있는 레이블 데이터셋입니다. 그리고 x_train과 y_train은 각각 10000개의 이미지와 레이블 데이터셋입니다. 먼저 x_train와 y_train을 통해 모델을 학습하고 난 뒤에, x_test, y_test 를 이용해 학습된 모델의 정확도를 평가하게 됩니다. 다음 코드는 신경망 모델입니다.

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

총 4개의 레이어로 구성된 신경망인데, 1번째 레이어는 입력 이미지의 크기가 28×28이므로 이를 1차원 텐서로 펼치는 것이고, 2번째 레이어는 1번째 레이어에서 제공되는 784 개의 값(28×28)을 입력받아 128개의 값으로 인코딩해 주는데, 활성함수로 ReLU를 사용하도록 하였습니다. 2번째 레이어의 실제 연산은 1번째 레이어에서 제공받은 784개의 값을 784×128 행렬과 곱하고 편향값을 더하여 얻은 128개의 출력값을 다시 ReLU 함수에 입력해 얻은 128개의 출력입니다. 3번째는 128개의 뉴런 중 무작위로 0.2가 의미하는 20%를 다음 레이어의 입력에서 무시합니다. 이렇게 20% 정도가 무시된 값이 4번째 레이어에 입력되어 충 10개의 값을 출력하는데, 여기서 사용되는 활성화 함수는 Softmax가 사용되었습니다. Softmax는 마지막 레이어의 결과값을 다중분류를 위한 확률값으로 해석할 수 있도록 하기 위함입니다. 10개의 값을 출력하는 이유는 입력 이미지가 0~9까지의 어떤 숫자를 의미하는지에 대한 각각의 확률을 얻고자 함입니다. 이렇게 정의된 모델을 학습하기에 앞서 다음처럼 컴파일합니다.

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

모델의 학습 중에 역전파를 통한 가중치 최적화를 위한 기울기 방향에 대한 경사하강을 위한 방법으로 Adam을 사용했으며 손실함수로 다중 분류의 Cross Entropy Error인 ‘sparse_categorical_crossentropy’를 지정하였습니다. 그리고 모델 평가를 위한 평가 지표로 ‘accuracy’를 지정하였습니다. 이제 다음처럼 모델을 학습할 수 있습니다.

model.fit(x_train, y_train, epochs=5)

학습에 사용되는 데이터넷과 학습 반복수로 5 Epoch을 지정했습니다. Epoch은 전체 데이터셋에 대해서 한번 학습할때의 단위입니다. 학습이 완료되면 다음과 같은 내용이 출력됩니다.

Train on 60000 samples
Epoch 1/5
2019-11-16 21:24:27.115767: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_100.dll
60000/60000 [==============================] – 6s 103us/sample – loss: 0.2971 – accuracy: 0.9137
Epoch 2/5
60000/60000 [==============================] – 5s 78us/sample – loss: 0.1428 – accuracy: 0.9577
Epoch 3/5
60000/60000 [==============================] – 5s 79us/sample – loss: 0.1074 – accuracy: 0.9676
Epoch 4/5
60000/60000 [==============================] – 5s 80us/sample – loss: 0.0846 – accuracy: 0.9742
Epoch 5/5
60000/60000 [==============================] – 5s 80us/sample – loss: 0.0748 – accuracy: 0.9766

다음 코드로 모델을 평가합니다.

model.evaluate(x_test,  y_test, verbose=2)

평가를 위한 데이터셋을 지정하고, 평가가 끝나면 다음과 같이 평가 데이터셋에 대한 손실값과 정확도가 결과로 표시됩니다.

10000/1 – 1s – loss: 0.0409 – accuracy: 0.9778

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다