Pytorch로 시작하는 딥러닝 입문(03-07. 커스텀 데이터셋, transform 약간, ToTensor)

2024. 2. 24. 09:13딥러닝 모델: 파이토치

파이토치에서는 데이터셋을 좀 더 쉽게 다룰 수 있도록 유용한 도구로서 torch.utils.data.Dataset과 torch.utils.data.DataLoader를 제공한다. 이를 사용하면 미니배치 학습,데이터 셔플, 병렬 처리까지 간단히 수행할 수 있다. 기본적인 사용 방법은 Dataset을 정의하고, 이를 DataLoader에 전달하는 것이다. 

♣ Custom Dataset

파이토치에서 제공하는 torch.utils.data.Dataset을 상속 받아서 직접 커스텀 데이터셋을 만들 수도 있다. 

torch.utils.data.Dataset은 파이토치에서 데이터셋을 제공하는 추상 클래스이다. 

 

커스텀 데이터셋을 만들 때, 가장 기본적인 뼈대는 아래와 같다. 기본적인 define이 3가지 있다. 

  • __ init__: 데이터셋의 전처리를 해주는 부분. img_dir, transform(이미지에 대한 transform 함수), target_transform(label에 대한 transform 함수)등이 들어감

 

  • __len__: 데이터셋의 길이. 즉 총 샘플의 수를 적는 부분으로 데이터셋의 크기를 리턴함. 만약 데이터셋의 길이가 100이라면 __len__ 메서드는 100을 반환한다. 데이터셋의 길이가 100이고 batch_ size가 10이라면 DataLoader는 각 epoch마다 10개의 미니배치를 생성하게 된다. 

 

  • __getitem__: 데이터셋에서 특정 1개의 샘플을 가져오는 함수. dataset[i]를 했을 때 i번째 샘플을 가져옴. 

 

♣ 커스텀 데이터셋으로 선형 회귀 구현하기

 DataLoader의 input

- dataset

- batch_size: mini-batch의 크기

- shuffle(binary): 무작위 순서로 데이터를 샘플링할 것인지

- num_workers: 데이터 로딩에 사용할 subprocess 개수(병렬 처리). num_workers 수가 많을수록 데이터 로딩이 더 빠르지만 그만큼 CPU core 개수도 충분해야 함. 

- pin_memory(binary): GPU memory에 pin 할 것인지. True로 정의할 경우  GPU memory를 미리 할당, 확보해서 조금 더 빠르게 데이터를 GPU에 올릴 수 있게 한다. 

- drop_last(binary): 마지막 mini_batch를 drop할 것인가

 

 

 

 

 

*파이토치 가이드에서의 다른 예시

import os
import pandas as pd
from torchvision.io import read_image

class CustomImageDataset(Dataset):
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file, names=['file_name', 'label'])
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

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

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        image = read_image(img_path)
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label

 

 

♣ 이미지 데이터 전처리 과정 

1. Pillow(PIL) Library로 이미지 파일 읽기

2. (PIL로 읽어온) 이미지를 numpy 배열로 변환하기

3. Numpy 배열을 Torch.Tensor로 변환하기

 

ToTensor에 대한 참고 사항

1. Channel에 대한 차원이 맨 앞으로 오게 바꿔준다(height, width, number of channels) => (number of channels, height, width)

2. 값을 255로 나눈다. 

3. uint8 =:> float32