텐서 플로우 블로그 케라스 딥러닝 2.1 신경망과의 첫 만남
텐서 플로우 블로그 케라스 딥러닝 2.5 첫번째 예제 다시 살펴보기
딥 러닝을 이용한 자연어 처리 입문 08. 딥 러닝 개요 06) 케라스(Keras) 훑어보기
해당 사이트를 개인 공부 목적으로 재구성한 내용입니다.
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)
신경망 구조
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개의 클래스로 분류하는 문제이므로 소프트맥스 함수를 활용한다.
: fully connected 신경망 레이어. model.add() 에서 add의 인자로 들어가게 된다.
해당 예시에서는 Dense 층 2개가 연속되어 있다.
model = Sequential()
model.add(Dense(1,input_dim=3, activation='relu'))
model.add(Dense(8, input_dim=4, activation='relu'))
# 출력 뉴런의 수가 8개인 레이어
model.add(Dense(1, activation = 'sigmoid'))
# 이전층 뉴런의 수를 알고 있기 때문에 input_dim 인자가 없다.
# 마지막 층이므로 첫번째 인자 1이 출력층의 뉴런의 개수가 된다.
모델을 기계가 이해할 수 있도록 컴파일
컴파일 단계
network.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
가중치 텐서를 학습하기 위한 피드백 신호로 사용된다.
훈련하는 동안 손실함수 값은 최소화된다. 미니배치 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) 크기인 배열
모델이 오차로부터 매개 변수를 업데이트 시키는 과정
훈련 = 학습 = 적합(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
save() : 인공 신경망 모델을 hdf5 파일에 저장합니다.
model.save("model_name.h5")
load_model() : 저장해둔 모델을 불러옵니다.
from tensorflow.keras.models import load_model
model = load_model("model_name.h5")