케라스, MNIST 손글씨 딥러닝 예제 분석
<참조> 유튜브 [토크ON세미나] 딥러닝 입문에서 활용까지 케라스(Keras)
https://www.youtube.com/watch?v=IPR2bYFa6Rw
글. 오상문 sualchi@daum.net
다음 예제는 숫자 0~9 숫자에 대한 MNIST 손글씨 데이터(그레이스케일 이미지 데이터와 숫자 결과)를 이용하여 딥러닝 후에 테스트 결과를 확인하는 예제이다. 예제에 설명을 달았으니 참고하기 바란다.
MNIST 데이터는 손글씨 이미지(28*28 = 784바이트 크기) 샘플 7만개와 정답을 담아놓은 데이터셋이다. 이 중에서 6만개는 학습 데이터셋으로 사용하고, 나머지 1만개는 테스트 데이터로 사용할 것이다.
[참고] 케라스2 사용자는 예제 일부에서 경고 메시지가 나타날 수 있다(실행은 됨).
-----------------------------------------------
다음처럼 케라스2 방식으로 수정하면 경고문이 사라진다.
# relu 선형함수를 이용하여 28*28(784) 클래스 크기를 64 크기로 바꾼다.
model.add(Dense(output_dim=64, input_dim=28*28, activation='relu'))
수정 --> model.add(Dense(input_dim=784, activation="relu", units=64))
# 28*28이나 784는 아무 것이나 써도 됨
# softmax 다중분류 함수를 이용하여 클래스 10개 구조로 바꾼다(원핫 인코딩 구조).
model.add(Dense(output_dim=10, activation='softmax'))
수정 --> model.add(Dense(activation="softmax", units=10))
model.fit(X_train, Y_train, nb_epoch=5, batch_size=32)
수정 --> model.fit(X_train, Y_train, epochs=5, batch_size=32)
--------------------------------------------------------------
다음은 설명이 달린 예제 소스 코드이다.
#-------------------------------------------------
# 모듈 임포트 (MNIST 딥러닝을 위해 필요한 기능 모듈을 가져온다)
from keras.utils import np_utils
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Activation
#-------------------------------------------------
# mnist 다운로드, 데이터셋 준비 (Download, Reshape & Categorical)
# mnist에서 훈련자료 6만개와 시험자료 1만개를 가져온다.
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# (학습 입력값,결과값 ), (테스트 입력값,결과값 )
# 구조 변경하여 가져오기
# 총 7만개 중에서 학습용 6만개, 시험용 1만개 샘플을 사용한다.
# 샘플당 크기는 784Byte, 정수 자료이다.
# 참고로, mnist에서 제공하는 손글씨 샘플 하나당 이미지 크기는 28*28(=784)바이트
X_train = X_train.reshape(60000, 784).astype('float32') / 255.0
# 6만개 샘플크기, 실수형 변환, 0~1.0 크기로 변경
X_test = X_test.reshape(10000, 784).astype('float32') / 255.0
# 1만개 샘플크기 , 실수형 변환, 0~1.0 크기로 변경
# 결과(정답) 값에는 0~9까지 숫자 값이 들어가 있다.
# 각 숫자별로 카테고리 클래스 분류를 한다(원핫 인코딩 방식).
# 결과는 클래스 10개 구조인 자료들이다. (예; [1,0,0,0,0,0,0,0,0,0])
# 이 카테고리 클래스 크기 10은 나중에 모델 구성할 단계에서도 사용된다.
Y_train = np_utils.to_categorical(Y_train)
Y_test = np_utils.to_categorical(Y_test)
#-----------------------------------------------------
# 모델 구성 (New Model & Add)
model = Sequential() # 순차적인 다층 구조 모델이 가능한 빈 모델 생성
# 각 층은 한 처리부만 존재하고 다음 층에 처리 결과 전달
# 한 층에서 여러 처리부를 사용하려면 Graph() 모델 사용.
# 단, Graph() 모델은 층 생성 함수가 다르다.
# relu 선형함수를 이용하여 28*28(784) 클래스 크기를 64 크기로 바꾼다.
model.add(Dense(output_dim=64, input_dim=28*28, activation='relu'))
# 출력 차원=64, 입력 차원=784, 활성함수='relu'
# softmax 다중분류 함수를 이용하여 클래스 10개 구조로 바꾼다(원핫 인코딩 구조).
model.add(Dense(output_dim=10, activation='softmax'))
# 출력 차원=10, 입력 차원=자동계산됨(64), 활성함수='softmax'
#------------------------------------------------------
# 모델 엮어서 완성 (Compile)
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
# 손실 처리=다중분류, 최적화 방법='sgd, 측정 기준=정확도
# (sgd: 확률적 경사하강법)
#-------------------------------------------------------
# 모델 학습 (Fit)
model.fit(X_train, Y_train, nb_epoch=5, batch_size=32)
# 입력, 정답 , 전체 5회 반복 , 샘플 32개씩 학습/갱신
#------------------------------------------------------
# 모델 사용 평가 (Evaluate)
loss_and_metrics = model.evaluate(X_test, Y_test, batch_size=32)
# 손실, 정확도 테스트 입력 , 정답 , 샘플 32개씩 작업
print("손실 및 정확도:", str(loss_and_metrics ))
#------------------------------------------------------
# 완성된 모델을 사용해보자 (Predict)
x = X_test[0:1] # 테스트의 첫 샘플을 가져와 사용해보자.
y = model.predict_classes(x) # 기대값이 가장 높은 결과 값 얻음
print("결과: ")
print(y)
y = model.predict(x) # 각 클래스(0~9) 기대값 얻음
print("각 숫자에 대한 가능성:")
print(y)
----------------------------------------------------------------------------
[실행 결과]
Epoch 1/5
60000/60000 [============] - 11s 175us/step - loss: 0.6899 - accuracy: 0.8217
Epoch 2/5
60000/60000 [============] - 11s 177us/step - loss: 0.3512 - accuracy: 0.9014
Epoch 3/5
60000/60000 [============] - 10s 175us/step - loss: 0.3043 - accuracy: 0.9131
Epoch 4/5
60000/60000 [============] - 11s 177us/step - loss: 0.2758 - accuracy: 0.9220
Epoch 5/5
60000/60000 [============] - 11s 178us/step - loss: 0.2540 - accuracy: 0.9280
10000/10000 [============] - 1s 89us/step
결과:
손실 및 정확도: [0.22523144161850214, 0.9363999962806702] <--93.64%
[7] <-- 정답 7이 나왔다!
각 숫자에 대한 가능성:
[[5.7013971e-05 1.5977866e-07 2.9202469e-04 1.7521917e-03 6.8809072e-06
5.1784831e-05 2.1408965e-07 9.9701726e-01 4.1261275e-05 7.8119605e-04]]
빨간색 부분이 숫자 7의 기대값(99.7%)이고 가장 높다.
(0,1,2,3,4,5,6,7,8,9 순서)
[참고] 손글씨 이미지를 출력하는 내용을 보고싶으면 아래 링크 참조
http://blog.daum.net/sualchi/13720847
<이상>
'AI 머신러닝' 카테고리의 다른 글
케라스 categorical_crossentropy, sparse_categorical_crossentropy (0) | 2020.01.16 |
---|---|
케라스, MNIST 예제에서 숫자 샘플 이미지 출력하기 (0) | 2020.01.15 |
케라스, 학습 모델을 파일에 저장하기, 읽어오기 (0) | 2020.01.14 |
케라스, One-hot Encoding (원핫 인코딩) (0) | 2020.01.13 |
케라스(Keras)에서 지원하는 활성 함수 (0) | 2020.01.13 |