Akurasi 0.9067 dari Bagian 3 baru menjawab “berapa banyak yang benar”, belum menjawab “kesalahan seperti apa yang tersisa”. Bagian ini membuka dua lapis evaluasi: confusion matrix yang memetakan arah kesalahan (sehat dikira sakit, atau sebaliknya), lalu keyakinan model pada tiap sampel yang menunjukkan seberapa yakin model saat keliru. Kerangka evaluasinya mengikuti chapter Confusion Matrix dan Metrik Klasifikasi .
Membaca Confusion Matrix #
Matriks 2x2 dari keluaran latih.py dibaca per baris — baris adalah label asli, kolom adalah prediksi:
| pred sehat | pred berbintak | |
|---|---|---|
| label sehat | 35 (benar) | 3 (false positive) |
| label berbintak | 4 (false negative) | 33 (benar) |
Dua jenis kesalahan memiliki konsekuensi yang berbeda pada konteks pertanian:
- False negative (4): daun berbintak diprediksi sehat. Inilah jenis kesalahan yang paling merugikan — penyakit lolos dari deteksi dan bisa menyebar ke tanaman lain di lapangan.
- False positive (3): daun sehat diprediksi berbintak. Petani kehilangan waktu memeriksa ulang satu daun, namun tanaman tidak terabaikan.
Ketika biaya kedua kesalahan timpang seperti ini, akurasi saja tidak cukup — kita perlu metrik yang menghitung kelas berbintak secara khusus.
Metrik untuk Kelas Berbintak #
Dari keempat sel di atas, metrik kelas berbintak dihitung langsung: precision = 33/(33+3) = 0.917, recall = 33/(33+4) = 0.892, dan F1 sebagai rata-rata harmoniknya = 0.904. Angka-angka ini bisa diringkas:
| Metrik | Rumus | Nilai | Makna |
|---|---|---|---|
| Precision | TP / (TP + FP) | 0.917 | dari semua prediksi “berbintak”, 91.7 persen memang sakit |
| Recall | TP / (TP + FN) | 0.892 | dari semua daun sakit, 89.2 persen berhasil terdeteksi |
| F1 | rata-rata harmonik | 0.904 | satu angka penyeimbang precision dan recall |
Recall yang lebih rendah daripada precision menegaskan arah masalahnya: model lebih sering melewatkan daun sakit (4 kasus) daripada salah menandai daun sehat (3 kasus). Pada sistem deteksi penyakit, hubungan ini biasanya dibalik lewat ambang keputusan — menerima lebih banyak false positive demi recall yang lebih tinggi, karena biaya memeriksa ulang jauh lebih murah daripada wabah yang lolos.
Prediksi per Sampel dan Keyakinan #
Angka agregat menyembunyikan detail; prediksi per sampel menampakkannya. Potongan berikut memuat checkpoint Bagian 3, memprediksi lima sampel uji pertama, lalu mencetak keyakinan model dari peluang softmax. Simpan potongan ini sebagai src/prediksi_coba.py (letaknya harus di dalam folder src/ agar pernyataan import dataset dan import model ditemukan), lalu jalankan dari folder proyek:
import torch
from dataset import indeks_latih_uji, muat_daun
from model import CNNDaun
NAMA_KELAS = ("sehat", "berbintak")
X, y, _ = muat_daun()
_, idx_uji = indeks_latih_uji(y)
checkpoint = torch.load("/tmp/model_daun.pt", weights_only=True)
model = CNNDaun()
model.load_state_dict(checkpoint["state_dict"])
model.eval()
with torch.no_grad():
peluang = torch.softmax(model(torch.tensor(X[idx_uji[:5]])), dim=1)
print("sampel | label | prediksi | keyakinan")
for i in range(5):
kelas = int(peluang[i].argmax())
print(f"{i:6d} | {NAMA_KELAS[y[idx_uji[i]]]:10s} | "
f"{NAMA_KELAS[kelas]:10s} | {peluang[i, kelas]:.3f}")python3 src/prediksi_coba.pyOutput yang Dihasilkan:
sampel | label | prediksi | keyakinan
0 | berbintak | berbintak | 0.964
1 | sehat | berbintak | 0.642
2 | sehat | berbintak | 0.684
3 | sehat | sehat | 0.727
4 | sehat | sehat | 0.943Mari kita telaah potongan di atas baris per baris:
torch.load(..., weights_only=True): hanya tensor yang dimuat dari checkpoint — mode aman bila checkpoint berasal dari sumber lain.model.eval()dantorch.no_grad(): Dropout dimatikan dan pelacakan gradien dilepas; tanpa keduanya hasil inferensi bisa berubah-ubah antar pemanggilan.torch.softmax(..., dim=1): dua logits diubah menjadi dua peluang yang berjumlah 1 per sampel;argmaxmemilih kelas, nilai peluangnya menjadi keyakinan.X[idx_uji[:5]]: lima sampel diambil dari indeks uji hasil pembagian Bagian 2 — sama persis dengan yang dievaluasilatih.py, sehingga label dan prediksi dapat dibandingkan langsung.
Keluarannya informatif: prediksi benar umumnya datang dengan keyakinan tinggi (0.964 dan 0.943), sedangkan dua sampel yang keliru (nomor 1 dan 2) hanya membawa keyakinan 0.642 dan 0.684. Model seolah tahu ia tidak yakin — perilaku yang membuka jalur praktis: sampel dengan keyakinan rendah bisa dialihkan ke pemeriksaan manusia, memanfaatkan softmax lebih jauh daripada sekadar argmax.
Tujuh kesalahan kini terlihat arah dan keyakinannya. Namun pertanyaan paling penting masih terbuka: kesalahan itu terjadi pada daun seperti apa? Bagian berikutnya membedah sampel salah satu per satu lalu membuktikan polanya lewat statistik bercak.