PyTorch Dataset & DataLoader 기초문법
Date:
Dataset & Dataloader
- 모델에 데이터를 feeding을 도와주는 API
- 우리가 사용하는 데이터는 대부분 바로 model에 투입할 수가 없음
-
Model로 돌리기 위해서는 몇까지 작업들이 필요함
- Data 전처리
- Data to Tensor(Model의 입력이 될수 있도록 tensor로 바꿔줌)
- model feeding
- PyTorch에서는 위 작업들을 돕기위해 3가지 package를 제공하고 있음
- Dataset, Transforms, DataLoader
- 만약 라이브러리로 사용하면 import가 필요함 (
from torchvision import datasets
,import torchvision.transforms as transforms
)
Transforms
- Data를 전처리하고, Model에 입력될 수 있는 형태(ToTensor())로 변경해주는 작업
- data augmentation 등을 진행하는 부분도 Transforms 부분에 해당함
- 최근 huggingFace, TestAI등 표준화된 라이브러리를 많이 사용함
- Dataset을 구성할때 같이 많이 사용되나, 꼭 입력할때 모든 Data를 변경하여 사용하지 않고, 필요한 시점에 변환하여 사용하기도 함
- image data같은 경우는 tensor로 변환하는 작업을 dataset의 init에서 다해줄 경우 memory를 많이 잡아먹고 시간도 오래걸리기 때문에,
- getitem이후 dataloader에서 tensor로 변환하여 GPU로 feed해주면 loss가 줄어듦 → (CPU에서는 Tensor로 변환하는 동안 GPU에서는 이전 image를 학습하여 병렬적으로 처리할 수 있음)
※ huggingFace는 인기있는 Transforms을 도와주는 라이브러리
Dataset
- Data 입력 형태를 정의해주는 클래스
- data 형태에 따라 각 함수를 다르게 정의해줘야함(Image, Text, Audio 등등)
- Dataset은 Map-Style, Iterable-Style
-
Map-Style Dataset은 Index존재하는 Data로 3가지의 요소가 갖춰지면 좋음
- init : 데이터를 받아서 정리/저장하는 단계
- len : 데이터의 길이를 지정하는 단계
- getitem : 출력을 어떻게 해줄지를 설정하는 단계, return값으로는 Dict도 좋고, tensor형태로도 많이 사용함
-
Iterable-Style Dataset은 Index가 존재하지 않고, data마다 batch size가 달라지는 dynamic batch size에 사용하고 2가지 요소로 이뤄짐
- init : 데이터를 받아서 정리/저장하는 단계
- iter : 데이터를 iterable하게 가져올 수 있음
- 데이터 셋에 대한 표준화된 처리방법을 제공하게 되면 도움이 많이됨
Map-style Dataset
import torch
from torch.utils.data import Dataset
class CustomDataset(Dataset):
def __init__(self, text, labels): # 초기 데이터 생성방법을 지정
self.labels = labels
self.data = text
def __len__(self): # Data 전체 길이
return len(self.labels)
def __getitem__(self, idx): # index값에 해당하는 data 출력
label = self.labels[idx]
text = self.data[idx]
sample = {"Text": text, "Class": label}
return sample # 출력은 dict도 좋고, tesnor 형태로도 많이 사용함
DataLoader
- data의 batch를 생성해주는 클래스
- 여러 데이터를 묶어서 model에 feeding 해줌
- 학습직전(GPU feed전) 데이터의 변환을 책임짐
- suffle=True로 해주면 순서를 섞어서 배출해주는데, 중복 없이 반환해줌
📰code
import torch
from torch.utils.data import Dataset, DataLoader
class CustomDataset(Dataset):
def __init__(self, text, labels):
self.labels = 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
text = ['1', '2', '3', '4', '5', '6', '7', '8', '9','10']
labels = ['o','e','o','e','o','e','o','e','o','e']
MyDataset = CustomDataset(text, labels)
MyDataLoader = DataLoader(MyDataset, batch_size=2, shuffle=True)
for dataset in MyDataLoader:
print(dataset)
🔍result
{'Text': ['10', '4'], 'Class': ['e', 'e']}
{'Text': ['5', '8'], 'Class': ['o', 'e']}
{'Text': ['6', '2'], 'Class': ['e', 'e']}
{'Text': ['9', '1'], 'Class': ['o', 'o']}
{'Text': ['3', '7'], 'Class': ['o', 'o']}
💡 DataLoader속 여러 parameter
Dataset
- 정리한 Dataset Class 입력
batch_size
- 데이터셋에서 data를 몇개씩 불러올지 정하는 para, (batch_size, (data.shape))형태의 tensor로 반환(data가 tensor로 입력되어야함)
suffle
- Dataset의 데이터를 랜덤하게 가져옴, torch.manual_seed를 활용하면 고정된 data를 출력하여 재현성을 갖게됨
sampler
-
torch.utils.data.Sampler
객체를 활용해서 data index를 조정함, 이 기능을 설정하기 위해서는 suffle=False로 설정 필요함- SequentialSampler : 항상 같은 순서
- RandomSampler : 랜덤, replacemetn 여부 선택 가능, 개수 선택 가능
- SubsetRandomSampler : 랜덤 리스트, 위와 두 조건 불가능
- WeigthRandomSampler : 가중치에 따른 확률
- BatchSampler : batch단위로 sampling 가능
- DistributedSampler : 분산처리 (torch.nn.parallel.DistributedDataParallel과 함께 사용)
batch_sampler
- sampler와 동일함
num_workers
- subprocess 개수 설정(multiprocessing), 수가 높아지면 CPU와 GPU data처리에 병목현상이 발생하여 적정한 숫자로 설정필요
collate_fn
- map-style 데이터셋에서 sample list를 batch 단위로 바꾸는 기능으로 zero-padding이나 Variable Size 데이터 등 데이터 사이즈를 맞추기 위해 많이 사용
pin_memory
- GPU(CUDA)에 고정된 메모리를 할당하여 data 처리의 시간 효율을 높이는데 사용됨
drop_last
- data숫자가 batch_size로 나눠떨어지지 않으면, 마지막 data가 남게 되는데 그부분을 버려주는 기능
timeout
- 기본값은 0이고 0보다 큰 수가 입력되면, data를 불러올때 제한시간을 걸어줌
worker_init_fn
- num_worker는 갯수로 subprocess를 쓴다고 하면, worker_init_fn은 어떤 worker를 불러올 것인가를 리스트로 입력
📌reference
- boostcourse AI tech
- Hello Subinium!
💡 수정 필요한 내용은 댓글이나 메일로 알려주시면 감사하겠습니다!💡
댓글