본문 바로가기
C.W.K.
Stream
Lesson 02 of 07 · published

이미지 증강: 무작위 자르기, 뒤집기, 색상, MixUp, CutMix

~14 min · augmentation, mixup, cutmix, regularization

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

증강은 데이터로 하는 정규화야

모델이 각 학습 이미지를 조금씩 변형한 모습으로 더 많이 볼수록 원본을 그대로 외우기 어려워지고 새로운 데이터에 더 잘 일반화해. 이미지 증강은 컴퓨터 비전에서 비용 대비 효과가 가장 큰 정규화 기법 중 하나야.

표준 이미지 증강

  • RandomResizedCrop: 무작위 크기와 가로세로비로 자른 뒤 고정된 출력 크기로 바꿔. ImageNet 학습의 표준 자르기 방식이야.
  • RandomHorizontalFlip(p=0.5): 자연 이미지에 널리 사용해.
  • RandomVerticalFlip: 위아래가 바뀌어도 의미가 유지되는 의료·위성·추상 이미지에만 사용해.
  • ColorJitter: 밝기, 대비, 채도, 색조를 무작위로 바꿔.
  • RandomRotation, RandomAffine: 작은 회전과 이동을 적용해.
  • RandomErasing: 무작위 직사각형 영역을 0으로 지워. Cutout이라고도 하며 놀랄 만큼 효과적이야.

배치 단위 증강: MixUp과 CutMix

두 이미지를 섞을 때 레이블도 같은 비율로 섞어, 모델이 혼합 정도에 맞는 부드러운 레이블을 예측하도록 해. 2020년 이후 ImageNet 기준선에 빠지지 않을 만큼 현대적인 이미지 분류 학습의 표준이 됐어.

  • MixUp: 베타 분포에서 뽑은 가중치 α로 두 이미지를 픽셀 단위에서 선형 보간해.
  • CutMix: 이미지 B의 직사각형 영역을 잘라 이미지 A에 붙여. 레이블은 붙인 영역의 넓이에 따라 가중해.

핵심 원칙

학습 변환에는 증강을 넣고, 검증·테스트 변환에는 결정적인 크기 조정과 정규화만 넣어. 검증 데이터를 무작위로 증강하면 측정 대상이 계속 바뀌어. 학습용과 검증용 파이프라인을 반드시 따로 만들어.

Code

학습 대 검증 변환: 절대 안 섞기·python
import torch
import torchvision.transforms.v2 as T

# TRAINING: includes augmentation
train_tf = T.Compose([
    T.ToImage(),
    T.ToDtype(torch.float32, scale=True),
    T.RandomResizedCrop(224, scale=(0.8, 1.0)),
    T.RandomHorizontalFlip(p=0.5),
    T.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.05),
    T.RandomRotation(15),
    T.RandomErasing(p=0.1),
    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# VALIDATION: deterministic only — resize, center-crop, normalize
val_tf = T.Compose([
    T.ToImage(),
    T.ToDtype(torch.float32, scale=True),
    T.Resize(256),
    T.CenterCrop(224),
    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
MixUp과 CutMix: 배치 별 적용·python
import torch
import torch.nn as nn
from torchvision.transforms.v2 import MixUp, CutMix, RandomChoice

mixup = MixUp(alpha=0.2, num_classes=10)
cutmix = CutMix(alpha=1.0, num_classes=10)

# Randomly pick one each batch
batch_aug = RandomChoice([mixup, cutmix])

# Loss: with mixed labels, use CE with soft targets
criterion = nn.CrossEntropyLoss()

for x, y in train_loader:
    x, y = batch_aug(x, y)               # y is now soft (probability over classes)
    out = model(x)
    loss = criterion(out, y)
    loss.backward()
변환한 이미지 한 장 살펴보기·python
import torch
import torchvision.transforms.v2 as T
from torchvision import tv_tensors

# Build a synthetic image
img = torch.randint(0, 255, (3, 224, 224), dtype=torch.uint8)

aug = T.Compose([
    T.ToImage(),
    T.ToDtype(torch.float32, scale=True),
    T.RandomResizedCrop(224, scale=(0.5, 1.0)),
    T.RandomHorizontalFlip(p=0.5),
])

# Apply twice — different random outcomes
out1 = aug(img)
out2 = aug(img)
print(torch.equal(out1, out2))   # False — random transforms differ each call

External links

Exercise

CIFAR-10용 학습 변환과 검증 변환 파이프라인을 만들어 봐. 같은 이미지에 각각 다섯 번 적용하면 학습 변환은 서로 다른 출력 다섯 개를, 검증 변환은 같은 출력 다섯 개를 만들어야 해. matplotlib로 2x5 격자에 저장해 두면 두 파이프라인을 분리해야 하는 이유를 눈으로 기억할 수 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.