본문 바로가기
Python

[DL] Dataset: CIFAR-10

by ds31x 2024. 5. 30.

CIFAR-10

  • Machine Learning 과 Computer Vision 의 학습에서 널리 사용되는 image dataset.
  • 캐나다 토론토 대학교의 Alex Krizhevsky, Vinod Nair, Geoffrey Hinton에 의해 만들어짐.

구성 및 classes

1.Data 구성:

  • 이미지 크기: 32x32 Pixels
  • channels: 컬러 이미지 (RGB, 3채널)
  • class: 10개의 상호 배타적. Multi-classes Classification 을 위한 Dataset
  • class별 sample 수: 각 class마다 6,000장의 image sample (전체 60,000장)

2.Class:

CIFAR-10은 다음 10개의 classes로 구성됨:

  • 비행기 (airplane)
  • 자동차 (automobile)
  • 새 (bird)
  • 고양이 (cat)
  • 사슴 (deer)
  • 개 (dog)
  • 개구리 (frog)
  • 말 (horse)
  • 배 (ship)
  • 트럭 (truck)

3.데이터 분할:

  • 훈련 데이터: 50,000장
  • 테스트 데이터: 10,000장

용도 및 특징.

용도:

CIFAR-10은 image based multi-class classification task를 위한 모델을 학습하고 평가하는 데 주로 사용.

오늘날에는 CIFAR-10은 매우 단순하여 최신 모델의 성능을 비교하고 검증하는 벤치마크로서는 거의 사용되지 않음.
하지만, CIFAR-10은 상대적으로 작은 크기 덕분에 빠르게 실험을 반복할 수 있어 DL을 공부하는 데에 유용하게 사용됨.


특징:

  • 다양한 classes:
    • 서로 다른 10개의 클래스는 모델이 다양한 객체를 인식하고 분류할 수 있는 모델 구축에 유용함.
    • 상호배타적으로 Multi-class classification 을 위한 모델 구축에 사용가능.
  • 작은 이미지 크기:
    • 32x32 픽셀 크기의 작은 이미지로 구성되어
    • 학습에 요구되는 시간이 짧아 학습에 유리함.
  • 데이터 다양성:
    • 동일한 class 내에서도 다양한 각도, 조명 조건, 배경 등을 포함하고 있음.
    • 다른 간단한 dataset에 비해 보다 모델의 일반화 능력을 평가하는데 유리.

PyTorch로 사용하기.

CIFAR-10 데이터셋을 사용하는 예시 코드 (PyTorch):

  • 위 코드는 CIFAR-10 데이터셋을 로드하고,
  • 이를 train, validataion, test 를 위한 dataset으로 나누고,
  • 각각의 dataloader를 생성하고
  • 일부 이미지를 시각화하는 간단한 예시임.

필요한 module들을 import.

import os
import numpy as np
import matplotlib.pyplot as plt

import torchvision
from torchvision import datasets, transforms
import torch
from torch.utils.data import random_split, DataLoader

Trainset과 Testset 생성.

  1. cifar10을 다운로드
  2. train과 test를 위한 Dataset 생성.
    • torch.tensor로 변환.
    • standaradization을 수행.
# 데이터셋이 저장될 경로를 지정합니다.
data_path = os.path.join('dataset')

# 데이터 전처리 과정을 정의합니다.
transform = transforms.Compose(
    [
        # 이미지를 PyTorch 텐서로 변환하며 [0,1] 범위로 normalization.
        transforms.ToTensor(),
        # 이미지의 채널별 평균과 표준편차를 사용하여 정규화합니다.
        transforms.Normalize(
            (0.4915, 0.4823, 0.4468),  # CIFAR-10 데이터셋의 채널별 평균값
            (0.2470, 0.2435, 0.2616)   # CIFAR-10 데이터셋의 채널별 표준편차
        )
    ]
)

# CIFAR-10 학습용 데이터셋을 불러옵니다.
cifar10_train = datasets.CIFAR10(
    data_path,             # 데이터셋 경로
    train=True,            # 학습 데이터셋 로드
    download=True,         # 데이터셋이 없을 경우 다운로드
    transform=transform    # 전처리 과정 적용
)

# CIFAR-10 테스트용 데이터셋을 불러옵니다.
cifar10_test = datasets.CIFAR10(
    data_path,             # 데이터셋 경로
    train=False,           # 테스트 데이터셋 로드
    download=True,         # 데이터셋이 없을 경우 다운로드
    transform=transform    # 전처리 과정 적용
)
  • CIFAR-10 학습용 데이터셋을 다운로드하고 data_path에 데이터셋을 저장.
  • train=True로 설정하여 학습 데이터를 train=False로 설정하여 테스트 데이터.
  • download=True로 설정하면 데이터셋이 로컬에 없을 때 자동으로 다운로드됨.
  • transform은 불러온 데이터에 적용할 전처리 과정.

참고로, transform에서 tensor로 바꾸지 않으면 PIL.Image.Image 객체가 각각의 sample 임: [0,255]

 

여기서 얻은 cifar10_traincifar10_testtorch.utils.data.DataLoader로 넘겨질 수 있음.


Validation set 분리

그전에 train 데이터셋의 20%를 validation set으로 구분하는 코드는 다음과 같음.

from torch.utils.data import random_split

# 학습 데이터셋의 80%에 해당하는 크기를 계산.
train_size = int(0.8 * len(cifar10_train))

# 검증 데이터셋의 크기를 계산.
validation_size = len(cifar10_train) - train_size

# 학습 데이터셋을 학습용 데이터셋과 검증용 데이터셋으로 나눔.
train_set, validation_set = random_split(
    cifar10_train,               # 원본 학습 데이터셋 (torch.utils.data.Dataset 객체)
    [train_size, validation_size] # 나눌 크기 리스트 (학습용, 검증용)
)

# train_set과 validation_set은 모두 torch.utils.data.Dataset 객체입니다.

DataLoader 생성

다음은 Dataset객체를 통한 DataLoader객체 생성하는 코드임.

# 학습 데이터셋에 대한 데이터 로더를 생성하는 코드임
train_loader = torch.utils.data.DataLoader(
    train_set,           # 학습용 데이터셋임
    batch_size=32,       # 배치 크기를 32로 설정함
    shuffle=True,        # 데이터를 무작위로 섞어서 로드함
    num_workers=0,       # 데이터를 로드할 때 사용할 서브 프로세스의 수임
)

# 검증 데이터셋에 대한 데이터 로더를 생성하는 코드임
val_loader = torch.utils.data.DataLoader(
    validation_set,      # 검증용 데이터셋임
    batch_size=32,       # 배치 크기를 32로 설정함
    shuffle=False,       # 데이터를 섞지 않고 로드함
    num_workers=0,       # 데이터를 로드할 때 사용할 서브 프로세스의 수임
)

# 테스트 데이터셋에 대한 데이터 로더를 생성하는 코드임
test_loader = torch.utils.data.DataLoader(
    cifar10_test,        # 테스트용 데이터셋임
    batch_size=32,       # 배치 크기를 32로 설정함
    shuffle=False,       # 데이터를 섞지 않고 로드함
    num_workers=0,       # 데이터를 로드할 때 사용할 서브 프로세스의 수임
)
  • num_workers=0: 데이터 로드가 메인 프로세스에서 수행됨.
  • num_workers>0: 데이터 로드가 지정된 수의 서브 프로세스를 통해 병렬로 수행.

Image 보여주기

위의 dataset은 standardization이 되어 image를 보여줄 때 제대로 보여지지 않음.
때문에 이를 다시 min-max normalization을 하여 [0.0, 1.0] 으로 만들어

matplotlib.pyplot으로 정상적(?)으로 보여지도록 처리를 해야줘야 함.

# 데이터 로더에서 데이터셋의 첫 번째 배치를 가져옴
dataiter = iter(train_loader)
images, labels = next(dataiter)

# 이미지를 그리드 형태로 만들기 위해 여러 이미지를 하나로 결합함
grid_img = torchvision.utils.make_grid(images)

# 그리드 이미지에서 최대값과 최소값을 계산함
max_val = torch.max(grid_img)
min_val = torch.min(grid_img)

# 그리드 이미지의 타입, 최대값, 최소값을 출력함
print(f'{type(grid_img)=}\n{max_val.item()=}\n{min_val.item()=}')

# 그리드 이미지를 정규화함 (값을 0과 1 사이로 조정함)
normalized_grid_img = (grid_img - min_val) / (max_val - min_val)

# 이미지를 matplotlib를 사용하여 시각화함
# 이미지는 (C, H, W) 형식이므로 (H, W, C) 형식으로 변경함
plt.imshow(np.transpose(normalized_grid_img, (1, 2, 0)))
plt.axis('off')
plt.show()

결과 이미지는 다음과 같음.


같이 읽어보면 좋은 자료들

https://gist.github.com/dsaint31x/6d262365c5bfdd50e545dba367f0b8c2

 

dl_cifar10_pytorch.ipynb

dl_cifar10_pytorch.ipynb. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

728x90