본문 바로가기
컴퓨터비전/CNN

[딥러닝] 데이터 증강(Data Augmentation)

by PIAI 2022. 3. 14.

데이터 증강(Data Augmentation)이해

 

CNN 모델의 성능을 높이고 오버피팅을 극복할 수 있는 가장 좋은 방법은 다양한 유형의 학습 이미지 데이터 양을 늘리는 것입니다. 하지만 이미지 데이터의 경우 학습 데이터 량을 늘리는 것은 쉽지가 않습니다. 데이터 증강(Data Augmentation)은 학습 이미지의 개수를 늘리는 것이 아니고 학습 시 마다 개별 원본 이미지를 변형해서 학습하는 것입니다.

https://albumentations.ai/docs/introduction/image_augmentation/

ImageDataGenerator(Keras)

 

import cv2
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing.image import ImageDataGenerator

#cv2.imread는 이미지를 RGB가 아닌 BGR로 받아오기 때문에 바꿔 주어야함.
image = cv2.cvtColor(cv2.imread('test.jpg'), cv2.COLOR_BGR2RGB)
plt.imshow(image)

원본 이미지

#augmentation이 적용된 image들을 시각화 해주는 함수
def show_aug_image(image, generator, n_images=4):
	
    # ImageDataGenerator는 여러개의 image를 입력으로 받기 때문에 4차원으로 입력 해야함.
    image_batch = np.expand_dims(image, axis=0)
	
    # featurewise_center or featurewise_std_normalization or zca_whitening 가 True일때만 fit 해주어야함
    generator.fit(image_batch) 
    # flow로 image batch를 generator에 넣어주어야함.
    data_gen_iter = generator.flow(image_batch)

    fig, axs = plt.subplots(nrows=1, ncols=n_images, figsize=(24, 8))

    for i in range(n_images):
    	#generator에 batch size 만큼 augmentation 적용(매번 적용이 다름)
        aug_image_batch = next(data_gen_iter)
        aug_image = np.squeeze(aug_image_batch)
        aug_image = aug_image.astype('int')
        axs[i].imshow(aug_image)
data_generator = ImageDataGenerator(horizontal_flip=True)
show_aug_image(image, data_generator, n_images=4)

horizontal_flip 적용

data_generator = ImageDataGenerator(vertical_flip=True)
show_aug_image(image, data_generator, n_images=4)

vertical_flip 적용

data_generator = ImageDataGenerator(horizontal_flip=True, vertical_flip=True)
show_aug_image(image, data_generator, n_images=4)

horizontal + vertical 적용

data_generator = ImageDataGenerator(rotation_range=45)
show_aug_image_batch(image, data_generator, n_images=4)

rotation -45 ~ 45도

data_generator = ImageDataGenerator(width_shift_range=0.4, fill_mode='nearest')
show_aug_image_batch(image, data_generator, n_images=4)

width_shift_range=0.4, fill_mode='nearest'

data_generator = ImageDataGenerator(width_shift_range=0.4, fill_mode='reflect')
show_aug_image_batch(image, data_generator, n_images=4)

width_shift_range=0.4, fill_mode='reflect'

data_generator = ImageDataGenerator(width_shift_range=0.4, fill_mode='wrap')
show_aug_image_batch(image, data_generator, n_images=4)

width_shift_range=0.4, fill_mode='wrap'

data_generator = ImageDataGenerator(width_shift_range=0.4, fill_mode='constant', cval=0)
show_aug_image_batch(image, data_generator, n_images=4)

width_shift_range=0.4, fill_mode='constant', cval=0

data_generator = ImageDataGenerator(shear_range=45)
show_aug_image_batch(image, data_generator, n_images=4)

shear -45 ~ 45

data_generator = ImageDataGenerator(zoom_range=[0.5, 0.9])
show_aug_image_batch(image, data_generator, n_images=4)

zoom_range 0.5 ~ 0.9

data_generator = ImageDataGenerator(zoom_range=[1.1, 1.5], fill_mode='constant', cval=0)
show_aug_image_batch(image, data_generator, n_images=4)

zoom_range 1.1 ~ 1.5, fill_mode='constant', cval=0

data_generator = ImageDataGenerator(brightness_range=(0.1, 0.9))
show_aug_image_batch(image, data_generator, n_images=4)

brightness_range 0.1 ~ 0.9

data_generator = ImageDataGenerator(brightness_range=(1.0, 1.0))
show_aug_image_batch(image, data_generator, n_images=4)

brightness_range 1.0

data_generator = ImageDataGenerator(brightness_range=(1.0, 2.0))
show_aug_image_batch(image, data_generator, n_images=4)

brightness_range 1.0 ~ 2.0

data_generator = ImageDataGenerator(channel_shift_range=150)
show_aug_image_batch(image, data_generator, n_images=4)

channel_shift_range 150

data_generator = ImageDataGenerator(
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    brightness_range=(0.7, 1.3),
    horizontal_flip=True,
    vertical_flip=True,
    #rescale=1/255.0 # 학습시 적용, 시각화를 위해 임시로 주석처리
)

show_aug_image_batch(image, data_generator, n_images=4)

여러가지 augmentation을 적용한 경우(일반적)

 

위의 그림들을 보면 적용이 된 그림도 있고 되지 않은 그림도 있습니다. 아무것도 적용이 되지 않은 그림은 원본 이미지와 같습니다. 그렇다고 이것이 나쁜것만은 아닙니다. 데이터를 학습할때 원본의 이미지가 하나도 없으면 학습이 잘 되지 않습니다. 위와 같이 keras의 ImageDataGenerator는 확률이 랜덤하게 적용됩니다. 

 

 

위의 그림을 보면 Augmentation 적용후 빈공간이 있습니다. 이 빈공간을 어떻게 채울지 결정해 주어야 합니다. fill_node의 파라미터로 입력을 받으며 디폴트는 nearest 입니다. 

  • nearest: 주변 환경 그대로 가져옴
  • reflect: 거울 모드로 가져옴
  • wrap: 잘린 부분을 채움
  • constant: cval 파라미터 값으로 채움 (0 ~ 255, 0에 가까울수록 어두워진다.)

ImageDataGenerator 변환 유형

Flip

  • 좌우 반전: horizontal_flip = True
  • 상하 반전: vertical_flip = True

Rotation

  • rotation_range = x
  • 임의의 -x ~ +x 사이 회전
  • 빈 공간은 fill_mode로 채워짐, default는 nearest

Zoom

  • zoom_range = [0.5, 1.5]
  • 1보다 작은 값은 확장
  • 1보다 큰 값은 축소(빈 공간은 fill_mode로 채워짐, default는 nearest)

Shift

  • 좌우 이동: width_shift_range = 0.2
  • 상하 이동: height_shift_range = 0.2
  • 0~1사이 값
  • 빈 공간은 fill_mode로 채워짐, default는 nearest

Shear

  • shear_range = 45
  • X축 또는 y축 중심으로 0~45도 사이 변환

Bright

  • brightness_range = (0.1, 0.9)
  • 밝기 조절, 0~1사이 값 입력, 0에 가까울수록 어둡고, 1에 가까울수록 밝음

Channel Shift

  • channel_shift_range = x
  • R, G, B Pixel값을 -x ~ x 사이의 임의의 값을 더하여 변환, 0보다 작으면 0, 255보다 크면 255로 초기화

Normalization

  • featurewise_center=True, 각 R, G, B Pixel 값에서 개별 채널 별 평균 Pixel값을 빼서 평균이 0이 되게 유지
  • featurewise_std_normalization=True 각 R, G, B Pixel값에서 개별 채널 별 표준 편차 Pixel값을 나눈다.
  • rescale = 1/255.0. 딥러닝은 입력이 비교적 작은 값을 선호하므로 0~255 -> 0~1

 

댓글