본문 바로가기

인공지능/DeepLearning

[Computer Vision] Image Augmentation

심층 신경망에서 데이터셋을 사용할 경우 대규모 데이터셋일수록 모델의 의존도를 줄일 수 있고, 이에 따른 일반화 능력이 향상된다. 따라서 심층 신경망의 성공적인 학습을 위해 동일한 이미지를 위치, 밝기, 색도와 같은 요소들을 무작위로 조절하면서 다양한 데이터를 만드는 것이다. 이러한 이미지 확대 기술은 심층 신경망의 성공에 크게 기여를 했으며, 이미지를 무작위로 변환해주는 작업은 다양한 모듈에서 제공을 해주고 있다.

def apply(img, aug, num_rows=2, num_cols=4, scale=1.5):
    Y = [aug(img) for _ in range(num_rows * num_cols)]
    d2l.show_images(Y, num_rows, num_cols, scale=scale)

%matplotlib inline
from d2l import torch as d2l
import torch
import torchvision
from torch import nn

실험에 필요한 기본적인 모듈이다. d2l의 경우 torch를 설치했음에도 별도로 추가 설치해주어야 한다.

 

학습에 필요한 데이터셋은 https://github.com/d2l-ai/d2l-en에서 다운로드하면 된다.

d2l.set_figsize()
img = d2l.Image.open('./img/cat1.jpg')
d2l.plt.imshow(img);

def apply(img, aug, num_rows=2, num_cols=4, scale=1.5):
    Y = [aug(img) for _ in range(num_rows * num_cols)]
    d2l.show_images(Y, num_rows, num_cols, scale=scale)

실질적인 명령어는 aug에 들어가게 되고 List Y을 생성할 때 aug(img)를 통해 변화된 이미지를 List의 크기만큼 저장한다.

show_images에 사용되는 scale은 이미지를 어느 정도의 크기로 확대해서 보여주는지를 의미한다.


이미지 뒤집기 - RandomHorizontalFlip(), RandomVerticalFlip()

apply(img, torchvision.transforms.RandomHorizontalFlip()) # Horizontal = 좌우반전
apply(img, torchvision.transforms.RandomVerticalFlip())   # Vertical   = 상하반전

torchvision.transforms.RandomHorizontalFlip()                              torchvision.transforms.RandomVerticalFlip()

RandomFlip의 경우 뒤집는 확률이 50%이다. Vertical보다는 상대적으로 Horizontal를 더 많이 사용한다.


이미지 잘라내기 - RandomResizedCrop()

shape_aug = torchvision.transforms.RandomResizedCrop(
    (200, 200), scale=(0.1, 1), ratio=(0.5, 2))
apply(img, shape_aug)

apply(img, shape_aug)

(200, 200)은 출력할 size를 조정해주는 부분이다.

scale(0.1, 1)은 면적의 비율 0.1~1 (10%~100%)를 무작위로 자르게 된다.

ratio(0.5, 2)은 면적의 너비와 높이의 비율 0.5~2를 무작위로 조절한다.

 

ratio를 통해 너비와 비율을 조절한 뒤 scale를 통해 자르고, 최종적으로 출력할 size로 조정을 한다.


색깔 바꾸기 - ColorJitter()

apply(img, torchvision.transforms.ColorJitter(brightness=0.5))   #밝기
apply(img, torchvision.transforms.ColorJitter(contrast=0.5))     #대비
apply(img, torchvision.transforms.ColorJitter(saturation=0.5))   #채도
apply(img, torchvision.transforms.ColorJitter(hue=0.5))          #색조

color_aug = torchvision.transforms.ColorJitter(
    brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5)
apply(img, color_aug)

apply(img, torchvision.transforms.ColorJitter(brightness=0.5))              apply(img, torchvision.transforms.ColorJitter(contrast=0.5))
apply(img, torchvision.transforms.ColorJitter(saturation=0.5))                        apply(img, torchvision.transforms.ColorJitter(hue=0.5))
apply(img, color_aug)

인자에서 0.5의 값은 1(100%)을 기준으로 +0.5~-0.5의 범위에서 무작위로 고르겠다는 의미이다.

즉 범위는 (1-0.5 ~ 1+0.5) -> (0.5 ~ 1.5)에서 무작위로 고르는 것이다.


이미지 처리 한 번에 합치기 - Compose()

augs = torchvision.transforms.Compose([
    torchvision.transforms.RandomHorizontalFlip(), color_aug, shape_aug])
apply(img, augs)

apply(img, augs)

원하는 이미지 처리를 Lsit 형식으로 모아서 Compose에 입력을 하면

Compose에서는 이미지 처리 모듈이 들어있는 List를 덮어 하나의 모듈로 합쳐준다.


ref. Dive into Deep Learning, Aston Zhang and Zachary C. Lipton and Mu Li and Alexander J. Smola, 2020