Data Augmentation Tips

1. Albumentations Library

특장점

  • 다양한 Augmentation 기법 및 빠른 속도로 augmentation pipeline을 구성할 수 있는 오픈 소스 라이브러리

  • Kaggle Master들이 작성한 라이브러리로 Kaggle, topcoder, CVPR, MICCAI의 많은 컴피이션에서 활발히 사용 중

  • 다양한 Pixel 레벨 변환 및 Spatial 레벨 변환을 지원하며, 확률적으로 augmentation 여부를 선택할 수 있고OneOf block으로 선택적으로 augmentation 방법을 선택 가능

Benchmarking

  • Intel Xeon Platinum 8168 CPU에서 ImageNet 검증셋의 2,000개 이미지에 대한 벤치마킹 수행

  • 아래 표는 단일 코어에서 처리하는 초당 이미지 수로 albumentation이 대부분의 transform에서 2배 이상 빠름

Code Snippets

How to use

torchvision_transform = transforms.Compose([
    transforms.Resize((256, 256)), 
    transforms.RandomCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
])

# Same transform with torchvision_transform
albumentation_transform = albumentations.Compose([
    albumentations.Resize(256, 256), 
    albumentations.RandomCrop(224, 224),
    albumentations.HorizontalFlip(), # Same with transforms.RandomHorizontalFlip()
    albumentations.pytorch.transforms.ToTensor()
])

img = img[:,:,np.newaxis]
img = np.repeat(img, 3, axis=2)
torchvision_img = torchvision_transform(img)
albumentation_img = albumentation_transform(image=img)['image']

Probability Calculation

  • p1p_1: augmentation 적용 여부 판단 (1일 경우에는 항상 augmentation 적용)

  • p2p_2: 90도 회전 여부 결정

  • p3p_3: OneOf 블록 적용 여부 결정 (블록 내 모든 확률을 1로 정규화한 다음, 정규화한 확률에 따라 augmentation 선택)

    • 예: IAAAdditiveGaussianNoise의 확률이 0.9이고 GaussNoise의 확률이 0.6이면 정규화 후에는 각각 0.6과 0.4로 변경됨

      • 0.6=(0.9/(0.9+0.6)),0.4=(0.9/(0.9+0.6))0.6 = (0.9 / (0.9 + 0.6)), 0.4 = (0.9 / (0.9 + 0.6))

  • 각 augmentation은 아래와 같은 확률이 적용됨

    • RandomRotate90: p1p2p_1 * p_2

    • IAAAdditiveGaussianNoise: p1p30.6p_1 * p_3 * 0.6

    • GaussianNoise: p1p30.4p_1 * p_3 * 0.4

2. CutMix

Background

  • Cutout: 훈련 이미지에서 일부 영역을 검은 색 픽셀 및 랜덤 노이즈 패치로 오버레이하여 제거 → 일부 경우에 잘 동작하지만 작은 object나 중요한 영역에 대한 정보 손실이 많이 발생하는 문제

  • Mixup: 이미지와 정답 레이블의 선형 보간(linear interpolation)을 통해 두 개의 샘플을 혼합 → 지나친 smoothing 효과로 object detection에서 그리 좋지 않음

  • CutMix: 두 이미지의 정보를 모두 살려 보자는 취지

Algorithm

  • 먼저, 훈련 이미지, 클래스, 각 클래스에 해당하는 훈련 샘플을 아래와 같이 정의하면,

(x,y):Training image, label(A,B):Training class(xA,yA),(xB,yB):Training sample(x, y): \text{Training image, label} \\ (A, B): \text{Training class} \\ (x_A, y_A), (x_B, y_B): \text{Training sample}
  • 두 개의 샘플 이미지인 (xA,yA),(xB,yB)(x_A, y_A), (x_B, y_B)를 사용하여 새로운 샘플 (x~,y~)(\tilde{x}, \tilde{y})를 생성할 수 있다.

    (\odot: element-wise multiplication)

x~=MxA+(1M)xBy~=λyA+(1λ)yB\tilde{x} = \mathrm{M} \odot x_A + (1 - \mathrm{M}) \odot x_B \\ \tilde{y} = \lambda{y_A} + (1 - \lambda)y_B
  • MM: 0이나 1로 표현되는 WHW*H 차원의 binary mask 영역으로 어느 부분을 mix할 것인지 결정

    • MM의 영역은 λ\lambda파라메터에 의해 결정되며, 두 이미지에서 잘라낼 영역을 알려 주는 bounding box 좌표 B를 가져와서 샘플링

    • xA,xBx_A, x_B라는 이미지가 있을 때, xAx_A내의 특정 bounding box 영역을 xBx_B 이미지로부터 가져와서 붙임

    • 즉, xAx_A의 bounding box 영역 B가 제거(crop)되고 그 영역은 xBx_B 의 bounding box B에서 잘린 패치로 대체됨(paste).

  • λ\lambda: mixing ratio로 베타 분포에 의해 결정

  • 이를 수식으로 표현하면 아래와 같다.

B:Bounding box coordinates (rx,ry,rw,rh)rxUnif (0,W),rw=W1λ,ryUnif (0,H),rh=H1λ\mathrm{B}: \text{Bounding box coordinates } (r_x, r_y, r_w, r_h) \\ r_x \sim \text{Unif }(0, W), r_w = W\sqrt{1-\lambda}, \\ r_y \sim \text{Unif } (0, H), r_h = H\sqrt{1-\lambda}
  • rx,ryr_x, r_y는 bounding box 중심 좌표이며, uniform distribution에 의해 결정됨

  • rw,rhr_w, r_h는 bounding box의 너비 및 높이로, 이 수식을 통해 cropped area ratio 1λ1-\lambda는 아래와 같이 계산할 수 있다.

  • rwrhWH=1λ\dfrac{r_w r_h}{WH} = 1 - \lambda

Code Snippets

Bounding box 좌표 생성

실제 호출 예시 (Kaggle Bangali.ai Handwritten recognition)

References

Last updated