본문 바로가기

AI: ML,DL

[인공지능] 합성곱 신경망을 활용한 이미지 분류

합성곱 신경망 구축

앞선 포스팅에서 학습한 합성곱 신경망을 직접 구축해보자.

from tensorflow import keras
from sklearn.model_selection import train_test_split
(train_input,train_target),(test_input,test_target) =\
keras.datasets.fashion_mnist.load_data()
train_scaled = train_input.reshape(-1,28,28,1)/255.0 #깊이 1 차원 추가
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled,train_target,test_size=0.2,random_state=42)

model = keras.Sequential()
#32개의 가로세로 3x3 필터, 렐루, 동일 패딩; 최대풀링 2X2 => 최종 특성맵(14,14,32)
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu',padding='same',input_shape=(28,28,1)))
model.add(keras.layers.MaxPooling2D(2))
#64개의 가로세로 3x3 필터, 렐루, 동일 패딩; 최대풀링 2X2 => 최종 특성맵(7,7,64)
model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu',padding='same',input_shape=(28,28,1)))
model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(100,activate='relu'))
model.add(keras.layers.Dropout(0.4)) #과대적합 방지
model.add(keras.layers.Dense(10,activate='softmax'))

model.summary()

모델을 파라미터 계산 결과를 검증해보자.

첫 번째 합성곱 층은 32개의 (3,3,1) 필터를 가지고 있고, 필터마다 절편이 한개씩 존재한다. 그 결과 3x3x1x32+32=320개의 파라미터가 존재한다. 두 번째 합성곱 층은 64개의 (3,3,32) 필터를 가지고 있고, 마찬가지로 절편이 한개씩 존재한다. 그 결과 3x3x32x64+64=18,496개의 파라미터가 존재한다. Flatten을 통해 (7,7,64)인 3차원 배열을 1차원으로 펼쳐 (3136,)이 된다.  이를 다음 밀집층인 100개의 뉴런과 연결하고 절편이 뉴런 당 한개씩 존재하므로 3136x100+100=313,700개의 파라미터가 존재한다. 마지막 밀집층은 10개의 뉴런이 존재하고 이전 100개의 뉴런과 연결되므로 100x10+10=1010개의 파라미터가 존재하게 된다.

 

추가로, 다음과 같이 plot_model() 메서드를 통해 전체 구조를 볼 수 있다.

 

모델 컴파일과 훈련

케라스  API는 딥러닝 모델에 관계 없이 컴파일 및 훈련 과정이 같다고 소개했다. 기존 신경망과 동일하게 옵티마이저와 콜백을 적절히 정의해주어 구현한다.

model.compile(optimizer='adam',loss='sparse_categorical_crossentropy', metrics='accuracy')
cp_cb = keras.callbacks.ModelCheckpoint('best-cnn-model.h5')
es_cb = keras.callbacks.EarlyStopping(patience=2,restore_best_weights=True)
history = model.fit(train_scaled,train_target,epochs=20,validation_data=(val_scaled,val_target),callbacks=[cp_cb,es_cb])

 

import matplotlib.pyplot as plt
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train','val'])
plt.show()

훈련세트와 검증세트 지속적으로 감소하다가 검증세트가 두번 연속 증가하는 11 에포크에서 중지되어 9 에포크에서 최상의 모델을 저장한다.

 

샘플 예측

실제로 샘플 이미지를 검증 세트에서 한개 추출하여 모델을 통해 예측한 결과를 확인해보자.

import numpy as np

plt.imshow(val_scaled[0].reshape(28,28), cmap='gray_r')
plt.show()

preds = model.predict(val_scaled[0:1])
print(preds)

plt.bar(range(1,11),preds[0])
plt.xlabel('class')
plt.ylabel('prob')
plt.show()

classes = ['티셔츠','바지','스웨터','드레스','코트','샌달','셔츠','스니커즈','가방','앵클부츠']
print(classes[np.argmax(preds)]) # 가방

가방으로 실제 잘 예측한 모습이다.

 

실제 실전에 투입할 경우 성능을 예측하기 위해 훈련 세트에 대해 평가해보자.

test_scaled = test_input.reshape(-1,28,28,1) / 255.0
model.evaluate(test_scaled,test_target)
# [0.23752424120903015, 0.9192000031471252]

약 91%의 성능을 기대할 수 있다.

 

 

참고

  • 혼자 공부하는 머신러닝+딥러닝(박해선 저)