➢ Pytorch 에서 dataset을 쉽게 다룰 수 있도록 모듈을 제공하고 있다.
아래와 같이 두가지 Step으로 구성 된다.
❏ (Step1) CustomDataset 뼈대 - 데이터셋 상속
from torch.utils.data import Dataset
# 데이터셋 상속
class CustomDataset_name(Dataset):
#데이터 전처리 과정 작성.
def __init__(self):
pass
# 데이터의 길이 (총 샘플수) 작성.
def __len__(self):
pass
# 전처리 된 데이터셋을 인덱스(idx)에 맞게, Pytorch Tensor 형태로 반환 함.
def __getitem__(self,idx):
pass
❏ (Step2) DataLoader 뼈대
중요 파라미터 설명:
- shuffle : 매번의 에포크 마다 배치 순서를 섞을지 여부. ('배치 내부의 구성물들을 바꾸는것이 아님(seed가 고정되어 있다는 전제하에')
좀더 자세히 설명하자면,
shuffle=False 일때는 batch_1, batch_2, batch_3, ..., batch_100 이렇게 각각의 배치들이 매번의 에폭마다 섞이지 않고 학습에 사용된다.
반면 shuffle=True 일때는 batch50, batch23, batch1, ..., batch_75 이렇게 무작위로 들어가게 된다.
왜 사용할까? 모델이 batch 간의 순서도 학습할 수 있다. 예를 들어 시계열 데이터를 학습한다고 하자. 시계열 데이터에서는 시간에 따른 순서가 상당히 중요한데 shuffle=True로 한다면 시간적 의미가 다 파괴될것이다. 그러므로 일반적으로 shuffle=False로 한다. 반면 이미지 분류 문제를 수행하고 있다면 shuffle=False로 하는것이 일반적이다. 그래야만 다양한 데이터에 대해 편향이 생기지 않고 처리가 가능하기 때문이다. (시계열 데이터의 반대 이유라고 생각하면 이해가 편할것이다) - drop_last : 데이터를 배치크기로 나누었을 때 나머지 데이터의 사용 유무.
예를 들어 데이터의 개수가 1280개가 있다면 batch_size=64로 한다면 1280/64 의 나머지는 0 임으로 문제가 없지만,
데이터의 개수가 1200개 이고 batch_size=64 이면 1200/64의 나머지는 48 이다. 나머지 48개의 데이터셋을 모델의 학습에 사용 유무를 선택하겠다는 것이다.
왜 사용할까? 나머지의 데이터가 loss값에 영향을 상당히 미칠 수 도 있다(좋던, 안좋던). 시계열 데이터라면 Flase로 해서 하는것이 명확한 방법일 것이며, 데이터가 상당히 많다면 True를 해도 상관없을듯 하다. 어떤 문제를 푸느냐에 따라 선택해야 한다. - batch_size : 하나의 소그룹에 속하는 데이터의 개수. 즉, mini batch 내부의 데이터 개수를 말하는 것.
from torch.utils.data import DataLoader
dataset = CustomDataset_name()
dataloader = DataLoader(dataset, batch_size=64, shuffle=True, drop_last=False)
❏ CustomDataset 예시(1)
- 이해를 돕기 위한 가장 기본적인 예시임
# Dataset 상속
class CustomDataset(Dataset):
def __init__(self):
self.x_data = [[1, 58, 24],
[31, 90, 73],
[49, 61, 40],
[57, 79, 57],
[63, 76, 20]]
self.y_data = [[862], [234], [230], [427], [624]]
# 데이터의 길이 (총 샘플수) 작성.
def __len__(self):
return len(self.x_data)
# 전처리 된 데이터셋을 인덱스(idx)에 맞게, Pytorch Tensor 형태로 반환 함.
def __getitem__(self, idx):
x = torch.FloatTensor(self.x_data[idx])
y = torch.FloatTensor(self.y_data[idx])
return x, y
# 참고: https://wikidocs.net/57165
dataset = CustomDataset()
dataloader = DataLoader(dataset, batch_size=2, shuffle=True, drop_last=False)
❏ CustomDataset 예시(2)
- 실제로 머신러닝을 돌리다보면 본인이 수집한 데이터들을 load해서 전처리를 수행한다.
- 데이터를 다른 폴더에서 불러와서 sliding_window로 전처리를 수행한 코드이다.
from torch.utils.data import Dataset,DataLoader
import torch
import os
import pandas as pd
import numpy as np
class CustomDataset(Dataset):
# 데이터 전처리
def __init__(self, window_size,Folder_dir):
self.data_list=[]
swindow_size=window_size
Folder_path=Folder_dir
for filename in os.listdir(Folder_path):
data=pd.read_csv(Folder_path+filename)
data=data.to_numpy()
features=torch.FloatTensor(data[:,0:99])
labels=torch.FloatTensor(data[:,99])
labels=labels.reshape(len(labels),-1)
for i in range(len(features)-window_size):
features_subset=features[i:i+window_size]
labels_subset=labels[i]
# print(features_subset.shape)
# print(labels_subset.shape)
self.data_list.append([features_subset,labels_subset])
# 데이터 길이
def __len__(self):
return len(self.data_list)
# 데이터 셋을 전처리 후 반환하는 함수
def __getitem__(self, idx):
x,y=self.data_list[idx]
x = torch.FloatTensor(x)
y = torch.FloatTensor(y)
return x, y
##
## 데이터셋 생성
##
from main_files.CustomDataset import CustomDataset # main_files 폴더에서 CustomDataset class 호출하여 사용.
from torch.utils.data import Dataset,DataLoader ,random_split
dataset=CustomDataset(window_size=30, Folder_dir='./main_data/')
# train,test 분리
val_ratio=0.2
val_size=int(val_ratio*len(dataset))
train_size=len(dataset)-val_size
train_dataset, val_dataset=random_split(dataset,[train_size,val_size])
train_dataloader=DataLoader(train_dataset,batch_size=64,shuffle=False,drop_last=True) # shuffle: 미니배치들이 에폭마다 섞이는 유무.
val_dataloader=DataLoader(val_dataset,batch_size=64,shuffle=False,drop_last=True) # shuffle: 미니배치들이 에폭마다 섞이는 유무.
print("Dataset size:",len(dataset),'\n')
print("Traing data size:",len(train_dataset))
print("Traing data size (.dataset):",len(train_dataloader.dataset))
print("Validation data size:",len(val_dataset),'\n')
print("Traing data # of batch:",len(train_dataloader))
print("Validation # of batch:",len(val_dataloader))
❏ CustomDataset 예시(3)
→ 만약 각각 train_x, train_y 를 불러와서 붙여야 한다면?...
→ TensorDatset활용 : PyTorch에서 제공하는 데이터셋 클래스 중 하나로, 여러개의 텐서들을 간단하게 묶어서 사용할 수 있도록 도와주는 클래스입니다. 이 클래스를 사용하면 훈련 데이터와 타깃 데이터를 각각의 텐서로 구성하여 편리하게 다룰 수 있습니다.
from torch.utils.data import DataLoader, TensorDataset
train_dataset=TensorDataset(train_x, train_y)
train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)
❏ 기타 팁
- 필자는 CustomDataset을 따로 .py 파일로 다른 파일에 만들어 놓고,
train.py 또는 main.py파일을 만들어서 class형태로 호출하여 model을 학습시킨다.
경험적으로 이러한 방식이 코드가 깔끔하고, 가독성도 높으며, 수정하기 편한것 같다.
'인공지능 (기본 딥러닝) > 딥러닝 스크래치 코드' 카테고리의 다른 글
[Pytorch 스크래치 코드] 회귀문제 Train, Validation 함수 (1) | 2023.12.17 |
---|---|
[Pytorch 스크래치 코드] 분류문제 Train, Validation 함수 (0) | 2023.12.16 |
[Pytorch 스크래치 코드] Train Test split (1) | 2023.12.10 |
[Pytorch 스크래치 코드] 실험 재현을 위한 Seed 고정 (0) | 2023.12.09 |
[Pytorch 스크래치 코드] Early Stopping (0) | 2023.12.09 |