딥러닝 프로젝트를 진행할 때 데이터 샘플을 처리하는 코드는 지저분하고 유지보수가 어려울 수 있다.
더 나은 가독성과 모듈성을 위해 데이터셋 코드를 모델 학습 코드로부터 분리하는 것이 이상적입니다.
파이토치는 Dataset 과 Dataloader를 사용하여 학습 모델에 맞게 train & test set 을 변경해주는 도구입니다.
PyTorch 공식 홈페이지 발취
공감되는 부분이다. 전에는 동작만 되면 상관없다는 마인드로 코드를 짰다.
하지만 정리가 되지 않아서 미래의 내가 알아볼 수 없는 것이다.(어케 짠거야 도대체...)
지금은 코드를 구조화 하고 모듈화하여 가독성을 생각하며 코딩한다.(겪어보지 않으면 모른다.)
파이토치는 이런 부분(data Input preprocessing)을 간결하게 구현할 수 있도록 도와준다.
Dataset ( torch.utils.data.Dataset )
Pytoch 라이브러리에 가지고 있는 데이터 셋 뿐만 아니라 미리 준비된(pre-loaded)데이터도 사용할 수 있다.
그러나 실제 프로젝트 때는 csv 와 같은 형태로 데이터 가지고 있는 경우가 대부분이다.
이런 경우 Dataset 클래스를 상속받아 구현할 수 있다.
FashionMNIST 이미지 데이터를 실제로 가지고 있다고 가정해보자.
이미지들은 img_dir 디렉토리에 저장되고 , 정답은 annotations_file csv 파일에 별도로 저장되어있다.
Dataset 클래스는 반드시 3개 함수를 구현해야 합니다.
- (1). __init__
- (2). __len__
- (3).__getitem__
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)
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
__init__ 함수는 Dataset 객체가 생성될 때 한 번만 실행됩니다.
여기서는 이미지와 주석 파일(annotation_file)이 포함된 디렉토리와 두가지 변형을 초기화 합니다.
transform 에는 변형해야할 타입의 변환 함수가 들어가게 됨
ex ) ToTensor()
즉 전처리 함수를 정의하고 init 함수를 통해 로드하여 나중에 한번에 처리할 수 있음.
__len__ 함수는 데이터셋의 샘플 개수를 반환합니다.
__getitem__ 함수는 주어진 인덱스 idx 에 해당하는 샘플을 데이터셋에서 불러오고 반환합니다.
인덱스를 기반으로 전처리를 진행하고 값을 리턴합니다.
사용자가 데이터 셋에 맞게 오버로딩해야할 함수가 바로 __getitem__ 입니다.
위에서 정의 했듯이 training_data 를 찍어보면 객체의 속성 정보가 나오고 안에 들어있는 값들에 접근하려면
__getitem__ 메서드를 통해서 접근이 가능합니다.
위 예제 에서는 디스크에서 이미지의 위치를 식별하고, read_image 를 사용하여 이미지를 텐서로 변환하고
self.img_labels 의 csv 데이터로부터 해당하는 정답(label)을 가져오고, 변형 함수들을 호출한 뒤, 텐서 이미지와 라벨을
python dict 형태로 반환하였습니다.(내가 데이터 셋에 맞춰서 바꿔나가야하는 부분)
Dataset 클래스를 사용하여 데이터 로드 부터 전처리(형변환)까지 모든 과정을 클래스로 관리할 수 있어서
유지보수가 쉽게 구현할 수 있다.
DataLoader(torch.utils.data.DataLodaer)
Dataset은 데이터셋의 특징(feature)을 가져오고 하나의 샘플에 정답(label)을 지정하는 일을 한 번에 처리해 주었다면.
DataLoader는 일반적으로 샘플들을 미니배치(minibatch)로 전달하고, 매 에폭(epoch)마다 데이터를 다시 섞어서 과적합(overfit)을 방지하고 python의 multiprocessing(CPU_WORKER)을 사용하여 데이터 검색 속도를 높이려고 합니다.
Tensorflow와 다르게 PyTorch는 학습과정에서 batch_size를 받아 미니배치를 처리하지않고
(미리하나 시작전에하나 차이) 학습하기 전에 미리 DataLoader를 통해 배치사이즈에 따라 미니배치를 진행합니다.
사용법
from torch.utils.data import DataLoader
train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)
Dataset 과 마찬가지로 결과를 찍어보면 객체의 대한 정보를 가지고 있다.
데이터의 접근하려면 python 의 내장함수 iter 와 next 을 사용하여 접근할 수 있다.
train_features, train_labels = next(iter(train_dataloader))
이렇게 해서 PyTorch 를 통해 모델 학습전에 편리하고 간결하게 Input_data 를 튜닝하는 클래스
Dataset , DataLoader에 대해서 알아보았습니다.
출처 : https://tutorials.pytorch.kr/beginner/basics/data_tutorial.html
'Machine learning > Deep Learning' 카테고리의 다른 글
[딥러닝]. 자연어 처리 모델 경량화 순서 (0) | 2023.03.23 |
---|---|
[딥러닝]. 효과적인 학습(training) 방법 모음 (0) | 2022.05.11 |
[DeepLearning]. GPU 메모리와 배치사이즈(Batch_size)의 관계 (0) | 2021.09.16 |
[PyTorch] . Tensorflow(텐서플로) PyTorch(파이토치) 차이점 비교 (0) | 2021.09.15 |
[Deep Learning] Tensorflow 자주 사용하는 Tensor 함수 정리 (0) | 2021.08.21 |