Topik ini membahas data augmentation, yakni pengayaan data latih dengan variasi sintetis yang dibuat dari data yang sudah ada. Flip, crop, dan ColorJitter pada torchvision dibahas bersama bukti bahwa hasilnya dapat direproduksi dengan benih, serta alasan transformasi acak hanya dipasang pada pipeline data latih.
Mengapa data citra perlu diperkaya#
Jaringan CNN menyimpan banyak parameter, sehingga dataset citra yang terlalu kecil cepat dihafal. Model yang menghafal menunjukkan overfitting, yakni keadaan ketika loss pada data latih terus turun sementara kinerjanya pada data baru tidak membaik. Memperbanyak variasi data latih adalah penangkalnya yang paling langsung.
Data augmentation membuat variasi baru tanpa mengumpulkan citra tambahan. Citra yang dibalik, digeser, dipotong pada posisi berbeda, atau dicerahkan tetap mewakili objek yang sama, sehingga setiap variasi itu berfungsi sebagai contoh baru dengan label yang tak berubah. Syaratnya hanya satu, yaitu transformasi tidak boleh mengubah makna label. Membalik citra pemandangan masih aman dilakukan, sedangkan membalik citra angka tulisan tangan menghasilkan cermin yang tidak muncul pada data aslinya.
Tiga transformasi acak yang umum#
torchvision menyediakan transformasi acak yang memilih parameternya sendiri setiap kali dipanggil. RandomHorizontalFlip(p=0.5) membalik citra secara horizontal dengan peluang p. RandomCrop(28, padding=4) menambahkan bingkai nol selebar 4 piksel pada setiap sisi, lalu memotong jendela 28x28 pada posisi acak, sehingga posisi objek di dalam jendela ikut bergeser. ColorJitter mengubah kecerahan dan kontras di dalam rentang yang diberikan, dan parameter saturasi serta hue-nya hanya bermakna untuk citra RGB. Ketiganya dirangkai dengan transforms.Compose, sebagaimana urutan transformasi dirangkai Compose pada pipeline pemuatan data.
Contoh di topik ini menggunakan citra RGB 32x32 yang dibuat di memori dengan Pillow, yaitu latar terang, satu persegi biru, dan satu lingkaran merah. Citra buatan semacam ini cukup untuk memeriksa perilaku transformasi tanpa perlu mengunduh dataset.
Demonstrasi dan reproduksibilitas#
Program berikut menerapkan pipeline augmentasi pada citra buatan dua kali dengan benih yang sama dan satu kali dengan benih berbeda, lalu mencetak rata-rata setiap kanal sebagai jejak perubahannya.
import torch
from PIL import Image, ImageDraw
from torchvision import transforms
# citra PIL 32x32 RGB dibuat di memori: latar terang, persegi biru, lingkaran merah
img = Image.new("RGB", (32, 32), (230, 230, 230))
draw = ImageDraw.Draw(img)
draw.rectangle([4, 4, 14, 24], fill=(40, 60, 160))
draw.ellipse([18, 8, 30, 20], fill=(160, 40, 40))
ke_tensor = transforms.ToTensor()
asli = ke_tensor(img)
print("citra asli :", tuple(asli.shape), asli.mean(dim=(1, 2)))
# pipeline augmentasi untuk data train
augmentasi = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomCrop(28, padding=4),
transforms.ColorJitter(brightness=0.4, contrast=0.4),
])
torch.manual_seed(0)
aug1 = ke_tensor(augmentasi(img))
print("augmentasi 1:", tuple(aug1.shape), aug1.mean(dim=(1, 2)))
# benih yang sama menghasilkan hasil augmentasi yang identik
torch.manual_seed(0)
aug2 = ke_tensor(augmentasi(img))
print("benih sama, hasil sama :", torch.equal(aug1, aug2))
# benih berbeda menghasilkan variasi acak yang berbeda
torch.manual_seed(1)
aug3 = ke_tensor(augmentasi(img))
print("benih beda, hasil beda :", not torch.equal(aug1, aug3))
print("augmentasi 3:", tuple(aug3.shape), aug3.mean(dim=(1, 2)))citra asli : (3, 32, 32) tensor([0.6993, 0.6577, 0.7462])
augmentasi 1: (3, 28, 28) tensor([0.5664, 0.4870, 0.5970])
benih sama, hasil sama : True
benih beda, hasil beda : True
augmentasi 3: (3, 28, 28) tensor([0.5541, 0.5148, 0.6359])Rata-rata kanal berubah dari citra asli (3, 32, 32) menjadi hasil augmentasi (3, 28, 28) karena jendela crop memilih posisi berbeda dan ColorJitter menggeser kecerahannya. Dua baris berikutnya menegaskan perilaku yang diharapkan, yaitu benih yang sama menghasilkan augmentasi yang identik, sedangkan benih yang berbeda menghasilkan variasi berbeda. Dengan benih tetap, seluruh pipeline yang tampak acak ini dapat direproduksi sepenuhnya.
Mengapa augmentasi hanya untuk data train#
Evaluasi menilai kemampuan model pada data apa adanya. Augmentasi acak menambah kebisingan pada metrik, sehingga dua eksekusi evaluasi yang sama persis dapat melaporkan akurasi berbeda hanya karena transformasi acaknya berbeda. Perbandingan antara eksperimen menjadi sah kembali apabila data evaluasi selalu diproses dengan pipeline yang deterministik.
Konvensi yang mengikutinya sederhana. Pipeline data latih memuat transformasi acak ditambah ToTensor, sedangkan pipeline data evaluasi memuat ToTensor dan normalisasi saja. Pemisahan ini sejalan dengan disiplin pemisahan data latih dan data uji, karena augmentasi adalah bagian dari proses pelatihan, bukan bagian dari pengukuran.
Kesalahan umum#
Ukuran crop yang lebih besar dari citranya menolak bekerja. RandomCrop(40) pada citra 32x32 memicu error berikut, dan perbaikannya adalah menambahkan argumen padding yang cukup atau menurunkan ukuran crop.
from PIL import Image
from torchvision import transforms
img = Image.new("RGB", (32, 32), (230, 230, 230))
try:
transforms.RandomCrop(40)(img) # 40 > 32 dan tanpa padding
except ValueError as e:
print("ValueError:", e)ValueError: Required crop size (40, 40) is larger than input image size (32, 32)Kesalahan kedua adalah mengharapkan hasil yang sama tanpa menetapkan benih. Tanpa torch.manual_seed, urutan flip, posisi crop, dan besar perubahan kecerahan berbeda pada setiap eksekusi, sehingga eksperimen menjadi sulit dicocokkan. Tetapkan benih di awal skrip, sebagaimana dilakukan program di atas, dan jalankan dua kali untuk memastikan keluarannya identik sebelum ditempelkan ke dokumentasi.
Ringkasan#
- Augmentasi data memperbanyak variasi latih tanpa mengumpulkan citra baru, dengan syarat transformasinya tidak mengubah label.
RandomHorizontalFlip,RandomCrop, danColorJittermemilih parameternya sendiri setiap dipanggil dan dirangkai dengantransforms.Compose.- Benih yang tetap membuat pipeline acak dapat direproduksi, sedangkan benih yang berbeda menghasilkan variasi berbeda.
- Transformasi acak dipasang hanya pada data latih, sedangkan data evaluasi diproses dengan pipeline deterministik.
Referensi#
- torchvision.transforms — PyTorch — Daftar transformasi beserta perbedaan transformasi acak dan deterministik.
- ColorJitter — PyTorch — Dokumentasi parameter kecerahan, kontras, saturasi, dan hue.