Sitemap

Klasifikasi Gambar dengan CNN — Part 2

6 min readAug 1, 2026

--

Pada part 1, kita sudah membahas pengenai tool-tool apa saja yang akan kita gunakan untuk klasifikasi gambar, pada part 2 kita akan belajar bagaimana memuat (load) dataset agar AI bisa mengkonsumsi data yang sudah kita siapkan.

Objektif

  • Download Dataset
  • Image Transform

Penjelasan Dataset

Temen-temen bisa bayangin seorang ibu yang ingin memasak makanan di dapur, sudah punya alat-alat- yang canggih, punya dapur yang nyaman dan hal lainnya yang mendukung ibu untuk memasak tapi ada satu hal yang tidak dimiliki, yaitu bahan-bahan yang berkualitas, pasti hasil masakannya pun tidak maksimal, begitupun pada AI. Data adalah ibarat bahan makanan, kualitas data akan sangat berpengaruh pada kualitas kecerdasan AI. Pada postingan kali ini, saya akan membahas mengolah dataset agar dataset yang digunakan bisa diolah dengan baik.

Jadi, Apa Itu Dataset?

Simpelnya, dataset adalah kumpulan data yang bisa berupa angka, gambar, teks, suara, pokoknya segala rekaman informasi yang disusun biar bisa “dimakan” mesin. Struktur dasarnya begini:

  • Baris (sampel) :Satu observasi utuh. Misalnya, satu pelanggan, satu foto kucing, atau satu kalimat ulasan.
  • Kolom (fitur): Ciri-ciri dari tiap observasi. Bisa umur, warna pixel, kata kunci.
  • Label: Jawaban yang ingin si mesin tebak. Ada di supervised learning, kayak “review positif/review negatif”.
  • Metadata: Keterangan tambahan yang sering terlupakan, tapi penting banget buat audit kapan data dikumpulkan, dari mana asalnya, versi berapa.

Dataset juga punya berbagai “wujud” sesuai data modality-nya:

  • Tabular (tabel biasa seperti CSV)
  • Gambar (pixel grid, label bisa kelas atau bounding box)
  • Teks (dokumen atau token)
  • Time series (data waktu berurutan, contoh: suhu harian)
  • Graph (simpul dan sisi, seperti jaringan pertemanan)
  • Multimodal (gabungan gambar + teks)

Struktur Dataset

  • Training set: Sebagai bahan belajar si mesin.
  • Validation set: Untuk mem-validasi hasil dari pembelajaran, lalu melakukan koreksi.
  • Test set: Untuk menguji model yang sudah jadi.

Biasanya pembagian dataset itu sebesar 70% untuk data training, 15% untuk data validation, dan 15% lagi untuk data testing. Kamu bisa bayangkan seperti ini, misal ada 100 gambar kucing, dan 100 gambar anjing, 70 gambar dari setiap kelas adala data untuk diplejari mesin, mesin tidak akan melihat data testing, setiap kali mesin belajar (1 epoch), mesin akan memvalidasi gambar tersebut dengan data validation. Setelah mesin selesai belajar, kamu bisa test si mesin dengan data testing.

Contoh, PlantVillage Dataset

Plant Village Dataset adalah kumpulan data gambar daun yang telah dikategorikan berdasarkan kondisi kesehatannya, seperti:

  • Daun sehat
  • Daun rusak
  • Daun terserang penyakit
  • Dan lain sebagainya

AI akan mengonsumsi data-data gambar ini sebagai bahan pembelajaran agar mampu memahami perbedaan dari setiap kategori (classes) yang ada.

Get Zulfikar Chamim’s stories in your inbox

Join Medium for free to get updates from this writer.

Untuk mendownload dataset-nya, gunakan kode berikut:

path = kagglehub.dataset_download('abdallahalidev/plantvillage-dataset')

Setelah berhasil didownload, kamu bisa mengecek lokasi penyimpanan dataset dengan memanggil variabel path. Contoh hasilnya akan tampak seperti ini:

/kaggle/input/plantvillage-dataset

Ini adalah path absolut dari dataset yang berhasil kamu download. Path ini nantinya akan kamu gunakan untuk memuat data ke dalam program.

Augmentasi Gambar (Image Augmentation)

Jika semua gambar untuk latihan memiliki ukuran yang sama, pencahayaan sempurna, dan posisi tegak lurus, model kalian akan menjadi “manja”. Ketika dihadapkan pada gambar tumbuhan yang miring atau gelap di dunia nyata, performanya akan buruk.

Press enter or click to view image in full size
Contoh Image Augmentation (https://www.ibm.com)

Disinilah data augmentation berperan, kamu menciptakan variasi buatan dari data yang ada agar model belajar fitur yang generalizable. Coba kamu perhatikan kode di bawah ini.

train_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomVerticalFlip(p=0.3),
transforms.RandomRotation(30),
transforms.RandomAffine(degrees=0, translate=(0.1, 0.1)),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
val_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])

train_transform

transforms.Resize((224, 224))
Apa
: Mengubah semua gambar ke ukuran 224×224 piksel.
Kenapa 224? Ini adalah ukuran input standar untuk arsitektur populer seperti ResNet, VGG, dan EfficientNet. Konsistensi ukuran penting karena model neural network membutuhkan input dengan dimensi yang seragam

transforms.RandomHorizontalFlip(p=0.5)
Apa: Membalik gambar secara horizontal (seperti efek cermin) dengan probabilitas 50%.
Kenapa? Banyak objek di dunia nyata tidak selalu menghadap ke arah yang sama. Ini mengajarkan model bahwa kucing yang menghadap kiri dan kanan tetaplah kucing.

transforms.RandomVerticalFlip(p=0.3)
Apa: Membalik gambar secara vertikal dengan probabilitas 30%.
Catatan: Hati-hati dengan augmentasi ini! Untuk dataset seperti objek darat (mobil, manusia), flipping vertikal mungkin tidak realistis karena objek tidak pernah terbalik. Tapi untuk dataset seperti gambar daun atau tumbuhan ini sangat berguna.

transforms.RandomRotation(30)
Apa: Memutar gambar hingga 30 derajat (searah atau berlawanan jarum jam).
Kenapa? Objek di dunia nyata bisa muncul dari berbagai sudut. Ini membantu model menjadi rotation-invariant.

transforms.RandomAffine(degrees=0, translate=(0.1, 0.1))
Apa: Transformasi affine dengan translasi (pergeseran) hingga 10% dari ukuran gambar.
Parameter “degrees=0”: Tidak ada rotasi tambahan (karena sudah ada sebelumnya).
Parameter “translate=(0.1, 0.1)”: Gambar bisa bergeser 10% ke kiri/kanan dan 10% ke atas/bawah. Ini mensimulasikan objek yang tidak selalu berada di tengah frame.

transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2)
Apa: Mengubah kecerahan, kontras, dan saturasi secara acak dengan faktor ±20%.
Kenapa? Kondisi pencahayaan di dunia nyata sangat bervariasi — dari siang terang hingga senja redup. Augmentasi ini memaksa model untuk fokus pada bentuk dan tekstur, bukan pada warna absolut.

transforms.RandomResizedCrop(224, scale=(0.8, 1.0))
Apa: Memotong area acak dari gambar (antara 80–100% dari ukuran asli), lalu meresize-nya kembali ke 224×224.
Kenapa? Ini adalah teknik augmentasi paling powerful. Model dipaksa untuk mengenali objek meskipun hanya sebagian yang terlihat. Ini juga membantu mengurangi overfitting terhadap background.

transforms.ToTensor()
Apa: Mengubah gambar dari format PIL/NumPy (H×W×C) menjadi Tensor PyTorch (C×H×W) dengan nilai piksel dari 0–255 menjadi 0.0–1.0.
Penting: Semua transformasi sebelumnya beroperasi pada format PIL, tapi model PyTorch membutuhkan Tensor.

transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
Apa: Normalisasi dengan mean dan standar deviasi dari dataset ImageNet.
Rumus: (x — mean) / std
Kenapa nilai ini? Ini adalah statistik ImageNet yang sudah terbukti efektif. Normalisasi membuat distribusi data memiliki mean=0 dan std=1 di setiap channel, yang mempercepat konvergensi selama training.

val_transform

Mengapa tidak pakai augmentasi?
Augmentasi adalah teknik untuk meningkatkan variasi data training. Pada saat validasi, kita ingin mengukur performa model pada data “asli” yang stabil dan konsisten. Menggunakan augmentasi di sini akan membuat metrik evaluasi menjadi tidak reliable (karena setiap epoch hasilnya berbeda).

Mengapa normalisasi tetap sama?
Karena model belajar pada data yang dinormalisasi. Agar prediksi konsisten, data validasi harus melalui preprocessing yang identik dengan training.

Load Dataset dan Objek Transformnya

Setelah kita buat objek untuk transformnya yaitu train_transform dan val_transform , selanjutnya kita load objek tersebut beserta datasetnya, kamu bisa lihat kode ini,

dataset = datasets.ImageFolder(root=path + "/plantvillage dataset/color", transform=train_transform)

print(f"Total images: {len(dataset)}")
print(f"Classes: {dataset.classes}")
print(f"Number of classes: {len(dataset.classes)}")

Dari kode di atas, kita load dataset ke dalam variabel dataset beserta objek transformnya, outputnya seperti ini

Total images: 54305
Classes: ['Apple___Apple_scab', 'Apple___Black_rot', 'Apple___Cedar_apple_rust', 'Apple___healthy', 'Blueberry___healthy', 'Cherry_(including_sour)___Powdery_mildew', 'Cherry_(including_sour)___healthy', 'Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot', 'Corn_(maize)___Common_rust_', 'Corn_(maize)___Northern_Leaf_Blight', 'Corn_(maize)___healthy', 'Grape___Black_rot', 'Grape___Esca_(Black_Measles)', 'Grape___Leaf_blight_(Isariopsis_Leaf_Spot)', 'Grape___healthy', 'Orange___Haunglongbing_(Citrus_greening)', 'Peach___Bacterial_spot', 'Peach___healthy', 'Pepper,_bell___Bacterial_spot', 'Pepper,_bell___healthy', 'Potato___Early_blight', 'Potato___Late_blight', 'Potato___healthy', 'Raspberry___healthy', 'Soybean___healthy', 'Squash___Powdery_mildew', 'Strawberry___Leaf_scorch', 'Strawberry___healthy', 'Tomato___Bacterial_spot', 'Tomato___Early_blight', 'Tomato___Late_blight', 'Tomato___Leaf_Mold', 'Tomato___Septoria_leaf_spot', 'Tomato___Spider_mites Two-spotted_spider_mite', 'Tomato___Target_Spot', 'Tomato___Tomato_Yellow_Leaf_Curl_Virus', 'Tomato___Tomato_mosaic_virus', 'Tomato___healthy']
Number of classes: 38

Jumlah class ada 38, jadi nanti output yang dihasilkan adalah probabilitas dari 38 kelas tersebut. Selanjutnya kita akan membagi data tersebut menjadi 2 bagian, untuk data training, dan data validation, mengapa tidak ada testing? kita akan ambil data testingnya secara random di luar datasetnya.

Skema pembagian datanya adalah 80% data testing dan 20% data validation, berikut kodenya

train_size = int(0.8 * len(dataset))
val_size = len(dataset) - train_size
train_dataset, val_dataset = random_split(dataset, [train_size, val_size])

val_dataset.dataset.transform = val_transform

Selanjutnya kita load data nya ke dalam masing-masing kategorinya dengan menggunakan DataLoader milik Pytorch, berikut kodenya

train_loader = DataLoader(
dataset=train_dataset,
batch_size=64,
shuffle=True,
num_workers=2,
pin_memory=True
)

val_loader = DataLoader(
dataset=val_dataset,
batch_size=64,
shuffle=False,
num_workers=2,
pin_memory=True
)

print(f"Train batches: {len(train_loader)}, Val batches: {len(val_loader)}")

Kode di atas terlihat rumit, gampangnya adalah kita load data ke masing-masing kategorinya, lalu setiap kategorinya memiliki beberapa parameter yang sama, ini penjelasannya

  • dataset adalah target data yang akan kita load (path file nya)
  • batch_size adalah jumlah sampel yang diproses setiap batchnya, semakin besar akan semakin cepat namun memakan RAM
  • shuffle adalah boolean yang menyatakan data nya diacak atau tidak, untuk training kita buat True agar model tidak mempelajari pola urutan datanya.
  • num_worker adalah jumlah proses paralelnya
  • pin_memory adalah boolean yang menyatakan datanya akan disimpan di RAM atau tidak, tapi ini hanya berfungsi pada GPU ya

Okay, untuk saat ini seperti itu dulu, kita akan lanjut ke part 3, see ya.

--

--