AI

PyTorch | Dataset & DataLoader

cstory-bo 2024. 1. 12. 14:38

PyTorch Dataset & DataLoader

이번 포스팅은 PyTorch에서 Dataset과 DataLoader 객체에 대한 내용이다.

만약 파이토치에서 자신의 데이터셋을 쓰기 위해서는 꼭 필요한 부분이라고 생각한다.

PyTorch의 데이터셋 처리 과정

파이토치 데이터는 아래와 같은 과정으로 사용한다.

collecting/cleaning/pre processing

⇒ Data

⇒ Dataset <= transforms ← ToTensor()/Crop()...

⇒ DataLoader

⇒ Model

Dataset class

  • 데이터 입력 형태를 정의하는 클래스
  • 데이터를 입력하는 방식의 표준화
  • Image, Text, Audio 등에 따라 다른 입력 정의
from torch.utils.data import Dataset

class CustomDataset(Dataset):
	def __init__(self, text, labels):
		self.lables = labels
		self.data = text
	def __len__(self):
		return len(self.labels)
	def __getitem__(self, idx):
		label = self.labels[idx]
		text = self.data[idx]
		sample = {"Text":text, "Class":label}
		return sample

위의 코드에서 

init함수는 초기 데이터 생성방법을 지정하고

len함수에서는 데이터의 전체 길이를 반환하고

getitem에서는 index값을 받았을 때 데이터와 label을 반환한다. 주로 dict타입을 반환을 많이 한다.

Dataset 유의점

  • 데이터 형태에 따라 각 함수를 다르게 정의한다.
  • 모든 것을 데이터 생성시점에 처리할 필요는 없다.
  • 최근에는 HuggingFace등 표준화된 라이브러리 사용한다.

DataLoader

  • Data의 Batch를 생성해주는 클래스이다.
  • 학습직전, 즉 GPU feed 전에 데이터의 변환을 책임진다.
  • Tensor로 변환 + Batch 처리가 메인 업무이다.
  • 병렬적인 데이터 전처리 코드의 고민이 필요하다.

DataLoader 옵션

DataLoader에는 아래와 같은 옵션들이 있다.

DataLoader(dataset,            # Dataset 인스턴스가 들어감

batch_size=1,       # 배치 사이즈를 설정

shuffle=False,      # 데이터를 섞어서 사용하겠는지를 설정

sampler=None,       # sampler는 index를 컨트롤

batch_sampler=None, # 위와 비슷하므로 생략

num_workers=0,      # 데이터를 불러올때 사용하는 서브 프로세스 개수

collate_fn=None,    # map-style 데이터셋에서 sample list를 batch 단위로 바꾸기 위해 필요한 기능

pin_memory=False,   # Tensor를 CUDA 고정 메모리에 할당

drop_last=False,    # 마지막 batch를 사용 여부

timeout=0,          # data를 불러오는데 제한시간

worker_init_fn=None # 어떤 worker를 불러올 것인가를 리스트로 전달
)

기본적인 default 값들은 아래와 같다. 

DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
batch_sampler=None, num_workers=0, collate_fn=None,
pin_memory=False, drop_last=False, timeout=0,
worker_init_fn=None, *, prefetch_factor=2,
persistent_workers=False)

사용 시에는 아래처럼 불러와 사용한다.

MyDataLoader = DataLoader(MyDataset, batch_size=2, shuffle=True)

sampler, batch_sampler

data를 어떻게 뽑을지 index를 뽑는 기법

그러면 이때 shuffle은 False여야한다.

불균형의 데이터셋일때 필요하다.

  • SequentialSampler : 항상 같은 순서
  • RandomSampler : 랜덤, replacemetn 여부 선택 가능, 개수 선택 가능
  • SubsetRandomSampler : 랜덤 리스트, 위와 두 조건 불가능
  • WeigthRandomSampler : 가중치에 따른 확률
  • BatchSampler : batch단위로 sampling 가능
  • DistributedSampler : 분산처리 (torch.nn.parallel.DistributedDataParallel과 함께 사용)

collate_fn

데이터 사이즈 맞추기위해 많이 사용된다. 

[data,label][data,labe] 을 [data,data...][label,label...]로 바꾸는 기법.

보통 padding이나 sequence data처리할 때 사용된다.

num_workers, worker_init_fn

num_workers에는 데이터를 불러올 때 사용하는 서브 프로세스 개수를 전달할 수 있다.

worker_init_fn 옵션에서는 어떤 worker를 불러올 것인가를 리스트로 전달할 수 있다.

그러나 너무 많이 사용하면 CPU와 GPU사이에 많은 교류가 발생하면서 병목 현상이 생길 수 있다!

drop_last

데이터 개수가 배치 사이즈와 딱 나누어 떨어지지 않을 수 있다.

이 경우 마지막 배치 사이즈가 작을 수 있는데, 만약 배치 사이즈 영향이 많이 받는 학습이라면

이 옵션으로 마지막 배치는 학습에서 제외시킬 수 있다.

pin_memory

Tensor를 CUDA 고정 메모리에 할당시키는 옵션이다.

이 경우 데이터 전송이 훨씬 빨라진다.