from torch.utils.data import DataLoader, Dataset 사용법

FSA·2024년 3월 22일
0

torch

목록 보기
2/3
post-custom-banner
  • torch.utils.data.DataLoadertorch.utils.data.Dataset은 PyTorch에서 데이터를 로드하고 전처리하는 데 사용되는 두 가지 중요한 클래스
  • 이들은 모델 학습을 위해 데이터를 효율적으로 처리하고 준비하는 데 필수적

1. Dataset

  • Dataset 클래스는 데이터셋을 나타내며, 이를 커스터마이즈하여 다양한 소스의 데이터를 다룰 수 있도록 합니다.
  • 사용자 정의 데이터셋을 만들기 위해서는 torch.utils.data.Dataset을 상속받아 최소한 두 개의 함수를 오버라이드해야 합니다: __len__()__getitem__().
  • __len__() 함수는 데이터셋의 총 데이터 포인트 수를 반환
  • __getitem__() 함수는 주어진 인덱스에 해당하는 데이터 포인트를 반환해야 합니다. 여기서 데이터 포인트는 보통 텐서(tensor) 형태

1.1. 사용자 정의 데이터셋 예시

from typing import List, Tuple
from torch.utils.data import Dataset
from torch import Tensor
from PIL import Image

class CustomDataset(Dataset):
    def __init__(self, data: List[Tensor], labels: List[int]):
        self.data: List[Tensor] = data
        self.labels: List[int] = labels

    def __len__(self) -> int:
        return len(self.data)

    def __getitem__(self, index: int) -> Tuple[Tensor, int]:
        data_point: Tensor = self.data[index]
        label: int = self.labels[index]
        return data_point, label

2. DataLoader

  • DataLoaderDataset에서 로드된 데이터를 아래와 같이 수행해주는 반복자(iterator)입니다.
    • 배치(batch)로 묶고,
    • 필요에 따라 데이터를 섞어주며(셔플),
    • 다양한 유용한 기능을 제공
  • DataLoader는 모델 학습을 위해 데이터를 배치 단위로 빠르게 로드하고 처리하는 데 도움을 줍니다.

2.1. DataLoader의 주요 파라미터

  • dataset: 로드할 데이터셋. Dataset 클래스의 인스턴스
  • batch_size: 배치 크기. 한 번에 로드할 데이터 포인트의 수
  • shuffle:
    • 매 에폭(epoch)마다 데이터를 섞을지 여부.
      • epoch: 전체 데이터셋이 학습 알고리즘을 통과하는 한 번의 완전한 사이클을 의미
    • 일반적으로 학습 데이터셋에는 True를, 검증/테스트 데이터셋에는 False를 사용
  • num_workers: 데이터 로딩에 사용할 서브 프로세스의 수. 더 빠른 데이터 로딩을 위해 0보다 큰 값을 설정할 수 있습니다.
    • 이 값이 0이면, 메인 프로세스가 모든 데이터 로딩 작업을 수행합니다.
  • collate_fn: 배치 데이터를 어떻게 처리할지 정의하는 함수입니다. 사용자 정의 데이터 처리를 위해 커스터마이즈할 수 있습니다.
pin_memory
  • pin_memory는 데이터 로더가 Tensor를 CPU 메모리에서 GPU 메모리로 전송할 때, 더 빠른 호스트(GPU)-디바이스(CPU) 복사를 가능하게 하는 옵션
  • 이 옵션을 True로 설정하면, DataLoader가 데이터를 미리 고정(pinned) 메모리 영역에 로드
  • 고정 메모리에서는 페이지 폴트(page fault)가 발생하지 않아 메모리 복사가 더 빠르게 이루어질 수 있습니다.
  • pin_memory=True주로 CUDA를 사용하는 GPU 환경에서 성능 향상을 위해 사용
  • CPU-only 환경에서는 이 옵션을 False로 두는 것이 일반적
    • GPU로 데이터를 효율적으로 전송하려는 경우에 유용
  • 메모리는 일반적으로 '페이징'이라는 방식으로 관리
    • 페이징:
      • 운영 체제가 프로그램의 메모리 사용을 더 효율적으로 만들기 위해
      • 메모리를 작은 블록(페이지)으로 나누고, 이를 필요에 따라 디스크와 RAM 사이에서 옮기는 과정
  • 'pin_memory'란, 이러한 페이징 과정에서 메모리 페이지가 디스크로 스왑(교체)되지 않도록 '고정'된 메모리 영역
  • 고정 메모리에서는 데이터가 항상 RAM에 상주하게 되므로, CPU나 GPU가 데이터에 접근할 때 발생할 수 있는 페이지 폴트가 없습니다.
    • 페이지 폴트는 필요한 데이터가 메모리에 없어 디스크에서 불러와야 할 때 발생하는데, 이 과정이 없어지므로 데이터 접근 시간이 단축됩니다.
  • pin_memory=True 설정이 CUDA를 사용하는 GPU 환경에서 성능 향상에 도움이 되는 이유와 CPU-only 환경에서는 이 옵션을 False로 두는 것이 일반적인 이유는 메모리 데이터의 이동 방식과 관련이 깊습니다.
  • CUDA를 사용하는 GPU 환경에서의 성능 향상
    1. 데이터 이동 최적화:
    • GPU를 사용하는 계산에서는 CPU 메모리에서 GPU 메모리로 데이터를 전송해야 합니다.
    • pin_memory=True로 설정하면, 데이터가 고정 메모리에 미리 로드되어, GPU로의 데이터 전송이 효율적으로 이루어짐
    • 고정 메모리는 페이지 폴트가 발생하지 않으므로, 호스트(CPU)에서 디바이스(GPU)로의 데이터 전송이 더 빨라집니다.
    1. 비동기 데이터 전송 지원:
    • CUDA는 비동기적으로 데이터를 GPU로 전송할 수 있는 기능을 제공
    • 데이터가 고정 메모리에 있을 때, CUDA는 CPU의 메인 작업과 동시에 데이터를 GPU로 전송할 수 있어, 전체적인 성능을 향상시킬 수 있습니다.
  • CPU-only 환경에서 pin_memory=False가 일반적인 이유
    1. 불필요한 메모리 고정:
    • CPU-only 환경에서는 데이터를 별도의 장치로 전송할 필요가 없으므로, 메모리를 고정하는 것이 추가적인 이점을 제공하지 않습니다.
    • 오히려 메모리를 고정하는 과정은 추가적인 오버헤드를 발생시킬 수 있습니다.
    1. 메모리 자원의 효율적 사용:
    • 메모리 고정은 사용 가능한 RAM의 일부를 고정 용도로 예약
    • CPU-only 환경에서는 모든 계산이 CPU와 그 메모리 상에서 이루어지므로, 메모리를 더 유연하게 관리할 필요가 있습니다.
    • 고정 메모리를 사용하지 않음으로써 시스템이 메모리를 보다 효율적으로 관리하고 필요에 따라 다른 프로세스와 메모리를 공유할 수 있게 합니다.

  • 페이지 폴트와 메모리 복사의 속도 향상
    • 페이지 폴트는 프로그램이 접근하려는 데이터가 메모리(RAM)에 없을 때 발생하며,
    • 이를 처리하기 위해 운영 체제는 해당 데이터가 저장된 디스크의 위치를 찾아 메모리로 로드하는 과정을 거칩니다.
    • 이 과정은 시간이 많이 걸리는 입출력(I/O) 작업을 필요로 합니다.
    • GPU에서 계산을 수행할 때, 계산에 필요한 데이터를 CPU 메모리에서 GPU 메모리로 복사해야 합니다.
    • pin_memory=True로 설정하면 PyTorch DataLoader는 데이터를 고정 메모리에 로드하여, GPU로의 데이터 전송 시 페이지 폴트를 방지합니다.
    • 고정 메모리에서의 데이터는 이미 RAM에 상주하고 있기 때문에, GPU로 복사할 때 발생할 수 있는 추가적인 지연이 없어 데이터 복사가 더 빠르게 이루어질 수 있습니다.
    • 이는 특히 큰 데이터셋을 GPU에서 빠르게 처리해야 하는 딥러닝과 같은 연산에서 중요한 성능 향상 요소가 될 수 있습니다. 데이터를 GPU로 더 빠르게 전송할 수 있으므로, GPU 연산의 효율성이 증가하고 전체 학습 시간이 단축될 수 있습니다.

2.2. DataLoader 사용 예시

from torch.utils.data import DataLoader

# 가정: CustomDataset은 이미 정의되어 있고, my_dataset은 이를 인스턴스화한 것이다.
data_loader = DataLoader(dataset=my_dataset, batch_size=64, shuffle=True, num_workers=4)

for batch in data_loader:
    data, labels = batch
    # 모델 학습 로직을 여기에 구현
  • 이 예시에서 DataLoadermy_dataset에서 데이터를 로드하고, 64개의 데이터 포인트로 구성된 배치를 생성
  • shuffle=True는 데이터를 섞어 모델 학습이 잘 일반화되도록 돕습니다.
  • num_workers=4는 데이터 로딩을 병렬로 처리하여 속도를 향상시킵니다.
profile
모든 의사 결정 과정을 지나칠 정도로 모두 기록하고, 나중에 스스로 피드백 하는 것
post-custom-banner

0개의 댓글