본문 바로가기
C.W.K.
Stream
Lesson 03 of 07 · published

실제 데이터에는 사용자 정의 데이터셋

~14 min · dataset, imagefolder, csv

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

계약은 메서드 두 개면 충분해

데이터를 '인덱스로 접근할 수 있는 샘플 목록'으로 표현할 수 있다면 사용자 정의 데이터셋에는 다음 두 메서드만 있으면 돼.

  • __len__(self): 전체 샘플 수를 반환해.
  • __getitem__(self, idx): 인덱스 idx의 샘플을 반환해.

이게 전체 계약이고 나머지는 DataLoader가 맡아.

계속 다시 쓰게 될 유형

  1. ImageFolder 방식: 하위 폴더 이름을 클래스 레이블로 쓰는 디렉터리 트리야. 전형적인 구조라면 torchvision의 ImageFolder를 바로 사용하고, 데이터 구조가 조금 다를 때만 변형해.
  2. CSV / pandas: 파일 경로와 레이블을 담은 매니페스트를 읽고 요청이 들어올 때 디스크에서 데이터를 가져와.
  3. HDF5 / Parquet / WebDataset: 큰 데이터셋을 디스크 기반 형식에서 읽을 때 사용해.
  4. 메모리 내 텐서: 모델을 시험해 볼 작은 데이터라면 텐서를 속성에 그대로 보관해도 돼.

지연 로드와 즉시 로드

큰 데이터셋은 반드시 지연 로드해야 해. __init__이 아니라 __getitem__ 안에서 디스크 파일을 읽어. 작은 데이터셋은 __init__에서 미리 처리해 메모리에 올릴 수 있어. 판단 기준은 데이터가 RAM에 넉넉하게 들어가는지 여부야. 컴퓨터에 따라 보통 10~100GB 사이에서 경계가 갈려.

Code

ImageFolder 방식: 클래스 이름으로 나눈 디렉터리에서 불러오기·python
import os
import torch
from torch.utils.data import Dataset
from PIL import Image

class ImageDirDataset(Dataset):
    """root/
        class_a/img1.jpg
                img2.jpg
        class_b/img3.jpg
    """
    def __init__(self, root, transform=None):
        self.root = root
        self.transform = transform
        self.samples = []
        self.classes = sorted(d for d in os.listdir(root)
                              if os.path.isdir(os.path.join(root, d)))
        self.class_to_idx = {c: i for i, c in enumerate(self.classes)}

        for cls in self.classes:
            cls_dir = os.path.join(root, cls)
            for fname in os.listdir(cls_dir):
                if fname.lower().endswith(('.jpg', '.jpeg', '.png')):
                    self.samples.append((os.path.join(cls_dir, fname), self.class_to_idx[cls]))

    def __len__(self):
        return len(self.samples)

    def __getitem__(self, idx):
        path, label = self.samples[idx]
        img = Image.open(path).convert('RGB')
        if self.transform:
            img = self.transform(img)
        return img, label
CSV 기반 데이터셋: 경로 + 레이블 매니페스트·python
import torch
import pandas as pd
from torch.utils.data import Dataset
from PIL import Image

class CSVImageDataset(Dataset):
    def __init__(self, csv_path, image_root, transform=None):
        self.df = pd.read_csv(csv_path)              # columns: 'path', 'label'
        self.image_root = image_root
        self.transform = transform

    def __len__(self):
        return len(self.df)

    def __getitem__(self, idx):
        row = self.df.iloc[idx]
        img = Image.open(f"{self.image_root}/{row['path']}").convert('RGB')
        if self.transform:
            img = self.transform(img)
        return img, int(row['label'])
표 형식 데이터셋: 특징을 담은 pandas DataFrame·python
import torch
import pandas as pd
from torch.utils.data import Dataset

class TabularDataset(Dataset):
    def __init__(self, csv_path, target_col, feature_cols=None):
        df = pd.read_csv(csv_path)
        self.target = torch.tensor(df[target_col].values, dtype=torch.long)
        cols = feature_cols or [c for c in df.columns if c != target_col]
        self.features = torch.tensor(df[cols].values, dtype=torch.float32)

    def __len__(self):
        return len(self.target)

    def __getitem__(self, idx):
        return self.features[idx], self.target[idx]

External links

Exercise

작은 이미지 모음에 맞춰 위의 ImageDirDataset을 작성해 봐. 데이터가 없다면 디렉터리 여섯 개에 무작위 JPEG를 다섯 장씩 만들어도 돼. len(dataset)을 확인하고 dataset[0]을 읽어 이미지가 열리며 레이블이 디렉터리 이름과 일치하는지 검증해. num_workers=0과 num_workers=4로 전체 데이터셋을 순회하는 시간을 재서 속도 차이도 측정해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.