Fashion MNIST 데이터 Set을 불러온 후, 특성 데이터를 Convolution Layer가 기대하는 3차원 배열로 변환한다.
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
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)
① Sequential 클래스의 객체를 만들고, 첫번째 Convolution Layer인 Conv2D 클래스를 추가한다.
model = keras.Sequential()
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu', padding='same', input_shape=(28, 28, 1)))
② Pooling Layer를 추가한다.
model.add(keras.layers.MaxPooling2D(2))
③ 다음으로, 두번째 Convolution-Pooling Layer를 추가해보기로 하겠다.
model.add(keras.layers.Conv2D(64, kernel_size=2, activation='relu', padding='same'))
model.add(keras.layers.MaxPooling2D(2))
④ 밀집층에서 클래스별 확률을 계산할 수 있도록, 3차원 특성 맵을 Flattening 한다.
model.add(keras.layers.Flatten())
⑤ 과대 적합을 방지하기 위해 은닉층과 출력층 사이에 Dropout을 적용한다.
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dropout(0.4))
model.add(keras.layers.Dense(10, activation='softmax'))
⑥ summary()
메서드를 통해 완성된 모델의 구조를 확인해보자.
3 X 3 X 32 + 32 = 320
으로 계산된다.model.summary()
⑦ summary()
대신 plot_model()
메서드를 사용할 수도 있다.
keras.utils.plot_model(model)
⑧ show_shapes 매개변수를 사용하여 입력과 출력의 크기를 표시할 수도 있다.
keras.utils.plot_model(model, show_shapes=True)
① Adam Optimizer와 ModelCheckpoint 및 EarlyStopping Callbak을 적용하여 모델을 컴파일하고 훈련시킨다.
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-cnn-model.keras', save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)
result = model.fit(train_scaled, train_target, epochs=20, validation_data=(val_scaled, val_target), callbacks=[checkpoint_cb, early_stopping_cb])
② 조기 종료가 잘 이루어진 것인지 확인해보기 위해, Loss Curve를 그려보자.
import matplotlib.pyplot as plt
plt.plot(result.history['loss'])
plt.plot(result.history['val_loss'])
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend(['Train', 'Validataion'])
plt.show()
③ 이번에는 검증 Set에서의 성능을 확인해보자.
model.evaluate(val_scaled, val_target)
④ predict()
메서드를 사용해 모델의 예측을 확인해보기 위해 먼저는 첫번째 Sample의 이미지를 출력해보자.
plt.imshow(val_scaled[0].reshape(28, 28), cmap='gray_r')
plt.show()
⑤ 10개의 클래스에 대한 예측 확률을 출력해보자.
preds = model.predict(val_scaled[0:1])
print(preds)
⑥ 출력 결과를 막대 그래프로 그려보면 아래와 같다.
plt.bar(range(1, 11), preds[0])
plt.xlabel('Class')
plt.ylabel('Prob')
plt.show()
⑦ 마지막으로 테스트 Set에서의 성능을 평가해보자.
test_scaled = test_input.reshape(-1, 28, 28, 1) / 255
model.evaluate(test_scaled, test_target)