Level 4: 실전 프로젝트
🚀

Level 4

데이터 로딩

Dataset, DataLoader, transforms 사용법

약 5분
데이터 로딩 강의 영상
강의 영상 보기 (새 탭에서 재생)YouTube

📓Google Colab에서 실습하기

이 레슨은 PyTorch/GPU가 필요합니다. 노트북을 다운로드 후 Google Colab에서 열어주세요.

학습 내용

데이터 로딩

학습 목표

이 레슨을 완료하면:

  • Dataset과 DataLoader의 역할과 관계를 이해합니다
  • 커스텀 Dataset 클래스를 직접 구현합니다
  • transforms를 활용한 데이터 증강의 원리를 설명합니다
  • 효율적인 데이터 파이프라인을 설계합니다

데이터 로딩이 왜 중요한가?

비유: 아무리 좋은 요리사(모델)라도 재료(데이터)가 제때 공급되지 않으면 요리를 할 수 없습니다. GPU가 아무리 빨라도 데이터가 느리게 도착하면 GPU는 대부분의 시간을 기다리며 낭비합니다. 효율적인 데이터 로딩은 학습 속도에 직접적인 영향을 미칩니다.

데이터 로딩 파이프라인 전체 흐름

단계구성 요소역할비유
1원본 데이터디스크에 저장된 파일창고의 원재료
2Dataset데이터 접근 방법 정의재료 꺼내기 규칙
3transforms전처리 및 변환재료 손질
4DataLoader배치 묶기, 셔플, 병렬 처리컨베이어 벨트
5모델 학습배치 단위 학습요리 시작

Dataset 클래스 이해하기

Dataset은 "데이터 하나를 어떻게 가져올 것인가"를 정의하는 클래스입니다.

반드시 구현해야 하는 메서드

메서드역할반환값
init데이터 경로, 변환 등 초기 설정없음
len데이터셋의 총 크기정수
getitem인덱스로 데이터 1개 가져오기(입력, 라벨) 튜플
python
⚠️ 로컬 실행 필요
from torch.utils.data import Dataset import torch class MyDataset(Dataset): def __init__(self, data, labels, transform=None): """데이터셋 초기화 - 데이터를 메모리에 올리거나 경로를 저장""" self.data = data self.labels = labels self.transform = transform def __len__(self): """데이터셋 크기 반환 - DataLoader가 전체 크기를 알아야 배치를 나눌 수 있음""" return len(self.data) def __getitem__(self, idx): """인덱스로 데이터 1개를 가져옴 - DataLoader가 이 메서드를 반복 호출""" x = self.data[idx] y = self.labels[idx] # 변환(전처리)이 정의되어 있으면 적용 if self.transform: x = self.transform(x) return x, y

왜 __getitem__이 핵심인가?

DataLoader는 내부적으로 인덱스를 생성하고, 각 인덱스에 대해 __getitem__을 호출합니다. 이 메서드가 효율적이지 않으면 전체 학습 속도가 느려집니다.


DataLoader 상세 설명

비유: DataLoader는 레스토랑의 웨이터입니다. 주방(Dataset)에서 음식(데이터)을 가져와 테이블(모델)에 배달하는데, 한 번에 여러 접시(배치)를 나르고, 매번 다른 메뉴 순서(셔플)로 서빙합니다.

python
⚠️ 로컬 실행 필요
from torch.utils.data import DataLoader train_loader = DataLoader( dataset=train_dataset, # 위에서 만든 Dataset 객체 batch_size=64, # 한 번에 처리할 데이터 수 shuffle=True, # 매 에폭마다 순서를 섞을지 여부 num_workers=4, # 데이터 로딩에 사용할 프로세스 수 pin_memory=True, # GPU 전송 최적화 (CUDA 사용 시) drop_last=True # 마지막 불완전 배치를 버릴지 여부 )

DataLoader 파라미터 상세

파라미터기본값설명
batch_size1배치 크기메모리 허용 범위에서 크게 설정
shuffleFalse데이터 섞기훈련: True, 테스트: False
num_workers0병렬 로딩 프로세스CPU 코어 수의 2~4배 시도
pin_memoryFalseGPU 전송 최적화GPU 사용 시 True 권장
drop_lastFalse마지막 불완전 배치 처리BatchNorm 사용 시 True 권장

왜 shuffle이 중요한가?

셔플을 하지 않으면, 모델이 데이터의 순서에서 패턴을 학습할 수 있습니다. 예를 들어 고양이 이미지가 앞에, 개 이미지가 뒤에 몰려 있으면 모델은 "앞쪽 = 고양이"라는 잘못된 규칙을 학습할 수 있습니다.

DataLoader 사용 패턴

python
# 기본 사용법: for 문으로 배치를 하나씩 가져옴 for batch_idx, (data, target) in enumerate(train_loader): # data 크기: [batch_size, channels, height, width] # target 크기: [batch_size] data, target = data.to(device), target.to(device) # ... 학습 코드 ... if batch_idx % 100 == 0: print("Batch {}/{}".format(batch_idx, len(train_loader)))

transforms: 데이터 변환과 증강

기본 변환

모든 이미지 데이터에 필수적으로 적용하는 변환입니다.

python
from torchvision import transforms # 기본 변환 파이프라인 basic_transform = transforms.Compose([ transforms.Resize((224, 224)), # 크기 통일 (모델 입력 크기에 맞춤) transforms.ToTensor(), # PIL 이미지 -> PyTorch 텐서 (0~1) transforms.Normalize( # 정규화 mean=[0.485, 0.456, 0.406], # ImageNet 평균 std=[0.229, 0.224, 0.225] # ImageNet 표준편차 ) ])

데이터 증강 (Data Augmentation)

비유: 데이터 증강은 "같은 시험 문제를 조금씩 변형해서 연습량을 늘리는 것"입니다. 고양이 사진을 뒤집거나, 밝기를 바꾸거나, 약간 회전시키면 모델 입장에서는 새로운 데이터입니다.

python
# 훈련용 변환: 증강 포함 train_transform = transforms.Compose([ transforms.RandomHorizontalFlip(p=0.5), # 50% 확률로 좌우 반전 transforms.RandomRotation(15), # -15도 ~ +15도 무작위 회전 transforms.RandomCrop(32, padding=4), # 패딩 후 무작위 자르기 transforms.ColorJitter( # 색상 변화 brightness=0.2, # 밝기 +/- 20% contrast=0.2, # 대비 +/- 20% saturation=0.2 # 채도 +/- 20% ), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)) ]) # 테스트용 변환: 증강 없음 (공정한 평가) test_transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)) ])

왜 테스트 데이터에는 증강을 적용하지 않는가?

테스트는 모델의 "진짜 실력"을 측정하는 것입니다. 테스트 데이터에 무작위 변환을 적용하면 매번 다른 결과가 나와서 공정한 평가가 불가능합니다.

변환훈련 시테스트 시이유
RandomHorizontalFlip적용미적용데이터 다양성 증가
RandomRotation적용미적용회전에 강건해지도록
ToTensor적용적용형식 변환 (필수)
Normalize적용적용분포 통일 (필수)

실전 예제 1: 이미지 폴더 Dataset

폴더 이름이 클래스 라벨이 되는 구조는 실무에서 가장 흔합니다.

python
# 폴더 구조 예시: # data/ # train/ # cat/ # cat001.jpg, cat002.jpg, ... # dog/ # dog001.jpg, dog002.jpg, ... # test/ # cat/ # cat101.jpg, ... # dog/ # dog101.jpg, ... from torchvision.datasets import ImageFolder # ImageFolder는 폴더 이름을 자동으로 클래스 라벨로 사용합니다 train_dataset = ImageFolder( root="data/train", transform=train_transform ) print(train_dataset.classes) # ["cat", "dog"] print(train_dataset.class_to_idx) # {"cat": 0, "dog": 1} print("Total images:", len(train_dataset)) # 폴더 내 전체 이미지 수

실전 예제 2: CSV 데이터 로딩

python
import pandas as pd class CSVDataset(Dataset): def __init__(self, csv_file, feature_cols, label_col): """CSV 파일에서 데이터를 로드하는 커스텀 Dataset""" self.df = pd.read_csv(csv_file) self.features = self.df[feature_cols].values self.labels = self.df[label_col].values def __len__(self): return len(self.df) def __getitem__(self, idx): x = torch.tensor(self.features[idx], dtype=torch.float32) y = torch.tensor(self.labels[idx], dtype=torch.long) return x, y # 사용 예시 dataset = CSVDataset( csv_file="data.csv", feature_cols=["age", "income", "score"], label_col="target" ) loader = DataLoader(dataset, batch_size=32, shuffle=True)

데이터셋 분할: 훈련/검증 나누기

python
⚠️ 로컬 실행 필요
from torch.utils.data import random_split # 전체 데이터를 80% 훈련, 20% 검증으로 분할 full_dataset = MyDataset(data, labels, transform=train_transform) train_size = int(0.8 * len(full_dataset)) val_size = len(full_dataset) - train_size train_dataset, val_dataset = random_split(full_dataset, [train_size, val_size]) # 각각 DataLoader 생성 train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)

핵심 요약

개념설명비유
Dataset데이터 1개를 가져오는 방법 정의재료 꺼내기 규칙
DataLoader배치 묶기, 셔플, 병렬 로딩컨베이어 벨트
transforms전처리 및 데이터 증강재료 손질 과정
ImageFolder폴더 구조 기반 이미지 로딩자동 분류 시스템
random_split데이터셋 분할재료를 훈련/검증용으로 나누기

학습 체크리스트

  • Dataset의 필수 메서드 3가지(init, len, getitem)를 안다
  • DataLoader의 주요 파라미터(batch_size, shuffle, num_workers)를 설명할 수 있다
  • 훈련 데이터에만 증강을 적용하는 이유를 안다
  • ImageFolder의 사용법을 이해한다
  • random_split으로 데이터를 분할하는 방법을 안다
  • num_workers와 pin_memory의 역할을 설명할 수 있다

레슨 정보

레벨
Level 4: 실전 프로젝트
예상 소요 시간
약 5분
참고 영상
YouTube 링크

💡실습 환경 안내

이 레벨은 PyTorch/GPU가 필요하여 Google Colab 사용을 권장합니다.

Colab은 무료 GPU를 제공하여 PyTorch, CNN, Transformer 등을 실행할 수 있습니다.