기억의 기록(나의 기기)

[Data Augmentation] 예제를 통한 데이터 증강 효과 설명 본문

딥러닝

[Data Augmentation] 예제를 통한 데이터 증강 효과 설명

황경하 2024. 6. 24. 14:09
반응형

Data Augmentation

안녕하세요, 데이터 과학을 공부하고 있는 황경하입니다.
오늘은 이전 포스팅에서 강아지, 고양이, MNIST 이미지를 증강하는 기법을 설명하였는데요. 글이 길어질 것 같아 그 효과를 설명하지 못했었습니다. 그래서 오늘은 데이터 증강 효과를 예제를 통해 보여드리겠습니다.
이번에도 Google Colab 환경에서 작업하였습니다.
코드: https://colab.research.google.com/drive/1lZdegtB7uyrTXlzVxLr8dXl38yC_1bYl?usp=sharing

 

[Data Augmentation] 강아지, 고양이, MNIST 예시를 통한 설명

Colab notebook

colab.research.google.com

Without Data Augmentation Layer

 

데이터를 다운로드하고 데이터셋으로 만드는 과정은 이전 포스팅을 참고해 주세요!
그러면, 바로 CNN 모델을 만들고 학습시켜 보겠습니다. 함수형 API로 모델을 생성합니다.
plot_model 함수를 통해 신경망 구조를 시각적으로 확인할 수 있습니다.

from tensorflow import keras
from keras.layers import Conv2D, MaxPooling2D, Rescaling, Flatten, Dense
from
 keras.utils import plot_model

def build_model(input_shape, num_out):
  inputs = keras.Input(shape = input_shape)
  x = Rescaling(1./255)(inputs)
  x = Conv2D(filters=32, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=64, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=128, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=256, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=256, kernel_size=3, activation="relu")(x)
  x = Flatten()(x)
  outputs = Dense(num_out, activation="sigmoid")(x)
  model = keras.Model(inputs=inputs, outputs=outputs)
  return model
model = build_model((180,180,3), 1)
plot_model(model, show_shapes = True, show_layer_activations=True)

 
모델을 만들었으니, 이제 학습 환경을 만들어보죠.

  • 중요한 건, loss를 'binary_crossentropy'로 설정해야 한다는 것입니다. optimizer는 다른 알고리즘으로 변경되어도 되지만, 현재 다루는 데이터가 이진분류이기에 binary_crossentropy로 설정합니다.
model.compile(optimizer = 'rmsprop', loss = 'binary_crossentropy', metrics = 'accuracy')

 
이제 모델을 학습시키고 그 결과를 그래프로 확인해 봄으로써, 우리가 예상하는 결과인 과대적합이 일어나는지 확인해 보죠. callback을 설정하고, history에 훈련 결과를 담아 시각화합니다.

callbacks = keras.callbacks.ModelCheckpoint(
    filepath="convnet_from_scratch.h5",
    save_best_only=True,
    monitor="val_loss")
history = model.fit(
    train_dataset,
    epochs=30,
    validation_data=validation_dataset,
    callbacks=callbacks)
import matplotlib.pyplot as plt
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()

위 사진처럼 약 10 에폭부터 급격히 loss가 증가함을 보면, overfitting이 심각하게 일어나고 있음을 알 수 있습니다. 그렇다고, 10 에폭에서 학습을 멈추기에는 정확도가 80프로도 되지 않죠. 이런 경우에 우리는 데이터 증강 기법을 활용할 수 있습니다.

With Data Augmentation Layer

데이터 증강층을 삽입하여 신경망을 다시 구성해 보죠. Dropout 층과 Data Augmentation층이 추가되었습니다.

from keras.layers import Dropout

def build_model(input_shape, num_out):
  inputs = keras.Input(shape=(180, 180, 3))
  x = data_augmentation(inputs)
  x = Rescaling(1./255)(x)
  x = Conv2D(filters=32, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=64, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=128, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=256, kernel_size=3, activation="relu")(x)
  x = MaxPooling2D(pool_size=2)(x)
  x = Conv2D(filters=256, kernel_size=3, activation="relu")(x)
  x = Flatten()(x)
  x = Dropout(0.5)(x)
  outputs = Dense(num_out, activation="sigmoid")(x)
  model = keras.Model(inputs=inputs, outputs=outputs)
  return model

model = build_model((180,180,3), 1)
plot_model(model, show_shapes = True, show_layer_activations=True)

 
이제 위에서 한 것처럼 학습 환경을 구성하고 학습을 시키되 overfitting이 일어나지 않음을 확인하기 위해 아까보다 epoch을 확 올려보겠습니다. 그리고 위에서 한 것처럼 history에 결과를 저장하여 시각화해 보겠습니다.

model.compile(loss="binary_crossentropy",
              optimizer="rmsprop",
              metrics=["accuracy"])

callbacks = [keras.callbacks.ModelCheckpoint(
    filepath="convnet_from_scratch_with_augmentation.h5",
    save_best_only=True,
    monitor="val_loss")]

history = model.fit(
    train_dataset,
    epochs=100,
    validation_data=validation_data
import matplotlib.pyplot as plt
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()

 

증강 후 정확도는 계속 증가하고 있고, loss는 계속 낮아지고 있죠. 데이터 증강층을 넣기 전에는 약 10 에폭만에 overfitting이 일어났는데 증강층을 넣으니 100 에폭을 진행해도 overfitting이 일어나지 않습니다. 또한, 정확도도 약 10% 넘게 증가했네요. 이것이 데이터 증강의 힘입니다!

마치며..

이렇게 데이터 증강 효과까지 살펴봤습니다. 제가 학업에서 배웠던 내용을 이해한 것을 토대로 작성해 보았는데요. 데이터 증강에 관심이 있었던 분들에게 도움이 되었으면 좋겠습니다. 또한, 데이터 증강은 이미지 데이터뿐 아니라 일반적인 측정 데이터도 가능하다고 하는데 그 부분은 더 공부해봐야 할 것 같습니다. 조만간 그 내용을 다뤄서 포스팅해 보겠습니다.
오늘도 읽어주셔서 감사합니다!

반응형