[DL] Dataset( )과 DataLoader( ): Image Built-in Dataset Loading

해피해피슈크림·2025년 5월 24일

Image Bulit-in Dataset Loading - Flowers102 Dataset 🌼

  • torchvision 모듈을 통해 Flowers102 데이터셋을 로드합니다.
  • Oxford 102 Flower는 이미지 분류 데이터셋입니다. 102개의 꽃 카테고리로 구성되어 있습니다. 데이터셋의 꽃들은 영국에서 주로 나는 꽃들입니다. 각각의 클래스에는 40~258개의 이미지가 있습니다.
  • 이번 실습은 데이터셋을 불러와 이미지를 시각화까지만 해보는 간단한 실습입니다. 😊

해설

📃 라이브러리 로드

from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np
  • 먼저, 데이터셋 로딩, 변환 및 시각화를 위한 필수 라이브러리들을 불러옵니다.

🙋🏼‍♀️ 데이터셋 불러오기

# 🌼 데이터 경로
flowers102_data_dir = "datasets"

# 🌻 Transform 정의
transform = transforms.Compose([
    transforms.Resize((128, 128)),  # 1. 이미지 크기를 128 x 128 픽셀로 조정
    transforms.ToTensor()           # PIL 이미지를 tensor형으로 변환
])

# 📦 Flowers102 불러오기 (train split만)
flowers102_trainset = datasets.Flowers102(
    root=flowers102_data_dir,  # root dir of the dataset
    download=True,             # 지정 경로에 데이터가 없을시 다운받을지 여부
    split='train',             # 'train' -> train dataset을 불러온다
    transform=transform        # 전처리 함수 지정
)
  • 데이터셋을 불러올 경로와 전처리 함수를 정의한 뒤, Flowers102 데이터셋을 불러옵니다.
  • 전처리 함수인 transform이미지 데이터를 모델 학습에 적절한 형태로 전처리합니다. 전처리 함수 정의 코드에서 transforms.Compose()는 여러 이미지 변환 작업(Transform)을 순차적으로 묶어주는 역할을 합니다.
  • 데이터셋을 불러올 때는 Flowers102() 객체에 파라미터를 적절히 지정하여 불러옵니다. (Pytorch 공식 홈페이지 참고: Flowers102 — Torchvision 0.22 documentation

🧐 전처리, 왜 필요할까요?

  • Pytorch 모델은 이미지가 텐서(tensor) 형태로 입력되기를 기대합니다.
  • 또한, 입력 이미지 크기를 통일해야 배치 학습이 가능합니다.
  • ➡️ 그래서 transform.Compose() 함수로 이런 전처리 과정들을 하나로 묶어주는 겁니다.

✅ 데이터셋 타입 확인

print(type(flowers102_trainset))
출력 결과:
<class 'torchvision.datasets.flowers102.Flowers102'>
  • 로드한 trainset의 타입을 확인합니다.
  • flowers102_trainsettorchvision 라이브러리의 Flowers102 클래스 인스턴스입니다.
  • 이 클래스는 torchvision.datasets.flowers102 모듈에 정의되어 있으며, 이름 그대로 Oxford Flowers 102 데이터셋을 나타냅니다.

✅ 상속 여부 확인

from torch.utils.data import Dataset

isinstance(flowers102_trainset, Dataset)
출력 결과:
True
  • isinstance() 함수: isinstance(obj, class)objclass의 인스턴스인지 확인해서, 맞으면 True, 아니면 False를 반환합니다.
  • 출력 결과가 True 이므로, flowers102_trainsettorch.utils.data.Dataset상속받고 있다는 의미입니다. 이는 PyTorch의 DataLoader로 로딩하거나, len(), __getitem() 같은 메서드를 사용할 수 있음을 뜻합니다.
  • 아래는 flowers102_trainset 인스턴스가 생성되기까지의 클래스 및 모듈 호출 흐름을 표현한 구조도입니다.
torchvision               ← 라이브러리
└── datasets              ← 서브모듈 (모듈 모음)
    └── flowers102.py     ← 모듈 (.py 파일)
        └── Flowers102    ← 클래스
            └── flowers102_trainset ← 인스턴스 (클래스 호출 결과)

✅ 데이터셋 정보 요약

flowers102_trainset
출력 결과:
Dataset Flowers102
    Number of datapoints: 1020
    Root location: datasets
    split=train
    StandardTransform
Transform: Compose(
               Resize(size=(128, 128), interpolation=bilinear, max_size=None, antialias=True)
               ToTensor()
           )
  • 이 출력은 현재 로딩된 데이터셋의 기본 정보와 적용된 전처리(transform) 내용을 요약한 것입니다.

✅ 학습 데이터 배치를 생성하는 DataLoader 객체 정의

# 🛒 Dataloader
train_loader = DataLoader(
    flowers102_trainset,    
    batch_size=8,           
    shuffle=True,           
    drop_last=True
    )
  • DataLoader를 이용해
    1. 학습용 데이터셋을 지정한 배치 크기(batch_size=8)로 나누고,

    2. shuffle=True 옵션을 통해 매 epoch마다 데이터를 무작위로 섞습니다.

    3. drop_last=True 옵션을 통해 마지막 배치의 크기가 지정한 배치의 크기보다 작을 경우 마지막 배치를 버립니다.

      이렇게 하면 모든 배치가 동일한 크기(8개)로 유지되어, 모델 학습 시 배치 단위 연산이 일정하게 처리됩니다.

  • 이렇게 만들어진 train_loader는 모델 학습 시 반복(iteration) 가능한 iterable 객체입니다.

✅ step 수 확인

# step
len(train_loader)
출력 결과:
127
  • len() 함수를 이용해 한 epoch 동안의 총 step 수 계산할 수 있습니다.
  • 훈련 데이터셋 크기 1020에서 batch 크기 8을 나누면 127.5로, 나누어 떨어지지 않습니다. 위에서 drop_last=True 옵션을 주었으므로 마지막 배치를 버렸기 때문에 step은 127번이 됩니다.

✅ 데이터 구성 확인: 이미지와 라벨

# 🔍 배치 하나 확인
images, labels = next(iter(train_loader))
images, labels
(tensor([[[[0.2549, 0.2706, 0.2980,  ..., 0.1765, 0.2000, 0.2000],
           [0.2549, 0.2549, 0.2863,  ..., 0.1843, 0.1922, 0.1922],
           [0.2588, 0.2941, 0.4000,  ..., 0.1804, 0.1882, 0.1882],
           ...,
           [0.2588, 0.2549, 0.2353,  ..., 0.1961, 0.1961, 0.2039],
           [0.2588, 0.2588, 0.2392,  ..., 0.2000, 0.2039, 0.2039],
           [0.2667, 0.2667, 0.2510,  ..., 0.2118, 0.2118, 0.2118]],
 
          
           ...,
           [0.1412, 0.2824, 0.2863,  ..., 0.1608, 0.1373, 0.1373],
           [0.0588, 0.1373, 0.0941,  ..., 0.1686, 0.1294, 0.1020],
           [0.0314, 0.0392, 0.0314,  ..., 0.1647, 0.1373, 0.1216]]]]),
 tensor([14, 97, 67, 52, 79, 26, 62, 27]))
  • 학습 데이터로더에서 배치 하나를 꺼내 이미지와 라벨을 확인합니다.
  1. train_loader: 배치 단위로 데이터를 꺼낼 수 있는 반복 가능한 객체 (iterable)
  2. iter(train_loader): iterable을 iter() 함수를 이용해 iterator로 변환
  3. next(iter(train_loader)): 안에 있는 iterator에서 값을 하나씩 꺼냄.

💡 (참고) iterableiterator

  • iterable: 리스트, 튜플, 문자열, 딕셔너리 등
  • iterator: `next()` 메서드를 가지고 있어서 값을 하나씩 꺼낼 수 있는 객체
  • iter()는 반복 가능한 객체(iterable)를 이터레이터(iterator) 로 변환합니다.

🎨 데이터 시각화

# 🎨 시각화 함수
def imshow(imgs, labels):
    imgs = imgs.numpy()
    fig, axs = plt.subplots(1, len(imgs), figsize=(15, 4))
    for i in range(len(imgs)):
        img = np.transpose(imgs[i], (1, 2, 0))  # (C, H, W) → (H, W, C)
        axs[i].imshow(img)
        axs[i].set_title(f"Label: {labels[i].item()}")
        axs[i].axis('off')
    plt.show()

# 🖼️ 배치 이미지 확인
imshow(images, labels)

  • 이 함수는 배치(batch)로 불러온 이미지와 라벨을 시각화해 보여주는 역할을 합니다.
  • imgs.numpy() : PyTorch 텐서를 NumPy 배열로 변환합니다. (ToTensor()로 변환된 데이터는 Tensor 형태이므로 시각화를 위해 변환 필요)
  • np.transpose(imgs[i], (1, 2, 0)) : 이미지의 채널 순서를 PyTorch 형식 (C, H, W)에서 matplotlib이 인식할 수 있는 (H, W, C)로 변경합니다.
  • imshow(images, labels) : images와 labels로 구성된 한 배치(batch) 를 시각화합니다. images는 DataLoader에서 추출한 이미지 텐서이고, labels는 해당 이미지들의 클래스(정수형 라벨)입니다.

0개의 댓글