📌 Intro
MNIST 데이터 셋을 이용하여 ANN(DNN) 모델을 구성, 학습, 정확도 측정까지 진행해보았다. 이번에는 모델의 layer를 더 깊게 만들어보고 정확도를 비교해보도록 하자.
또 CNN모델을 만들어 학습, 정확도를 측정하여 ANN모델과의 정확도를 비교해보도록 하자. MNIST를 사용하는 방법과 CNN에 대한 내용은 이전에 정리해두었기 때문에 바로 코드를 보며 간단한 주석과 함께 내용을 정리할 것이다.
📌 DNN 코드
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 1. MNIST 데이터 셋 import
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 2. 모델 구성
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(512, activation=tf.nn.relu),
tf.keras.layers.Dense(256, activation=tf.nn.relu),
tf.keras.layers.Dense(128, activation=tf.nn.relu),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
# 3. 모델 컴파일
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 4. 모델 요약
model.summary()
# 5. 모델 훈련
history = model.fit(x_train, y_train, validation_split=0.1, epochs=5)
# 6. 훈련 과정 확인
train_accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']
train_loss = history.history['loss']
val_loss = history.history['val_loss']
plt.plot(list(range(5)), train_accuracy, 'b', label='Training accuracy')
plt.plot(list(range(5)), val_accuracy, 'r', label='Validation accuracy')
plt.title("Training and validation accuracy")
plt.legend()
plt.show()
plt.figure()
plt.plot(list(range(5)), train_loss, 'b', label='Training loss')
plt.plot(list(range(5)), val_loss, 'r', label='Validation loss')
plt.title("Training and validation loss")
plt.legend()
plt.show()
# 7. 모델 평가
test_loss, test_acc = model.evaluate(x_test, y_test) print("Accuracy : ", test_acc)
📌 DNN 코드 설명
4. 모델 요약
모델 요약에 대한 출력 화면이다. 이전 모델보다 layer가 2층 더 깊어졌고, 학습되는 파라미터가 약 40만개에서 50만개로 많아진 것을 확인할 수 있다.
5. 모델 훈련
이전 모델과 같이 에포크는 5, validation_split은 0.1로 설정하였다. 에포크 수를 늘리면 일반적으로 정확도가 올라가지만 항상 그렇지만은 않다. 과적합(Overfitting)이 생기는 이유때문인데 이에 대해서는 나중에 더 자세하게 정리해야겠다.
6. 훈련 과정 확인
7. 모델 평가
새로 만든 모델의 정확도를 테스트해본 결과 97.46%가 나온 것을 확인할 수 있다.
📌 CNN 전체 코드
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 1. MNIST 데이터 셋 import
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# normalization
x_train, x_test = x_train/255.0, x_test/255.0
# (60000, 28, 28) -> (60000, 28, 28, 1)로 reshape
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
# 2. 모델 구성
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(kernel_size=(3,3), filters=64, input_shape=(28,28,1), padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=(3,3), filters=64, padding='same', activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=(2,2)),
tf.keras.layers.Conv2D(kernel_size=(3,3), filters=128, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=(3,3), filters=256, padding='valid', activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=(2,2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(units=512, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(units=256, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(units=10, activation='softmax')
])
# 3. 모델 컴파일
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
# 4. 모델 훈련 (gpu 사용)
with(tf.device("device:GPU:0")):
history = model.fit(x_train, y_train, epochs=5, validation_split=0.1)
# 5. 훈련과정 확인
print(history.history.keys())
train_accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']
train_loss = history.history['loss']
val_loss = history.history['val_loss']
plt.plot(list(range(5)), train_accuracy, 'b', label='Training accuracy')
plt.plot(list(range(5)), val_accuracy, 'r', label='Validation accuracy')
plt.title("Training and validation accuracy")
plt.legend()
plt.show()
plt.figure()
plt.plot(list(range(5)), train_loss, 'b', label='Training loss')
plt.plot(list(range(5)), val_loss, 'r', label='Validation loss')
plt.title("Training and validation loss")
plt.legend()
plt.show()
# 6. 모델 평가
loss, accuracy = model.evaluate(x_test, y_test)
print("Accuracy: ", accuracy)
📌 CNN 코드 설명
2. 모델 구성
tf.keras.layers.Conv2D() 함수를 이용하여 합성곱 신경망 층을 추가할 수 있다. 여러가지 인자를 통해서 파라미터를 정할 수 있는데 3 x 3 크기의 필터를 사용하고, 필터의 개수는 64개로 설정했다. 필터의 크기와 개수는 개인에 따라 변경해도 되지만 input_shape은 MNIST 데이터 셋이 28 x 28 x 1 이기 때문에 이에 맞게 설정해주어야 한다.
tf.keras.layers.MaxPool2D() 함수를 사용하여 맥스 풀링 레이어를 추가할 수 있고, 사이즈는 2 x 2로 설정하였다.
tf.keras.layers.Flatten() 함수를 이용하여 다차원의 피처 맵을 평평하게 펴주도록 한다. 위 그림에서 flatten 레이어를 살펴보면 Output Shape이 9216(256 x 6 x 6)인 것을 확인할 수 있다.
tf.keras.layers.Dense() 함수를 이용하여 합성곱 이후에 classification을 위한 다층 신경망을 구성해준다.
tf.keras.layers.Dropout(0.5) 함수는 Fully Connected Layer에서 주로 사용하는 방법인데 전체 weight 중 다음 신경망으로 가는 weight의 비율을 조절하는 것이다. 이를 통해 과적합을 방지할 수 있고 이 역시 다음에 정리해두도록 하겠다.
전체적으로 보면 DNN보다는 확실히 많은 layer와 파라미터를 사용한다. 때문에 한 에포크당 학습시간도 굉장히 오래걸릴 수 있다.(각자 환경에 따라 다를 수 있다.)
5. 훈련과정 확인
6. 모델 평가
CNN 모델의 성능은 확실히 DNN보다 좋은 것을 볼 수 있다. 아무래도 MNIST 데이터 셋이 이미지이다 보니 CNN이 더 좋은 성능을 보이는 것 같고 차이가 고작 1% 내외라고 생각할 수 있지만 실제로 인공지능 분야에서 1%의 성능 차이는 굉장하다고 볼 수 있다.