[tensorflow] CNN을 이용한 필기 숫자 인식

초창기 모델인 LeNet-5를 텐서플로로 재현하여 데이터를 인식한다.

컨볼루션 신경망의 유연성을 확인하기 위해 표전적인 빌딩 블록을 벗어난 신경망도 실험한다.

 

LeNet-5 재현

MNIST를 인식하는 컨볼루션 신경망이다.

import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from tensorflow.keras.optimizers import Adam

#데이터를 신경망에 입력할 형태로 변환
(x_train, y_train), (x_test,y_test) = mnist.load_data()
x_train = x_train.reshape(60000,28,28,1) 
x_test = x_test.reshape(10000,28,28,1)

#데이터셋 정규화
x_train = x_train.astype(np.float32)/255.0
x_test = x_test.astype(np.float32)/255.0

#원핫코드 변환
y_train = tf.keras.utils.to_categorical(y_train,10)
y_test = tf.keras.utils.to_categorical(y_test,10)

#LeNet-5 신경망 모델 설계
cnn = Sequential()
cnn.add(Conv2D(6,(5,5),padding='same', activation='relu', input_shape=(28,28,1)))
cnn.add(MaxPooling2D(pool_size=(2,2)))
cnn.add(Conv2D(16,(5,5),padding='same', activation='relu'))
cnn.add(MaxPooling2D(pool_size=(2,2)))
cnn.add(Conv2D(120,(5,5), padding='same', activation='relu'))
cnn.add(Flatten())
cnn.add(Dense(84, activation='relu'))
cnn.add(Dense(10,activation='softmax'))

#신경망 모델 학습
cnn.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
hist = cnn.fit(x_train,y_train, batch_size = 128, epochs = 30, validation_data=(x_test, y_test), verbose=1)

#신경망 모델 정확률 평가
res=cnn.evaluate(x_test,y_test, verbose=0)
print("정확률은",res[1]*100)

import matplotlib.pyplot as plt

#정확률 그래프
plt.plot(hist.history['accuracy'])
plt.plot(hist.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Validation'], loc='best')
plt.grid()
plt.show()

#손실 함수 그래프
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Validation'], loc='best')
plt.grid()
plt.show()

신경망을 C-P-C-P-C-FC-FC 순서로 층을 쌓아 LeNet-5와 가급적 비슷한 구조로 설계한다.

 

데이터셋을 준비할 때 2차원맵을 1차원으로 변환해야 하므로 reshape(60000,784)를 사용했는데

여기서는 2차원 맵을 그대로 입력해야 하므로 reshape(60000,28,28,1)을 사용한다.

 

정확률은 99.17%이며, 학습 곡선을 보면 수렴도 훨씬 빠르다.

padding인자는 'SAME'이나 'VALID'로 설정할 수 있으며, 이 둘의 차이는 다음과 같다.
'VALID': 합성곱층에 zero-padding을 사용하지 않는다. 그렇기 때문에 합성곱 연산을 통해 이미지의 데이터 손실이 일어난다.
'SAME' : 합성곱층에 zero-padding을 사용하며, 이 경우에는 출력 특성맵의 크기는 입력을 스트라이드로 나눈 다음 올림 한 것과 같다(ceil(13/5)=3).
출처: https://excelsior-cjh.tistory.com/180 [EXCELSIOR]

 

 

 

 


참고교재 파이썬으로 만드는 인공지능 - 한빛미디어