[프로젝트 1 - 이미지 처리] 2. 데이터

Jade·2021년 3월 30일
0

부스트캠프 AI Tech

목록 보기
32/54

프로젝트 1 - 데이터

  • 데이터 전처리
  • 데이터셋과 데이터로더

[데이터 전처리]

바닐라 데이터를 모델에 적합한 형태의 데이터셋으로 가공하는 과정

캐글 등의 경진대회에서 주어지는 데이터는 대부분 이상이나 노이즈가 없는 아름다운 데이터다. 하지만 실제로 데이터를 수집한다면 이상한 값이 들어있거나 null값이 들어 있는 경우가 꽤 있다.

이상이 있는 데이터를 골라내거나 데이터가 모델에 잘 맞도록 가공하기 위해 전처리 과정을 거친다. 전처리가 마스터 키는 아니지만 task에 따라 적절한 전처리를 해 주면 성능을 끌어올리는 데 큰 도움이 되는 경우도 있다.

  • Bounding box
    이미지가 필요 이상으로 많은 정보를 가지고 있을 때도 있다. 필요한 부분만 잘라서 학습에 사용한다면 원하는 정보에 집중할 수 있어서 더 나은 성능을 기대할 수 있을 것이다. 단, bounding box를 찾고 크롭하는 과정에는 알고리즘(과거의 방법) 또는 bounding box 탐색 모델이 필요하다.

  • Data augmentation
    데이터를 일반화하기 위해서 사용하는 방법이다. 밝기를 조절하거나 회전시키거나 뒤집거나 기울이거나 노이즈를 주는 등 데이터가 가질 수 있는 상태를 다양하게 해서 데이터셋의 수를 늘리는 기법이다. 성능을 올리는 데 도움이 되는 방법이지만, 문제가 만들어진 배경과 모델의 쓰임새, 데이터가 가질 수 있는 상태를 잘 파악하고 사용해야 한다. EDA!!!
    데이터에 따라서 하면 안 되는 변형도 있다! (MNIST 데이터 중 숫자 6과 9, 2와 5 등)
    torchvision.transforms 모듈 안에 augmentation에 사용할 수 있는 다양한 함수들이 있다. 외부 라이브러리인 Albumentations를 쓰면 torchvision.transform보다 더 빠르고 다양한 augmentation 기법을 적용할 수도 있다.


[데이터셋과 데이터로더]

torch.utils.data 모듈의 Dataset 클래스를 상속받아 자신만의 커스텀 데이터셋 클래스를 만들 수 있다. Dataset 은 바닐라 데이터를 원하는 형태로 출력할 수 있는 클래스다.

class MyDataset(Dataset):
    def __init__(self, img_paths, transform):
        self.img_paths = img_paths
        self.transform = transform

    def __getitem__(self, index):
        image = Image.open(self.img_paths[index])

        if self.transform:
            image = self.transform(image)
        return image

    def __len__(self):
        return len(self.img_paths)

커스텀 데이터셋 클래스를 만들어 사용할 때 DataLoader와 연계해서 사용하면 편하다. 데이터로더는 데이터셋을 잘 쓸 수 있게 해 주는 유틸리티로, torch.utils.data.DataLoader에 포함되어 있다. 데이터로더를 쓰면 아주 편리하게 배치 사이즈만큼 데이터를 묶을 수 있는데, num_worker 옵션을 설정하면 스레드를 여러 개 사용할 수도 있다. drop_last 옵션을 통해 배치를 이루지 못하고 남은 데이터를 버릴지 말 지 설정할 수도 있다. 데이터로더는 여러 개의 Dataset 을 만들어 두고 각각에 다른 처리를 하고 싶은 경우에 특히 유용하다. 데이터로더에 들어갈 Dataset을 바꿔 가면서 각각 처리하면 된다!

transform = transforms.Compose([
				ToTensor(),
                		Normalize(mean=(0.5, 0.5, 0.5), std=(0.2, 0.2, 0.2)),
    				# 그 밖의 augmentation들 
                    		])

trainSet = MyDataset(imgPaths, transform) # 위에서 만든 MyDataset에서 imgPaths를 요구한다
trainLoader = DataLoader(trainSet, shuffle=False, num_workers=2, drop_last=True)

[피어 세션]

피어 세션 시간에 앞으로 프로젝트에 적용해 보면 좋을 것 같은 방법에 대한 이야기를 나눴다. 생각 못 해 봤던 아이디어도 있고 성능을 끌어올리기 좋을 것 같은 아이디어도 몇 개 떠올릴 수 있었다.

  • 모든 데이터에 동일한 augmentation을 적용하지 말고 데이터를 몇 묶음으로 나눠서 묶음별로 다른 augmentation을 랜덤하게 적용하기

  • Albumentation 모듈은 정말 진짜 엄청 빠르다

  • 데이터 중에서 이상한 것이 몇 가지 있음! 마스크를 눈에 쓴 사람이나 손수건을 두른 사람 등

  • 얼굴 부분만 데이터를 크롭해서 사용한다면 어떨까? 얼굴이 영역 안에 다 안 들어오고 조금 잘려도 큰 문제 없을 것 같은데.

  • 학습 데이터 안에서 클래스별 데이터 수가 굉장히 불균형한데, 검증셋을 구성할 때 클래스별 분포가 균등하게 만들어서 검증 정확도를 측정하면 더 정확한 측정이 가능할 것

  • 학습 데이터 비율이 불균형하니까 수가 많은 마스크 정상 착용 데이터는 augmentation 하지 말고 부족한 데이터에만 적용해서 수를 불리면 어떨까?

  • 한 번에 하나(성별만 구분, 마스크만 구분, 연령대만 구분)만 하는 모델 여러 개를 만들어서 앙상블하면 어떨까?

  • 모델 만들고 나서 학습 데이터를 분류시켜 본 다음 모델이 생각한 레이블과 실제 레이블을 각각 scatter plot으로 나타내 본다면 모델이 어떤 것을 헷갈리는지 알 수 있을 것이다. 그러면 augmentation 등으로 그쪽 데이터를 더 만들어 주면 해결될지도!

profile
반가워용

0개의 댓글