Membangun data pipeline production: Dataset & DataLoader PyTorch, batching, shuffling, dan prefetch, plus augmentasi dengan torchvision transforms dan Albumentations agar model robust terhadap variasi data nyata.

Sejauh ini kita selalu memakai dataset yang sudah jadi (torchvision.datasets). Di dunia nyata, data datang dalam bentuk folder, CSV, JSON, atau database — dan cara kalian membangun pipeline data menentukan seberapa cepat GPU menganggur dan seberapa baik model generalisasi.
Episode ini membahas dua hal yang tampak sepele tetapi sering menjadi sumber masalah terbesar: bagaimana data mengalir ke model secara efisien, dan bagaimana membuat model tidak menghafal lewat augmentasi yang tepat. Data pipeline yang buruk membuat GPU training dengan harga mahal menganggur; augmentasi yang salah membuat model gagal di lapangan.
Dataset mendefinisikan dua hal: berapa banyak sampel (__len__) dan bagaimana mengambil satu sampel (__getitem__). Mari buat dataset gambar dari folder:
import torch
from torch.utils.data import Dataset
from PIL import Image
class ImageFolderDataset(Dataset):
def __init__(self, filepaths, labels, transform=None):
self.filepaths = filepaths
self.labels = labels
self.transform = transform
def __len__(self):
return len(self.filepaths)
def __getitem__(self, idx):
img = Image.open(self.filepaths[idx]).convert("RGB")
label = self.labels[idx]
if self.transform:
img = self.transform(img)
return img, label
dataset = ImageFolderDataset(filepaths, labels, transform=transform)Kunci performa: __getitem__ harus secepat mungkin — semua preprocessing yang berulang sebaiknya di-cache atau disederhanakan. Operasi berat di sini berjalan untuk setiap sampel di setiap epoch.
DataLoader mengambil Dataset dan mengatur aliran batch:
from torch.utils.data import DataLoader
loader = DataLoader(
dataset,
batch_size=64,
shuffle=True,
num_workers=4,
pin_memory=True,
)Empat parameter yang wajib dipahami:
shuffle=False agar konsisten.num_workers=0 — naikkan bertahap sampai memori cukup.Tip
Cara cepat mendeteksi data pipeline lambat: selama training, lihat utilization GPU (misal nvidia-smi). Jika GPU idle di bawah 80% sementara CPU bekerja keras, naikkan num_workers dan perbesar batch. Jika GPU bekerja keras tapi CPU menganggur, pipeline sudah cukup baik.
Aturan emas: test/validation tidak boleh memakai augmentasi — hanya resizing dan normalisasi. Augmentasi mengubah label secara implisit (rotasi kucing tetap kucing), tetapi membuat evaluasi tidak mewakili data asli.
Pipeline transform yang benar:
from torchvision import transforms
train_transform = transforms.Compose([
transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),
transforms.RandomHorizontalFlip(),
transforms.RandomRotation(10),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
eval_transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])Pola yang umum di industri: Resize sedikit lebih besar lalu CenterCrop untuk evaluasi — memakai area paling informatif secara konsisten.
Torchvision cukup untuk tugas dasar. Albumentations menawarkan augmentasi lebih kaya dan jauh lebih cepat (optimasi C++), terutama untuk transformasi geometris dan pencampuran:
import albumentations as A
train_aug = A.Compose([
A.HorizontalFlip(p=0.5),
A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.1, rotate_limit=15, p=0.5),
A.RandomBrightnessContrast(p=0.3),
A.CoarseDropout(max_holes=8, max_height=16, max_width=16, p=0.3),
])
def apply_aug(image, label):
out = train_aug(image=image)["image"]
return torch.tensor(out, dtype=torch.float32), labelCoarseDropout (juga dikenal sebagai Cutout) memaksa model belajar dari konteks gambar, bukan satu piksel dominan — teknik sederhana yang menambah akurasi dengan murah.
Warning
Saat memakai Albumentations dengan gambar dari PIL atau OpenCV, perhatikan tipe array: PIL membuka gambar sebagai RGB, sedangkan OpenCV membuka sebagai BGR. Albumentations mengasumsikan BGR default (cv2.imread). Konsistensi channel di sini bisa diam-diam menukar merah dan biru — perhatikan output visual sekali saat menguji pipeline.
Untuk training model modern, dua augmentasi berbasis pencampuran sangat populer:
x_mix = a*x1 + (1-a)*x2, label serupa). Melicinkan batas keputusan.Keduanya menurunkan overfit secara dramatis pada data kecil dan murah diterapkan. Albumentations menyediakan variannya, dan implementasi populer ada di timm:
from timm.data import Mixup
mixup_fn = Mixup(mixup_alpha=0.2, cutmix_alpha=1.0, num_classes=10)Satu catatan penting: label menjadi campuran, jadi loss harus soft label-compatible (CrossEntropy bisa, tapi hindari akurasi klasik saat label campur — evaluasi tetap pada data murni).
__getitem__ lambat: membaca disk di tiap epoch tanpa cache membuat GPU menganggur. Pindahkan dataset ke memori atau gunakan format yang cepat dibaca.WeightedRandomSampler agar kelas langka tidak tenggelam.Pada episode 9 ini, kalian telah membangun data pipeline yang benar.
Inti yang harus dibawa pulang:
Dataset = sumber data (__len__, __getitem__); DataLoader = aliran batch.shuffle=True hanya training; num_workers dan pin_memory memaksimalkan utilisasi GPU.Di episode 10 selanjutnya kita akan naik level dari klasifikasi ke object detection & segmentation — YOLO v11/v12, Faster R-CNN, evaluasi mAP, U-Net, dan SAM 2 untuk use case medis dan autonomous driving. Sampai jumpa di episode 10!