본문 바로가기
Theory/Pytorch

[파이토치 트랜스포머 #10] 4장 파이토치 심화 - 4) 데이터 증강 및 변환

by 남디윤 2024. 6. 30.

https://github.com/wikibook/pytorchtrf

 

 

 

 

 

 

데이터 증강 및 변환

  • 데이터 증강 Data Argumentation
    • 데이터가 가진 고유한 특징을 유지한 채 변형하거나 노이즈를 추가해 데이터세트의 크기를 인위적으로 늘리는 방법
    • 기존 학습 데이터를 재가공, 원래 데이터와 유사하지만 새로운 데이터 생성
    • 필요 이유
      • 모델의 과대 적합 감소, 일반화 능력 향상
      • 데이터세트를 인위적으로 확장
        • 기존 데이터 품질 유지한 채 특징을 살려 모델 학습에 사용
        • 모델의 분산과 편향 감소 가능
        • 데이터 수집 시 잘못된 정보가 들어오는 문제 발생 x
        • 특정 클래스의 데이터가 적은 경우 데이터 증강 → 불균형 완화
    • 주의 사항
      • 너무 많은 변형, 노이즈 추가 → 기존 데이터가 가진 특징 파괴 = 데이터의 일관성 사라짐
      • 데이터 증강: 특정 알고리즘 적용해 생성, 데이터 수집보다 더 많은 비용 발생 가능

 

텍스트 데이터

  • 문서 분류 및 요약, 문장 번역과 같은 자연어 처리 모델을 구성할 때 데이터세트의 크기를 쉽게 늘리기 위해 사용됨
  • 증강 방법: 삽입, 삭제, 교체, 대체, 생성, 반의어, 맞춤법 교정, 역번역 등
  • (이 책에서는) 자연어 처리 데이터 증강(NLPAUG) 라이브러리 활용
    • 텍스트 이외 음성 데이터 증강도 지원
    • 넘파이와 requests 에 종속적

삽입 및 삭제

  • 삽입: 의미 없는 문자나 단어, 또는 문장 의미에 영향을 끼치지 않는 수식어 등을 추가하는 방법
    • 임의의 단어나 문자를 기존 텍스트에 덧붙여 사용
  • 삭제: 삽입과 반대로 임의의 단어나 문자를 삭제해 데이터의 특징을 유지
  • 너무 적응 양 삽입, 삭제 시, 오히려 과대적합 문제 발생 가능
  • 너무 많은 양 삽입, 삭제 시, 데이터 품질 저하
  • 단어 삽입 예시 (출력 결과 생략)
    • ContextualWordEmbsAug 클래스: BERT 모델을 활용해 단어 삽입 기능 제공
    • action 매개변수: 모델이 수행할 기능 선택. 문장 삽입하는 경우 insert 적용, 단어를 대체 substitute 하는 기능도 제공
    • aug 클래스 선언 후 augment 메서드를 통해 기존 데이터 증강 가능
    • 입력 데이터에 문자열로 입력하더라도, 리스트 구조로 반환됨
    • 기존 문장의 의미를 크게 바꾸지 않은 채 데이터가 증강됨
import nlpaug.augmenter.word as naw

texts = [
    "Those who can imagine anything, can create the impossible.",
    "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
    "If a machine is expected to be infallible, it cannot also be intelligent.",
]

aug = naw.ContextualWordEmbsAug(model_path="bert-base-uncased", action="insert")
augmented_texts = aug.augment(texts)

for text, augmented in zip(texts, augmented_texts):
    print(f"src : {text}")
    print(f"dst : {augmented}")
    print("------------------")

 

 

  • 문자 삭제 예시 (출력 결과 생략)
    • RandomCharAug 클래스: 삽입 insert, 대체 substitue, 교체 swap, 삭제 delete 기능 제공
    • 문장 내 문자들이 무작위로 삭제됨
import nlpaug.augmenter.char as nac

texts = [
    "Those who can imagine anything, can create the impossible.",
    "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
    "If a machine is expected to be infallible, it cannot also be intelligent.",
]

aug = nac.RandomCharAug(action="delete")
augmented_texts = aug.augment(texts)

for text, augmented in zip(texts, augmented_texts):
    print(f"src : {text}")
    print(f"dst : {augmented}")
    print("------------------")

 

 

교체 및 대체

  • 교체: 단어나 문자의 위치를 교환하는 방법
    • ex) 문제점을 찾지 말고 해결책을 찾으라 → 해결책을 찾으라 문제점을 찾지 말고
    • 단어 교체 시, 본래의 의미나 맥락 보존 불가
    • → 데이터 특성에 따라 주의해 사용 필요
  • 대체: 단어나 문자를 임의의 단어나 문자로 바꾸거나 동의어로 변경하는 방법
    • ex) 유사한 단어로 변경 “사과” → “바나나”, “해” → “태양”
    • 다른 증강 방법보다 비교적 데이터의 정합성 Consistency이 어긋나지 않음
    • 의미가 달라지기도 함 (사과가 빨갛다 ≠ 바나나가 빨갛다, (조사 어색) 해는 동쪽에서 뜬다 → 태양 동쪽에서 뜬다)
  • 단어 교체 예시 (출력 결과 생략)
    • RandomWordAug 클래스: 무작위로 단어 교체 가능. 삽입 insert, 대체 substitute, 교체 swap, 삭제 delete 기능 제공, 자르기 crop 기능도 제공
      • 자르기: 연속된 단어 집합을 한 번에 삭제하는 기능
    • 무작위 교체의 경우, 문맥을 파악하지 않고 교체하여 the. 와 같이 교체될 수 있으므로 사용 주의 필요
import nlpaug.augmenter.word as naw

texts = [
    "Those who can imagine anything, can create the impossible.",
    "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
    "If a machine is expected to be infallible, it cannot also be intelligent.",
]

aug = naw.RandomWordAug(action="swap")
augmented_texts = aug.augment(texts)

for text, augmented in zip(texts, augmented_texts):
    print(f"src : {text}")
    print(f"dst : {augmented}")
    print("------------------")

 

 

  • 단어 대체 예시1 (출력 결과 생략)
    • SynonymAug 클래스: 워드넷 (WordNet) 데이터베이스나 의역 데이터베이스(The Paraphrase Database, PPDB) 를 활용해 단어 대체해 데이터 증강
    • 데이터베이스 내 유의어나 동의어로 변경 (=문맥 파악 x)
    • → 본래 문맥과 전혀 다른 문장이 될 수 있어 사용해 주의 필요
    • 모델을 활용해 대체하는 경우 → ContextualWordEmbsAug 클래스 사용
import nlpaug.augmenter.word as naw

texts = [
    "Those who can imagine anything, can create the impossible.",
    "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
    "If a machine is expected to be infallible, it cannot also be intelligent.",
]

aug = naw.SynonymAug(aug_src='wordnet')
augmented_texts = aug.augment(texts)

for text, augmented in zip(texts, augmented_texts):
    print(f"src : {text}")
    print(f"dst : {augmented}")
    print("------------------")

 

 

  • 단어 대체 예시2 (출력 결과 생략)
    • ReservedAug 클래스: 입력 데이터에 포함된 단어를 특정한 단어로 대체하는 기능 제공
    • 가능한 모든 조합 생성하거나 특정 글자나 문자를 reserved_tokens에서 선언한 데이터로 변경
import nlpaug.augmenter.word as naw

texts = [
    "Those who can imagine anything, can create the impossible.",
    "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
    "If a machine is expected to be infallible, it cannot also be intelligent.",
]
reserved_tokens = [
    ["can", "can't", "cannot", "could"],
]

reserved_aug = naw.ReservedAug(reserved_tokens=reserved_tokens)
augmented_texts = reserved_aug.augment(texts)

for text, augmented in zip(texts, augmented_texts):
    print(f"src : {text}")
    print(f"dst : {augmented}")
    print("------------------")

 

 

역번역

  • 역번역 Back-translation: 입력 텍스트를 특정 언어로 번역한 다음 다시 본래의 언어로 번역하는 방법
    • 패러프레이징 효과
    • 번역 모델의 성능에 크게 좌우됨
    • 기계 번역의 품질을 평가하는 데 사용되기도 함
    • 두 개의 모델을 활용해 데이터를 증강, 데이터 증강 방법 중 가장 많은 리소스 소모
  • 역번역 적용 예시 (출력 결과 생략)
    • BackTranslationAug 클래스: 입력 모델 from_model_name과 출력 모델 to_model_name을 설정해 번역 수행 가능
import nlpaug.augmenter.word as naw

texts = [
    "Those who can imagine anything, can create the impossible.",
    "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
    "If a machine is expected to be infallible, it cannot also be intelligent.",
]

back_translation = naw.BackTranslationAug(
    from_model_name='facebook/wmt19-en-de', 
    to_model_name='facebook/wmt19-de-en'
)
augmented_texts = back_translation.augment(texts)

for text, augmented in zip(texts, augmented_texts):
    print(f"src : {text}")
    print(f"dst : {augmented}")
    print("------------------")

 

 

이미지 데이터

  • 객체 검출 및 인식, 이미지 분류와 같은 이미지 처리 모델을 구성할 때 데이터세트의 크기를 쉽게 늘리기 위해 사용
  • 증강 방법: 회전, 대칭, 이동, 크기 조정 등
  • (이 책에서는) 토치비전 torchvision 라이브러리와 이미지 증강 imgaug 라이브러리를 활용
    • 토치비전 라이브러리에서 이미지 증강 및 변형을 위한 기본적인 메서드 제공
    • 이미지 증강 라이브러리는 토치비전 라이브러리에서 제공하지 않는 증강 방법 제공

 

변환 적용 방법

  • 토치비전 라이브러리의 변환 transforms 모듈을 통해 수행 가능
    • 여러 모델 매개변수를 묶어주는 시퀀셜 Sequential과 같은 역할을 하는 통합 Compose 클래스를 함께 사용해 증강 적용
  • 통합 클래스 사용 예제 (출력 결과 생략)
    • 이미지 데이터를 512 512 크기로 변환, 텐서 타입 변환
    • 이미지 증강은 어떤 순서로 진행하는가에 따라 픽셀 데이터의 변환 폭과 결과물이 크게 달라질 수 있음
      • 이미지 잘라낸 다음 512 512 크기로 변환 결과물≠ 512 512 변환 후 잘랐을 때 결과물
    • 이러한 문제를 방지하고자 통합 클래스 사용. 증강 방법을 정렬하고 하나로 묶어 데이터 핸들링 Data Handling을 수행
    • 텐서화 클래스 transforms.ToTensor: PIL.Image 형식을 Tensor 형식으로 변환
      • 텐서화 클래스: 0~255 범위의 픽셀 값을 0.0 ~ 1.0 사이의 값으로 Min-max 정규화 수행
      • 입력 데이터의 [높이, 너비, 채널] 형태 → [채널, 높이, 너비] 형태
    • 대부분의 이미지 증강 클래스 → PIL.Image 형식을 대상으로 변환
    • 파이토치에서는 Tensor 을 사용하기 때문에 torchvision.transforms로 PIL.Image 형식을 변환해 활용함
    • 데이터세트 일괄 적용 시, torchvision.datasets.ImageFolder와 같은 이미지 데이터세트 클래스의 transform 매개변수에 입력해 활용 가능
from PIL import Image
from torchvision import transforms

transform = transforms.Compose(
    [
        transforms.Resize(size=(512, 512)),
        transforms.ToTensor()
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
print(transformed_image.shape)
plt.imshow(transformed_image)

 

 

회전 및 대칭

  • 학습 데이터 구성 시 모든 방향으로 회전되거나 대칭된 이미지 수집 어려움
    • 이미지를 회전하거나 대칭한다면 변형된 이미지가 들어오더라도 더 강건한 모델 구축 가능, 일반화 성능 향상
  • 과도하게 증강 시, 본래 특징 소실 가능성 존재 및 실제 데이터에 존재하지 않는 데이터 생성 가능성 존재
    • ex) 표지판 인식 모델, 대칭하거나 과도하게 회전하면 의미 달라지거나 존재하지 않는 표지판
  • 회전 및 대칭 적용 예제 (출력 결과 생략)
    • 이미지 -30~30 사이로 회전, 수평 대칭과 수직 대칭을 50% 확률로 적용
    • 무작위 회전 클래스 RandomRotation:
      • 입력된 각도 degrees를 음수부터 양수 사이의 각도로 변환. 범위 설정 시에는 [-30, 90] 과 같은 시퀀스 형태로 입력
      • 이미지 회전 시 여백 생성됨 → 확장expand 을 True로 할당한다면 여백 x
      • 중심점 center: 시퀀스 형태로 전달, 입력하지 않으면 왼쪽 상단을 기준으로 회전
    • 무작위 대칭 클래스 RandomHorizontalFlip, RandomVerticalFlip: 수행 확률(p)을 활용해 대칭 여부 설정. (0.5=50%)
from PIL import Image
from torchvision import transforms

transform = transforms.Compose(
    [
        transforms.RandomRotation(degrees=30, expand=False, center=None),
        transforms.RandomHorizontalFlip(p=0.5),
        transforms.RandomVerticalFlip(p=0.5)
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

자르기 및 패딩

  • 학습 데이터의 크기가 일정하지 않거나 주요한 객체가 일부 영역에만 작게 존재할 수 있음
  • → 객체가 존재하는 위치로 잘라 불필요한 특징 감소, 패딩을 주어 이미지 크기를 동일한 크기로 맞추기 가능
  • 과도하게 잘라 검출하려는 객체가 포함되지 않거나 너무 많은 패딩을 주어 특징의 영향 감소 가능성 존재
  • 자르기 및 패딩 적용 예시 (출력 결과 생략)
    • 무작위 자르기 클래스 RandomCrop: 정수나 시퀀스 형태로 값 입력
      • 정수: 이미지 높이와 너비가 동일한 정사각형 이미지로 잘림
      • 시퀀스: (높이, 너비) 순서로 이미지 잘림
    • 패딩 클래스 Pad: 이미지 테두리에 특정한 방식이나 고정값으로 이미지 확장하는 기능 제공
      • 모든 방향으로 적용
      • 예시 512 512 자른 후 패딩 50 → 612 612 크기
      • 패딩 방식 padding_mode: 상수 constant로 입력해 RGB(127, 127, 255)로 테두리 생성
      • 패딩 방식을 반사 reflect 나 대칭 symmetric 입력 시 이미지의 픽셀값을 반사하거나 대칭해 생성함
    • 무작위 자르기 클래스 RandomCrop에도 패딩 부여 가능
      • 패딩 방법이 아닌 자를 때 발생하는 여백 공간 할당 방법 설정
from PIL import Image
from torchvision import transforms

transform = transforms.Compose(
    [
        transforms.RandomCrop(size=(512, 512)),
        transforms.Pad(padding=50, fill=(127, 127, 255), padding_mode="constant")
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

크기 조정

  • 수집된 이미지 데이터가 모두 동일한 크기의 이미지로 수집되거나 편집하기는 어려움
  • 모델 학습을 위해서는 이미지 크기가 일정해야 함
  • 데이터 자체를 수정하면 향후 모델이 입력받는 이미지 크기가 달라졌을 때 데이터 관리 어려움
  • → 증강 클래스에서 이미지 크기 변환
  • 크기 조정 예시 (출력 결과 생략)
    • 크기 조정 Resize 클래스: 크기size 매개변수를 정수 또는 시퀀스로 입력 받음
      • 정수: 높이나 너비 중 크기가 더 작은 값에 비율을 맞춰 크기 수정
        • 예) 원본 이미지 크기 (500, 400) → 작은 값인 400이 300이 되도록 → (300×500÷400, 300) = (375, 300)
      • 특별한 경우가 아니면, 시퀀스 형태로 입력해 크기 설정함
      • 보편적으로 정사각형으로 데이터 정규화
from PIL import Image
from torchvision import transforms

transform = transforms.Compose(
    [
        transforms.Resize(size=(512, 512))
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

변형

  • 기하학적 변환 Geometric Transform 을 통해 이미지 변경
    • 인위적으로 확대, 축소, 위치 변경, 회전, 왜곡 등 이미지 형태 변환
    • 아핀 변환 Affine Transformation, 원근 변환 Perspective Transformation
    • 아핀 변환: 2 × 3 행렬 사용, 행렬 곱셈에 벡터 합을 활용해 표현할 수 있는 변환
    • 원근 변환: 3 × 3 행렬 사용, 호모그래피 Homography로 모델링
  • 아핀 변환 적용 예시 (출력 결과 생략)
    • 각도 degrees, 이동 translate, 척도 scale, 전단 shear 입력해 이미지 변형
    • 회전이나 이동 이외에도 중심점(원전)에서 임의로 설정된 점을 향하는 벡터를 선형 변환 → 이미지가 눕혀지거나 비틀어진 결과물
    • 특징 유지되지만, 이미지 픽셀들이 큰 폭으로 변환, 가장 많은 변환
from PIL import Image
from torchvision import transforms

transform = transforms.Compose(
    [
        transforms.RandomAffine(
            degrees=15, translate=(0.2, 0.2),
            scale=(0.8, 1.2), shear=15
        )
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

색상 변환

  • 특정 색상에 편향되지 않도록 픽셀값 변환, 정규화 → 모델 일반화 성능 향상 및 학습 시간 단축
  • 색상의 채도 Saturation, 명도 Brightness, 대비 Contrast
  • 색상 변환 및 정규화 적용 예시 (출력 결과 생략)
    • 색상 변환 클래스 ColorJitter: 이미지 밝기, 대비, 채도, 색상 hue 을 변환
      • 이미지는 거리나 조명 등에 의해 색상 color 이 크게 변화됨
      • 여러 색상으로 변형해 간접적으로 데이터 세트의 일반화 효과 얻을 수 있음
      • 객체 검출, 인식 과정에서, 색상이 중요하지 않고 형태 shape가 더 중요한 경우 형태를 유지하면서 색상 톤을 낮출 수 있음
    • 정규화 클래스 Normalize: 픽셀의 평균과 표준편차를 활용해 정규화 (데이터를 정규화)
      • PIL.Image 형식이 아닌 Tensor 형식 입력 받음
      • 예제 코드에서는 이미지로 출력값을 확인하기 위해 텐서 변환 클래스 적용
      • 본래 픽셀값 확인하고자 한다면, 역정규화(Denormalization 수식 반대로 적용) 수행
from PIL import Image
from torchvision import transforms

transform = transforms.Compose(
    [
        transforms.ColorJitter(
            brightness=0.3, contrast=0.3,
            saturation=0.3, hue=0.3
        ),
        transforms.ToTensor(),
        transforms.Normalize(
            mean = [0.485, 0.456, 0.406],
            std = [0.229, 0.224, 0.225]
        ),
        transforms.ToPILImage()
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

노이즈

  • 이미지 처리 모델은 주로 합성곱 연산을 통해 학습을 진행
    • 예) 이미지 내 3 × 3 픽셀 영역 합성곱 → 1 × 1 크기
    • 픽셀값에 따라 특징 추출하는 매개변수 변동
  • 노이즈 추가도 특정 픽셀값에 편향되지 않도록 임의의 노이즈를 추가해 모델 일반화 능력 향상
  • 학습에 직접 포함되지 않더라도, 테스트 데이터에 노이즈를 추가해 일반화 능력 혹은 강건성 Robustness 평가하는데 사용
  • 노이즈 추가 예시 (출력 결과 생략)
    • 점 잡음(Salt and pepper noise)과 빗방울 레이어 적용
    • 이미지 증강 라이브러리의 증강 클래스는 넘파이 ndarray 클래스를 입력값과 출력값으로 사용
    • 토치비전은 PIL.Image 형식이나 Tensor 형식으로 증강 적용하기 때문에 IaaTransforms 클래스 선언해 적용
    • IaaTransforms 클래스
      • 초기화 메서드에서 증강 방법 설정. imgaug.augmenters 모듈에서 이미지 증강 클래스 사용 가능
      • 호출 메서드에서 PIL 이미지를 ndarray 형식으로 변환, augment_image 메서드로 증강 적용
      • 증강 적용 후 ndarray 클래스를 fromarray로 다시 PIL Image 형식으로 변환해 반환
import numpy as np
np.bool = np.bool_ # Deprecated 오류 방지
from PIL import Image
from torchvision import transforms
from imgaug import augmenters as iaa

class IaaTransforms:
    def __init__(self):
        self.seq = iaa.Sequential([
            iaa.SaltAndPepper(p=(0.03, 0.07)),
            iaa.Rain(speed=(0.3, 0.7))
        ])

    def __call__(self, images): 
        images = np.array(images)
        print(images.shape, images.dtype)
        augmented = self.seq.augment_image(images)
        return Image.fromarray(augmented)

transform = transforms.Compose([
    IaaTransforms()
])

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

컷아웃 및 무작위 지우기

  • 컷아웃 Cutout과 무작위 지우기 Random Erasing는 거의 동일한 시점에서 제안된 증강 및 정칙화 방법
  • 컷아웃: 이미지에서 임의의 사각형 영역 삭제, 0의 픽셀값으로 채우는 방법
    • 폐색 영역 Occlusion(특정 프레임에는 존재하지만 다른 프레임에는 존재하지 않는 영역)에 대해 모델을 더 강건하게 해줌
  • 무작위 지우기: 임의의 사각형 영역을 삭제, 무작위 픽셀값으로 채우는 방법
    • 일부 영역이 누락되거나 잘렸을 때 모델을 더 강건하게 해줌
  • 두 가지 방법 모두 이미지의 객체가 일부 누락되더라도 모델을 견고하게 만드는 증강 방법
  • 무작위 지우기 예시 (출력 결과 생략)
    • 무작위 지우기 클래스 RandomErasing: 컷아웃과 무작위 지우기 방법 모두 가능
      • 값 value을 0으로 할당하면 컷아웃 방법, random을 입력하면 무작위 지우기 방법
      • Tensor 형식만 지원. 클래스 호출 전 텐서 변환 클래스 호출하여 Tensor 형식 변환 필요
      • 마지막에 PIL 변환하여 시각화
from PIL import Image
from torchvision import transforms

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.RandomErasing(p=1.0, value=0),
    transforms.RandomErasing(p=1.0, value='random'),
    transforms.ToPILImage()
])

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

혼합 및 컷믹스

  • 혼합 Mixup: 두 개 이상의 이미지를 혼합 Blending해 새로운 이미지를 생성하는 방법
    • 픽셀 값을 선형으로 결합해 새 이미지 생성
    • 생성된 이미지는 두 개의 이미지가 겹쳐 흐릿한 형상을 지니게 됨
    • 혼합 방식으로 이미지 데이터를 증강해 학습하면 레이블링이 다르게 태깅돼 있어도 더 낮은 오류를 보이며, 이미지를 혼합했기 때문에 다중 레이블 Multi-label 문제에 대해서도 더 견고한 모델 구성 가능
  • 컷믹스 CutMix: 이미지 패치 patch 영역에 다른 이미지를 덮어 씌우는 방법
    • 네이버 클로바에서 발표한 이미지 증강 방법
    • 이미지 영역을 잘라내고 붙여넣기 Cut and Paste 하는 방법
    • 비교적 자연스러운 이미지 구성
    • 모델이 이미지의 특정 영역을 기억해 인식하는 문제 완화. 이미지 전체를 보고 판단할 수 있게 일반화
  • 둘 다 두 개 이상의 이미지를 활용해 이미지를 증강하는 방법
  • 차이점
    • 혼합: 이미지 크기만 맞다면 쉽게 혼합 가능
    • 컷믹스: 패치 영역의 크기와 비율 고려 필요
  • 혼합 구현 예시 (출력 결과 생략)
    • Mixup 클래스도 구현해 증강
      • target: 혼합하려는 이미지를 입력
      • scale: 이미지 크기 조절
      • alpha와 beta: 이미지의 혼합 비율 설정
      • 호출 메서드: 간단한 넘파이 연산으로 두 이미지 혼합
import numpy as np
from PIL import Image
from torchvision import transforms

class Mixup:
    def __init__(self, target, scale, alpha=0.5, beta=0.5):
        self.target = target
        self.scale = scale
        self.alpha = alpha
        self.beta = beta

    def __call__(self, image):
        image = np.array(image)
        target = self.target.resize(self.scale)
        target = np.array(target)
        mix_image = image * self.alpha + target * self.beta
        return Image.fromarray(mix_image.astype(np.uint8))

transform = transforms.Compose(
    [
        transforms.Resize((512, 512)),
        Mixup(
            target=Image.open("../datasets/images/dog.jpg"),
            scale=(512, 512),
            alpha=0.5,
            beta=0.5
        )
    ]
)

image = Image.open("../datasets/images/cat.jpg")
transformed_image = transform(image)
plt.imshow(transformed_image)

 

 

텍스트 및 이미지 증강 방법

  • 모든 데이터에 적용하는 것이 아닌, 일부 데이터에만 적용해 증강
  • 모든 데이터에 적용하게 된다면 오히려 일반화 성능이 떨어지고 실제 데이터와 거리가 먼 데이터 구조를 갖게 되어, 부적절한 모델이 구성됨
  • 색상 변환이나 정규화 같이 픽셀 데이터의 형태를 완전히 바꾸는 경우, 모델 추론 과정에서도 동일한 증강 방법이나 정규화 방법 적용 필요