관리 메뉴

Bull

[ML] 데이터 증강 및 변환 | study book 본문

Artificial Intelligence/Machine Learning

[ML] 데이터 증강 및 변환 | study book

Bull_ 2024. 8. 31. 12:36
transform = transforms.Compose(
    [
        transforms.Resize((512, 512)),
        Mixup(
            target=Image.open("../datasets/images/dog.jpg"),
            scale=(512, 512),
            alpha=0.5,
            beta=0.5
        )
    ]
)

데이터 증강

데이터가 가진 고유한 특징을 유지한 채 변형하거나 추가하여 데이터셋을 인위적을 늘린다. 데이터 수집은 제한된 상황에서 얻기 어려울 수 있음. 그래서 기존의 데이터를 증강시켜 새로운 데이터를 추출하는 방식.

  • 기존 데이터의 형질이 유지되므로 모델 분산과 편향을 줄임
  • 너무 많은 노이즈가 추가되면 기존 데이터 특징이 파괴될 수 있다.

텍스트 데이터

MLPAUG(자연어 처리 데이터 증강), 텍스트에 대해 삽입, 삭제, 교체, 대체, 생성, 반의어, 맞춤법, 교정, 역변역 등이 있다.

삽입 삭제

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("------------------")

ContextualWordEmbsAug 클래스에 BERT 모델을 활용하여 단어를 삽입했다. 삭제를 하려면 action에 delete를 입력하면 된다.

교체 대체

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("------------------")

RandomWordAug 클래스를 사용한다. 단어는 무작위로 교체된다. 그 외 insert, substitute, swap, delete, crop 기능을 제공한다.

문제점을 찾지말고 해결책을 찾으라 <=> 해결책을 찾으라 문제점을 찾지말고
와 같은 방식으로 교체를 적용할 수 있다.

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("------------------")

SynonymAug 클래스를 사용한다. wordnet이나 의역을 도와주는 The Parahprase DataBase(PPDB) 기능을 제공한다.
대체는 해 -> 태양으로 바꾸는 형식으로,정합성(Consistency)이 어긋나지 않도록 대체해준다.

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("------------------")

ReservedAug 클래스는 SynonymAug와 마찬가지로 특정 단어를 대체해주는 기능을 제공한다.

역번역

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("------------------")

역번역은 입력 텍스트를 특정 언어로 번역한 다음 다시 본래의 언어로 번역한다.

  • 영어 -> 한국어 -> 영어
  • 패러프레이징 효과를 얻을 수 있다.

BackTranslationAug 클래스는 입력 모델과 출력 모델을 설정해주어야한다. 코드는 영어 독일어가 사용되었다.

이미지 데이터

이미지 데이터 증강은 객체 검출 및 인식, 이미지 분류를 위해 사용된다. 회전, 대칭, 이동, 크기 조정 등이있다.

변환 방법

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)

토치 비전의 Compose 클래스를 사용한다. 모델 매개변수를 여러개 묶어주는 Sequential 클래스와 같은 역할을 한다.

transform = transforms.Compose(
    [
        transforms.RandomRotation(degrees=30, expand=False, center=None),
        transforms.RandomHorizontalFlip(p=0.5),
        transforms.RandomVerticalFlip(p=0.5)
    ]
)
  • to.Tensor 는 이미지 형식인 PIL.Image를 텐서형식으로 변환한다. [0,255]를 [0,1]로 정규화시켜준다.회전 대칭RandomRotation : 무작위 회전 클래스, [-30,30] 회전.
    RandomHorizontalFlip : 무작위 수평 대칭, 50% 확률.
    RandomVerticalFlip : 무작위 수직 대칭, 50% 확률.

자르기 패딩

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

RandomCrop : 무작위로 512크기로 crop.
Pad : 패딩, 50px,RGB 값.

크기 조정

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

압축된 거처럼 찌그러진 사진이 됨.

변형

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

RandomAffine : 아핀 변환을 해줌. 각도, 이동, 척도, 전단(층밀림)을 입력할 수 있다.

색상 변환

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()
    ]
)

ColorJitter : 채도, 명도, 대비, 색상 설정이 가능핟.

  • 정규화는 왜? 한건지는 모르겠음.

노이즈

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()
])

SaltAndPepper 잡음, 빗방울 잡음을 추가했다.

  • 일반화 능력, 강건성(Robustness) 를 평가하는 데 사용한다.

컷아웃, 무작위 지우기

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

컷아웃 : 이미지에서 임의의 사각형 영역을 삭제하고 0으로 채움, 폐쇄 영역을 더 강건하게 해주며 무작위 일부 영역이 누락될 때 더 강건한 모델을 만들어줌.

혼합, 컷믹스

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
        )
    ]
)

혼합은 두 개 이상의 이미지를 혼합해서 새로운 이미지를 만듬. 컷믹스는 이미지 패치 영역에 다른 이미지를 덮어 씌움.

참고 자료

https://product.kyobobook.co.kr/detail/S000209621433

 

파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습 | 윤대희 - 교보문고

파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습 | 트랜스포머는 딥러닝 분야에서 성능이 우수한 모델로 현대 인공지능 분야의 핵심 기술입니다. 트랜스포머와 비전 트랜스

product.kyobobook.co.kr