데이터 분석가
article thumbnail
Published 2023. 8. 30. 22:46
CNN_데이터 증식 DeepLearning

이전 내용 확인

  • 이번 글에서는 이전 블로그에 이어 훈련데이터가 적어 과대적합이 발생하는 문제를 해결하기 위해 데이터 증식에 대해 다뤄보고자 합니다.

교재 홍보

 

케라스 창시자에게 배우는 딥러닝 개정 2판 - 예스24

단어 하나, 코드 한 줄 버릴 것이 없다!단 한 권의 딥러닝 책을 선택한다면 바로 이 책이다!케라스 창시자이자 구글 딥러닝 연구원인 저자는 ‘인공 지능의 민주화’를 강조한다. 이 책 역시 많

www.yes24.com

 

1. 데이터 증식 층 정의

  • 훈련 데이터가 부족하기 때문에 이를 해결하기 위해 이미지에 여러 가지 랜덤한 변환을 적용하여 샘플을 늘려주는 데이터 증식 층을 정의합니다. 이 층은 후에 컨브넷 모델을 생성할 때 적용될 것입니다.
data_augmentation = keras.Sequential([
    layers.RandomFlip('horizontal'), # 랜덤하게 이미지를 수평으로 뒤집는다.
    layers.RandomRotation(0.1), # +-10% 범위에서 랜덤하게 이미지를 회전합니다.
    layers.RandomZoom(0.2) # 20% 범위에서 랜덤하게 이미지를 확대 또는 축소합니다.
])

 

2. 증식 층에 이미지 넣기

  • 정의한 증식 층에 이미지를 넣으면 아래처럼 하나의 이미지가 랜덤하게 변환된 것을 볼 수 있습니다.
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1): # 훈련 Dataset 객체에서 take(1)을 사용하여 1개의 배치를 샘플링합니다.
    for i in range(9):
        augmented_images = data_augmentation(images) # 증식층에 1개의 배치 이미지를 넣어 변환된 이미지를 얻습니다.
        ax = plt.subplot(3, 3, i + 1)
        plt.imshow(augmented_images[0].numpy().astype("uint8"))
        plt.axis("off")

 

3. 모델 생성

  • 앞에서 말한대로 데이터 증식 층을 적용한 모델을 생성하겠습니다.
  • 이때, 데이터 증식은 기존 데이터의 재조합이기 때문에 과대적합을 제거하기 충분하지 않을 수도 있으므로 Dropuout층을 통해 신경망 내의 뉴런 연결을 임시로 끊음으로써 과대적합을 억제하는 데 기여하도록 하겠습니다.
inputs = keras.Input(shape=(180, 180, 3)) # 입력층
x = data_augmentation(inputs) # 데이터 증식 단계 통과
x = layers.Rescaling(1./255)(x) # 이미지 [0, 1]

# 은닉층
x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.Flatten()(x)
x = layers.Dropout(0.5)(x) # 드롭아웃을 적용하면 과대적합이 덜 일어난다.

# 출력층
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)

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

 

4. 모델 훈련

  • 과대적합이 늦게 나타날 것이기 때문에 에포크 수를 늘려 모델을 훈련합니다.
  • 모델 평가에서 데이터 증식과 Dropout은 없는 것처럼 취급됩니다.
callbacks = [
    keras.callbacks.ModelCheckpoint(
        filepath="convnet_from_scratch_with_augmentation.keras",
        save_best_only=True,
        monitor="val_loss")
]

history = model.fit(
    train_dataset,
    epochs=100,
    validation_data=validation_dataset,
    callbacks=callbacks)

 

5. 손실과 정확도 그래프

  • vis함수를 이용해 그래프를 그려줍니다.
  • 결과를 보면 이전과 달리 데이터 증식과 드롭아웃의 영향으로 이전(10epochs)보다 과대적합이 훨씬 늦은 60~70번째 에포크에서 발생함을 볼 수 있습니다.
vis(history)

 

6. 모델 평가

  • callback을 통해 저장된 파일에서 모델을 로드하고 테스트 데이터셋으로 모델을 평가합니다.
  • 아래와 같이 정확도 또한 79.4%로 이전(69.5) 보다 더 개선된 정확도를 보이고 있습니다.
  • 하지만 데이터셋의 크기 자체가 작아 정확도 개선에 한계가 있으므로, 다음 글에서는  사전훈련된 모델로 정확도를 높이는 과정을 살펴보겠습니다.
test_model = keras.models.load_model("convnet_from_scratch_with_augmentation.keras") # callback을 통해 저장했던 모델을 불러옵니다.
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"테스트 정확도: {test_acc:.3f}")

'DeepLearning' 카테고리의 다른 글

CNN_데이터 증식  (0) 2023.09.01
CNN_사전훈련된 모델  (0) 2023.08.31
CNN_강아지 vs 고양이  (0) 2023.08.30
CNN_MNIST  (0) 2023.08.29
다중 분류 모델_Reuter  (0) 2023.08.29
profile

데이터 분석가

@이꾹꾹

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!