AI & Data/Deep Learning

[딥러닝] PyTorch - Dataset and Data Loader

테드리 2024. 8. 17. 19:02

Dataset과 Data Loader는 Pytorch에서 제공하는 추상 클래스이다. 

 

Dataset (torch.utils.data.Dataset)

- Mini-Batch를 구성할 각 data sample들을 하나씩 불러오는 기능을 수행한다

 

Data Loader (torch.util.data.DataLoader)

- Dataset에서 불러온 각 data sample들을 모아서 mini-batch로 구성하는 기능을 수행한다.

 

Dataset의 기본 뼈대

1. __init__ 함수

2. __len__ 함수

3. __getitem__ 함수

 

위 함수들을 명시해서 Custom Dataset을 만들 수 있다!

 

from torch.utils.data import Dataset

class CustomDataset(Dataset):
    def __init__(self):
    	#데이터셋의 전처리 수행 부분
        
    def __len__(self):
    	#데이터셋의 길이 (즉, 총 샘플의 개수를 명시)
        
    def __getitem__(self):
    	#데이터셋에서 특정 1개의 샘플을 가져오는 부분
        #참고로 item은 index

 

CIFAR10 Dataset 불러오기

torchvision.datasets.CIFAR10을 통해서 데이터셋을 다운로드할 수 있다.

  1. root = dataset을 다운로드 받을 위치, 혹은 다운로드 받은 데이터셋이 저장된 위치
  2. train = train dataset인지 혹은 test dataset인지 명시
  3. download = 다운로드 받을 것인지 명시
  4. transform = image를 어떻게 transform할 것인지 명시 
import numpy as np
import torch
from torch.utils.data import Dataset
from torchvision import import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
import os

os.makedirs("../.cache", exist_ok = True)

train_data = datasets.CIFAR10(
	root = "../.cache",
    train = True
    download = True
    transform = ToTensor()
)

test_data = datasets.CIFAR10(
	root = "../.cache",
    train = False
    download = True
    transform = ToTensor()
)

 

 

CIFAR10 데이터셋은 각 이미지를 정수로 레이블링 해서 출력하는데, 각 이미지에 해당하는 레이블 값은 다음과 같다

label 값 해당 이미지
0 plane
1 car
2 bird
3 cat
4 deer
5 dog
6 frog
7 horse
8 ship
9 truck

 

 

이미지 데이터 전처리

 

torchvision을 통해 불러온 이미지 데이터를 전처리하는 방법을 알아보도록 하겠다. 전처리는 기본적으로 다음과 같은 과정을 거쳐 진행된다.

  1. PIL Library로 이미지 파일 읽기
  2. 읽어온 이미지를 numpy 배열로 변환하기
  3. Numpy 배열을 Torch Tensor로 변환하기

 

1. PIL Library로 이미지 파일 읽기

 

이미지 데이터들은 흔히 .jpeg나 .png 형식으로 저장된다. 이런 파일을 읽을 때는 PIL.image.open을 사용할 수 있다.

from PIL import Image

img = Image.open("이미지 파일 경로")
img

 

2. 읽은 이미지를 numpy로 변환하기

np_img = np.array(img)

np.img.shape 	# 이미지의 (height, width, channel 수) 형태로 출력
		# 일반적인 RGB channel의 경우, channel 수 = 3
                
"""RGB channel의 경우, R,G,B에 해당하는 값이 각각 0~255까지의 정수 값을 가진다. 
이 값들을 보고 싶으면 다음과 같이 확인할 수 있다."""

for each_channel in range(3):
	print(f"{each_channel)-th min value: , {np.min(np_img[:,:,each_channel]}"))
    	print(f"{each_channel)-th max value: , {np.max(np_img[:,:,each_channel]}"))

 

3. numpy를 Torch Tensor로 변환하기

tensor_img = ToTensor()(np_img)

tensor_img.shape

for each_channel in range(3):
	print(f"{each_channel)-th min value: , {torch.min(tensor_img[:,:,each_channel]}"))
    	print(f"{each_channel)-th max value: , {torch.max(tensor_img[:,:,each_channel]}"))

 

Dataset Customize 하기

 

"Data customizing"은 데이터를 특정한 요구나 목적에 맞게 변형하거나 최적화하는 과정을 의미한다. 이는 데이터를 수집, 정리, 변환, 그리고 분석하는 과정에서 자주 사용되며, 대표적으로 아래와 같은 방식으로 이루어진다.

  1. 데이터 변환: 원본 데이터를 원하는 형식으로 변환하는 작업으로, 예를 들어, 텍스트 데이터를 숫자로 변환하거나, 특정 형식의 날짜를 다른 형식으로 바꾸는 작업 등
  2. 데이터 정제: 데이터에서 불필요한 부분을 제거하거나, 데이터 오류를 수정하는 과정으로, 데이터를 더 신뢰성 있게 만들고 분석의 정확성을 높이기 위한 목적
  3. 데이터 통합: 여러 출처의 데이터를 하나로 통합하여 분석할 수 있도록 만드는 과정으로, 서로 다른 데이터 포맷을 일치시키고, 중복 데이터를 제거하거나 결합하는 작업

 

Dataset을 customize하기 위해서는 torch.utils.data.Dataset을 상속받아야 한다. 앞서 말한 Dataset의 뼈대에 해당하는 매서드들을 구현해서 customizing을 할 수 있다.

 

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)
        # 각 이미지 파일의 label이 annotations_file에 저장되어 있다.
        self.img_dir = img_dir
        # 이미지들이 저장되어 있는 폴더 위치
        self.transform = transform
        # 이미지에 대한 transform 함수
        self.target_transform = target_transform
        # 레이블에 대한 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:
        	img = self.transform(image)
            
        if self.target_transform:
        	img = self.target_transform(label)
            
        return image, label

 

Data Loader의 input

  • dataset
  • batch_size : mini-batch의 크기
  • shuffle (binary) : 무작위 순서로 데이터를 샘플링 할 것인지
  • num_workers : 데이터 로딩에 사용할 subprocess 개수 (병렬 처리)
  • pin_memory (binary) : GPU memory에 pin 할 것인지
  • drop_last (binary) : 마지막 mini-batch를 drop 할 것인지
참고로, num_workers가 많을 수록 데이터 로딩이 빠르지만, 그만큼 CPU core 개수도 충분해야 한다. 만약 num_workers 수가 CPU core 개수보다 많으면 오히려 데이터 로딩이 느려지는 현상이 발생할 수 있다.

 

 

Data Loader 사용하기

 

Data Loader는 Dataset을 감싸주는 함수이고, 각 data를 mini-batch를 이용해 출력해준다.

from torch.utils.data import DataLoader

train_dataloader = DataLoader(train_data, batch_size = 64, shuffle = True)
test_dataloader = DataLoader(test_data, batch_size = 64, shuffle = False)

 

'AI & Data > Deep Learning' 카테고리의 다른 글

[딥러닝] Loss Function  (0) 2024.08.18
[딥러닝] PyTorch - Transforms  (1) 2024.08.17
[딥러닝] PyTorch - Tensor  (0) 2024.08.16
[딥러닝] DL 실무 기초 개념  (0) 2024.08.16
[딥러닝] Neural Network  (1) 2024.07.15