Machine Learning bukan lagi teknologi eksklusif untuk peneliti atau perusahaan raksasa. Dengan tools modern seperti TensorFlow dan Keras, developer manapun bisa membangun model AI yang powerful bahkan untuk tugas kompleks seperti klasifikasi gambar.
Dalam artikel ini, kita akan membangun model Convolutional Neural Network (CNN) dari nol untuk mengklasifikasikan gambar kucing vs anjing menggunakan Python dan TensorFlow. Setiap langkah dijelaskan secara detail agar mudah dipahami, bahkan jika kamu baru pertama kali menyentuh machine learning.
1. Memahami Konsep Dasar: Bagaimana Komputer "Melihat" Gambar?
Bagi komputer, gambar hanyalah matriks angka. Sebuah gambar berwarna berukuran 224x224 pixel adalah array 3D berukuran (224, 224, 3) di mana 3 merepresentasikan channel warna RGB (Red, Green, Blue).
# Visualisasi: gambar adalah matriks angka
import numpy as np
from PIL import Image
img = Image.open('kucing.jpg').resize((224, 224))
pixel_array = np.array(img)
print(f"Shape: {pixel_array.shape}") # (224, 224, 3)
print(f"Tipe data: {pixel_array.dtype}") # uint8
print(f"Rentang nilai: {pixel_array.min()} - {pixel_array.max()}") # 0 - 255
Neural network belajar mengenali pola dalam angka-angka ini edge, texture, bentuk yang secara bertahap membentuk fitur-fitur bermakna untuk klasifikasi.
2. Setup Environment & Install Dependencies
Siapkan environment Python dengan library yang dibutuhkan:
# Buat virtual environment
python -m venv ml-env
source ml-env/bin/activate # Linux/macOS
# ml-env\Scripts\activate # Windows
# Install dependencies
pip install tensorflow==2.16.1
pip install matplotlib
pip install numpy
pip install pillow
Verifikasi instalasi TensorFlow:
import tensorflow as tf
print(f"TensorFlow version: {tf.__version__}")
print(f"GPU tersedia: {tf.config.list_physical_devices('GPU')}")
Tips: Jika tidak memiliki GPU, TensorFlow tetap bisa berjalan di CPU. Untuk dataset kecil-menengah, CPU modern sudah cukup memadai. Alternatifnya, gunakan Google Colab untuk mendapatkan akses GPU gratis.
3. Persiapan Dataset
Kita akan menggunakan dataset bawaan TensorFlow yang otomatis di-download:
import tensorflow as tf
import matplotlib.pyplot as plt
# Download dataset langsung dari TensorFlow
dataset_url = "https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip"
path_to_zip = tf.keras.utils.get_file(
'cats_and_dogs.zip',
origin=dataset_url,
extract=True
)
import pathlib
base_dir = pathlib.Path(path_to_zip).parent / 'cats_and_dogs_filtered'
# Buat dataset dari directory
BATCH_SIZE = 32
IMG_SIZE = (160, 160)
train_dataset = tf.keras.utils.image_dataset_from_directory(
base_dir / 'train',
image_size=IMG_SIZE,
batch_size=BATCH_SIZE,
shuffle=True,
seed=42,
)
validation_dataset = tf.keras.utils.image_dataset_from_directory(
base_dir / 'validation',
image_size=IMG_SIZE,
batch_size=BATCH_SIZE,
shuffle=False,
)
# Lihat nama kelas
class_names = train_dataset.class_names
print(f"Kelas: {class_names}") # ['cats', 'dogs']
Visualisasi Sample Dataset
plt.figure(figsize=(12, 8))
for images, labels in train_dataset.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
plt.tight_layout()
plt.savefig('sample_dataset.png', dpi=150)
plt.show()
4. Optimasi Performa Dataset
Teknik penting untuk mempercepat training prefetching dan caching:
# Konfigurasi performa dataset
AUTOTUNE = tf.data.AUTOTUNE
train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
validation_dataset = validation_dataset.cache().prefetch(buffer_size=AUTOTUNE)
Penjelasan:
cache()Simpan dataset di memori setelah epoch pertama, hindari re-read diskshuffle()Acak urutan data setiap epoch untuk mencegah model menghafal urutanprefetch()Load batch berikutnya sementara batch saat ini diproses GPU
5. Membangun Model CNN
Convolutional Neural Network (CNN) adalah arsitektur neural network yang dirancang khusus untuk memproses data visual. Komponen utamanya:
- Conv2D Mendeteksi fitur lokal (edge, texture, pattern)
- MaxPooling2D Mengurangi dimensi sambil mempertahankan fitur penting
- Dense Fully connected layer untuk klasifikasi akhir
- Dropout Regularisasi untuk mencegah overfitting
from tensorflow.keras import layers, models
# Data augmentation layer menambah variasi data training
data_augmentation = tf.keras.Sequential([
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.2),
layers.RandomZoom(0.2),
layers.RandomContrast(0.1),
])
# Membangun model CNN
model = models.Sequential([
# Input dan augmentation
layers.Input(shape=(160, 160, 3)),
data_augmentation,
# Normalisasi pixel values dari [0,255] ke [0,1]
layers.Rescaling(1.0 / 255),
# Block 1: Deteksi fitur dasar (edge, warna)
layers.Conv2D(32, (3, 3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
# Block 2: Deteksi fitur menengah (texture, shape)
layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
# Block 3: Deteksi fitur kompleks (bagian wajah, telinga)
layers.Conv2D(128, (3, 3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
# Block 4: Fitur high-level
layers.Conv2D(256, (3, 3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
# Flatten & Classification
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dropout(0.5), # 50% neuron dimatikan saat training
layers.Dense(1, activation='sigmoid'), # Binary classification
])
model.summary()
Output model.summary() menunjukkan arsitektur lengkap:
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
random_flip (RandomFlip) (None, 160, 160, 3) 0
rescaling (Rescaling) (None, 160, 160, 3) 0
conv2d (Conv2D) (None, 160, 160, 32) 896
batch_normalization (None, 160, 160, 32) 128
max_pooling2d (None, 80, 80, 32) 0
conv2d_1 (Conv2D) (None, 80, 80, 64) 18,496
... ... ...
dense (Dense) (None, 512) 8,389,120
dropout (Dropout) (None, 512) 0
dense_1 (Dense) (None, 1) 513
=================================================================
Total params: 8,409,153 (32.08 MB)
Trainable params: 8,408,989 (32.08 MB)
Non-trainable params: 164 (656.00 B)
_________________________________________________________________
6. Training Model
Compile dan train model dengan callback untuk monitoring:
# Compile model
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='binary_crossentropy',
metrics=['accuracy'],
)
# Callbacks
callbacks = [
# Simpan model terbaik berdasarkan val_accuracy
tf.keras.callbacks.ModelCheckpoint(
'best_model.keras',
monitor='val_accuracy',
save_best_only=True,
verbose=1,
),
# Kurangi learning rate jika val_loss tidak membaik
tf.keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=3,
min_lr=1e-7,
verbose=1,
),
# Hentikan training jika sudah konvergen
tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=7,
restore_best_weights=True,
verbose=1,
),
]
# Training
history = model.fit(
train_dataset,
validation_data=validation_dataset,
epochs=50, # Akan berhenti lebih awal via EarlyStopping
callbacks=callbacks,
)
7. Evaluasi & Visualisasi Hasil
Visualisasikan training history untuk menganalisis performa model:
def plot_training_history(history):
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
# Accuracy
ax1.plot(history.history['accuracy'], label='Training', linewidth=2)
ax1.plot(history.history['val_accuracy'], label='Validation', linewidth=2)
ax1.set_title('Model Accuracy', fontsize=14, fontweight='bold')
ax1.set_xlabel('Epoch')
ax1.set_ylabel('Accuracy')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Loss
ax2.plot(history.history['loss'], label='Training', linewidth=2)
ax2.plot(history.history['val_loss'], label='Validation', linewidth=2)
ax2.set_title('Model Loss', fontsize=14, fontweight='bold')
ax2.set_xlabel('Epoch')
ax2.set_ylabel('Loss')
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('training_history.png', dpi=150, bbox_inches='tight')
plt.show()
plot_training_history(history)
Prediksi pada Gambar Baru
def predict_image(model, image_path):
"""Prediksi apakah gambar adalah kucing atau anjing."""
img = tf.keras.utils.load_img(image_path, target_size=(160, 160))
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Buat batch
prediction = model.predict(img_array)[0][0]
label = "Anjing 🐕" if prediction > 0.5 else "Kucing 🐈"
confidence = prediction if prediction > 0.5 else 1 - prediction
print(f"Prediksi: {label}")
print(f"Confidence: {confidence:.2%}")
plt.imshow(tf.keras.utils.load_img(image_path))
plt.title(f"{label} ({confidence:.1%})")
plt.axis('off')
plt.show()
# Penggunaan
predict_image(model, 'foto_kucing_baru.jpg')
Hasil tipikal: Dengan dataset cats_and_dogs_filtered (~3000 gambar), model CNN sederhana ini bisa mencapai akurasi 85-90% pada validation set. Untuk akurasi lebih tinggi, gunakan transfer learning dengan model pre-trained seperti MobileNetV3 atau EfficientNet.
8. Transfer Learning: Akurasi 95%+ dengan Sedikit Data
Daripada training dari nol, manfaatkan model yang sudah di-train pada jutaan gambar:
# Transfer Learning dengan MobileNetV2
base_model = tf.keras.applications.MobileNetV2(
input_shape=(160, 160, 3),
include_top=False, # Buang classification head
weights='imagenet', # Pre-trained pada 14 juta gambar
)
# Freeze base model jangan update weight-nya
base_model.trainable = False
# Bangun model baru di atasnya
transfer_model = models.Sequential([
layers.Input(shape=(160, 160, 3)),
data_augmentation,
layers.Rescaling(1.0 / 255),
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(256, activation='relu'),
layers.Dropout(0.3),
layers.Dense(1, activation='sigmoid'),
])
transfer_model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='binary_crossentropy',
metrics=['accuracy'],
)
# Training converge lebih cepat!
transfer_history = transfer_model.fit(
train_dataset,
validation_data=validation_dataset,
epochs=15,
callbacks=callbacks,
)
Transfer learning memungkinkan kamu mencapai 95%+ accuracy hanya dengan 15 epoch training dan dataset yang relatif kecil.
Kesimpulan
Machine learning, khususnya image classification, sudah sangat accessible berkat ekosistem Python dan TensorFlow. Dalam artikel ini kita telah membangun pipeline lengkap:
- Persiapan data loading, augmentasi, dan optimasi dataset
- CNN dari nol memahami setiap layer dan fungsinya
- Training & evaluasi dengan callbacks untuk monitoring dan early stopping
- Transfer learning mencapai akurasi tinggi dengan data terbatas
Langkah selanjutnya? Coba deploy model kamu sebagai REST API menggunakan TensorFlow Serving atau FastAPI, atau konversi ke TensorFlow Lite untuk inferensi di mobile device.