이번 포스팅은 PyTorch에서 Dataset과 DataLoader 객체에 대한 내용이다.
만약 파이토치에서 자신의 데이터셋을 쓰기 위해서는 꼭 필요한 부분이라고 생각한다.
파이토치 데이터는 아래와 같은 과정으로 사용한다.
collecting/cleaning/pre processing
⇒ Data
⇒ Dataset <= transforms ← ToTensor()/Crop()...
⇒ DataLoader
⇒ Model
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타입을 반환을 많이 한다.
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)
data를 어떻게 뽑을지 index를 뽑는 기법
그러면 이때 shuffle은 False여야한다.
불균형의 데이터셋일때 필요하다.
데이터 사이즈 맞추기위해 많이 사용된다.
[data,label][data,labe] 을 [data,data...][label,label...]로 바꾸는 기법.
보통 padding이나 sequence data처리할 때 사용된다.
num_workers에는 데이터를 불러올 때 사용하는 서브 프로세스 개수를 전달할 수 있다.
worker_init_fn 옵션에서는 어떤 worker를 불러올 것인가를 리스트로 전달할 수 있다.
그러나 너무 많이 사용하면 CPU와 GPU사이에 많은 교류가 발생하면서 병목 현상이 생길 수 있다!
데이터 개수가 배치 사이즈와 딱 나누어 떨어지지 않을 수 있다.
이 경우 마지막 배치 사이즈가 작을 수 있는데, 만약 배치 사이즈 영향이 많이 받는 학습이라면
이 옵션으로 마지막 배치는 학습에서 제외시킬 수 있다.
Tensor를 CUDA 고정 메모리에 할당시키는 옵션이다.
이 경우 데이터 전송이 훨씬 빨라진다.