케라스 기초 with MNIST 샘플

이은지·2021년 8월 5일
0
post-custom-banner

텐서 플로우 블로그 케라스 딥러닝 2.1 신경망과의 첫 만남
텐서 플로우 블로그 케라스 딥러닝 2.5 첫번째 예제 다시 살펴보기
딥 러닝을 이용한 자연어 처리 입문 08. 딥 러닝 개요 06) 케라스(Keras) 훑어보기
해당 사이트를 개인 공부 목적으로 재구성한 내용입니다.

MNIST 샘플 소개


28 X 28 pixel의 손글씨 숫자 이미지를 10개의 범주 즉 클래스(0~9)로 분류하는 문제
(분류 문제에서의 범주를 클래스라고 칭한다.)

6만 개의 훈련 이미지/ 1만 개의 테스트 이미지로 구성되어 있다.
마치 딥러닝계의 hello world!

데이터 불러오기 및 확인

from keras.datasets import mnist 
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

>>> train_images.shape
(60000, 28, 28)
>>> len(train_labels)
60000
>>> train_labels
array([5, 0, 4, .. ., 5, 6, 8], dtype=uint8)
  • numpy 배열로 인코딩되어 있는 이미지 - 0부터 9까지의 숫자 레이블. 이미지와 레이블은 일대일 관계

신경망 모델 형성하기


신경망 구조

from keras import models
from keras import layers
network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))
  • 층 = 레이어
    : 주어진 문제에 더 의미있는 표현(representation)을 입력된 데이터로부터 추출한다.
    딥러닝 모델은 마치 데이터 정제 필터(layer)가 연속되어 있는 데이터 여과기와 같다.

  • Sequential()
    : 모델을 선언한다. 선언한 모델에 model.add() 라는 코드를 통해 레이어를 단계적으로 추가한다.

  • 소프트맥스 함수
    : 셋 이상을 분류하는 다중 클래스 분류 문제에서 출력층에 주로 활용되는 활성화 함수.
    10개의 확률 점수가 들어 있는 배열을 반환한다. 배열의 값을 모두 더하면 1이다.
    이 예제는 10개의 손글씨를 10개의 클래스로 분류하는 문제이므로 소프트맥스 함수를 활용한다.

Dense() 자세히 살펴보기

: fully connected 신경망 레이어. model.add() 에서 add의 인자로 들어가게 된다.
해당 예시에서는 Dense 층 2개가 연속되어 있다.

  • 첫번째 인자 = 출력 뉴런의 수
  • input_dim = 입력 뉴런의 수(입력의 차원)
  • activation = 활성화 함수
model = Sequential()
model.add(Dense(1,input_dim=3, activation='relu'))

img

model.add(Dense(8, input_dim=4, activation='relu'))
# 출력 뉴런의 수가 8개인 레이어
model.add(Dense(1, activation = 'sigmoid')) 
# 이전층 뉴런의 수를 알고 있기 때문에 input_dim 인자가 없다.
# 마지막 층이므로 첫번째 인자 1이 출력층의 뉴런의 개수가 된다.

img

컴파일(Compile)과 훈련(Training)


컴파일(Compile)

모델을 기계가 이해할 수 있도록 컴파일

컴파일 단계

network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])
  • 손실함수와 옵티마이저의 경우 네트워크에 데이터를 주입하기 전에 정의되어야 한다.
  • 손실함수로 'categorical_crossentropy' 함수를 활용.

가중치 텐서를 학습하기 위한 피드백 신호로 사용된다.
훈련하는 동안 손실함수 값은 최소화된다. 미니배치 SGD를 통해!

  • 'rmsprop' 옵티마이저에 의해 경사 하강법을 적용하는 구체적인 방식이 결정된다.
    즉 훈련 과정을 설정.

  • metrics = 훈련을 모니터링하기 위한 지표. 여기서는 정확도를 사용했다.


손실함수(loss function)

: 훈련 데이터에서 신경망의 성능을 측정하는 방법.
실제값과 예측값의 차이를 수치화하는 함수이다. 오차가 클수록 손실함수의 값이 크다.

MSE, Cross-Entropy function 등

옵티마이저(Optimizer)

: 입력된 데이터와 손실 함수를 기반으로 네트워크를 업데이트하는 매커니즘
SGD(경사하강법)의 변종들을 옵티마이저라고 부른다.

모멘텀을 사용한 SGD, Adagrad, RMSProp

정확도(Accuracy)

: 훈련과 테스트 과정을 모니터링할 지표로서 정확도를 사용할 수 있다.


이미지 리사이징

이미지 리사이징

train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255

[0,255] 사이의 값인 uint8 타입의 (60000,28,28) 크기를 가진 배열
=> 0과 1사이의 값을 가지는 float32 타입의 (60000, 28*28) 크기인 배열


훈련(Training)

모델이 오차로부터 매개 변수를 업데이트 시키는 과정
훈련 = 학습 = 적합(fititng) = 모델이 데이터에 적합해가는 과정

그래서 fit() 라는 단어를 사용한다.

>>> network.fit(train_images, train_labels, epochs=5, batch_size=128)
# 네트워크가 128개 샘플 씩 미니 배치로 훈련 데이터로 훈련을 다섯 번 반복한다.
Epoch 1/5
60000/60000 [==============================] - 1s 22us/step - loss: 0.2571 - acc: 0.9257
Epoch 2/5
60000/60000 [==============================] - 1s 12us/step - loss: 0.1027 - acc: 0.9695
Epoch 3/5
60000/60000 [==============================] - 1s 12us/step - loss: 0.0686 - acc: 0.9797
Epoch 4/5
60000/60000 [==============================] - 1s 12us/step - loss: 0.0494 - acc: 0.9856
Epoch 5/5
60000/60000 [==============================] - 1s 12us/step - loss: 0.0368 - acc: 0.9894
  • fit()

    • 첫번째 인자 = 훈련 데이터

    • 두번째 인자 = 지도 학습에서 레이블 데이터

    • epochs = 총 훈련 횟수

    • batch_size = 배치 크기. 미니 배치 경사 하강법을 사용하고 싶지 않을 경우 batch_size=None으로 설정.

  • 각 반복마다 네트워크가 배치에서 손실에 대한 가중치의 그래디언트를 계산한다.
    그리고 그에 맞추어 가중치를 업데이트 한다.
  • 훈련 샘플이 6만개, 배치 사이즈 128개
    => 469개의 배치

    한 에포크 당 469번의 그래디언트 업데이트를 수행한다.


모델 평가

>>> test_loss, test_acc = network.evaluate(test_images, test_labels)
10000/10000 [==============================] - 0s 16us/step
>>> print('test_acc:', test_acc)
test_acc: 0.9789
  • evaluate()
    : 테스트 데이터를 통해 학습한 모델에 대한 정확도를 평가한다.
  • 훈련 데이터보다 테스트 데이터의 정확도가 더 낮은 이유는 오버피팅으로 설명할 수 있다.

모델의 저장(Save)과 로드(Load)

save() : 인공 신경망 모델을 hdf5 파일에 저장합니다.

model.save("model_name.h5")

load_model() : 저장해둔 모델을 불러옵니다.

from tensorflow.keras.models import load_model
model = load_model("model_name.h5")
post-custom-banner

0개의 댓글