데이터 증강 및 변환
- 데이터 증강 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. 와 같이 교체될 수 있으므로 사용 주의 필요
- 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.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에도 패딩 부여 가능
- 패딩 방법이 아닌 자를 때 발생하는 여백 공간 할당 방법 설정
- 무작위 자르기 클래스 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)
- 특별한 경우가 아니면, 시퀀스 형태로 입력해 크기 설정함
- 보편적으로 정사각형으로 데이터 정규화
- 정수: 높이나 너비 중 크기가 더 작은 값에 비율을 맞춰 크기 수정
- 크기 조정 Resize 클래스: 크기size 매개변수를 정수 또는 시퀀스로 입력 받음
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 수식 반대로 적용) 수행
- 색상 변환 클래스 ColorJitter: 이미지 밝기, 대비, 채도, 색상 hue 을 변환
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 변환하여 시각화
- 무작위 지우기 클래스 RandomErasing: 컷아웃과 무작위 지우기 방법 모두 가능
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: 이미지의 혼합 비율 설정
- 호출 메서드: 간단한 넘파이 연산으로 두 이미지 혼합
- Mixup 클래스도 구현해 증강
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)
텍스트 및 이미지 증강 방법
- 모든 데이터에 적용하는 것이 아닌, 일부 데이터에만 적용해 증강
- 모든 데이터에 적용하게 된다면 오히려 일반화 성능이 떨어지고 실제 데이터와 거리가 먼 데이터 구조를 갖게 되어, 부적절한 모델이 구성됨
- 색상 변환이나 정규화 같이 픽셀 데이터의 형태를 완전히 바꾸는 경우, 모델 추론 과정에서도 동일한 증강 방법이나 정규화 방법 적용 필요
'Theory > Pytorch' 카테고리의 다른 글
[파이토치 트랜스포머 #11] 4장 파이토치 심화 - 5) 사전 학습된 모델 (1) | 2024.07.03 |
---|---|
[파이토치 트랜스포머 #9] 4장 파이토치 심화 - 3) 정칙화 (0) | 2024.04.12 |
[파이토치 트랜스포머 #8] 4장 파이토치 심화 - 2) 가중치 초기화 (0) | 2024.04.12 |
[파이토치 트랜스포머 #7] 4장 파이토치 심화 - 1) 과대적합과 과소적합, 배치 정규화 (0) | 2024.04.12 |
[파이토치 트랜스포머 #6] 3장 파이토치 기초 - 6) 순전파와 역전파, 퍼셉트론 (1) | 2024.04.03 |