Rekan ArtonLabs, kalau Anda ingin komputer mengenali benda di foto atau kamera tanpa riset bertahun-tahun, YOLO adalah jalan pintas yang jujur.
YOLO membuat deteksi objek, yaitu menemukan dan mengotaki benda di dalam gambar, menjadi pekerjaan yang bisa diselesaikan dalam satu sore. Pustaka Ultralytics menyatukan model, pelatihan, dan inferensi dalam beberapa baris Python. Tulisan ini memasangnya, menjalankan deteksi dengan model siap pakai, melatih dengan data Anda sendiri, dan menjalankannya di server tanpa GPU, termasuk angka-angka yang realistis soal kecepatan.
Daftar Isi
- Instalasi
- Deteksi Pertama dengan Model Siap Pakai
- Menyiapkan Dataset Sendiri
- Melatih
- Membaca Hasil Evaluasi
- Inferensi di CPU dan Ekspor ONNX
- Menjadikannya Layanan
- Penutup
Instalasi
python3 -m venv .venv && source .venv/bin/activate
pip install -U ultralytics
Paket ini menarik PyTorch. Di server tanpa GPU, pasang PyTorch versi CPU lebih dulu dari indeks resminya agar unduhannya ratusan megabyte, bukan beberapa gigabyte, lalu baru ultralytics. Dokumentasi terkini memakai yolo26n.pt sebagai model bawaan; huruf n berarti nano, varian terkecil dan tercepat, dan ada varian s, m, l, x yang lebih akurat dan lebih lambat.
Deteksi Pertama dengan Model Siap Pakai
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # diunduh otomatis saat pertama dipakai
hasil = model("https://ultralytics.com/images/bus.jpg")
for r in hasil:
for kotak in r.boxes:
print(r.names[int(kotak.cls)], float(kotak.conf), kotak.xyxy.tolist())
hasil[0].save("hasil.jpg")
Model bawaan dilatih pada 80 kelas umum (orang, mobil, kursi, dan seterusnya). Kalau yang Anda cari ada di daftar itu, Anda sudah selesai. Kalau tidak, misalnya mendeteksi jenis produk tertentu atau kerusakan pada komponen, lanjut ke pelatihan.
Menyiapkan Dataset Sendiri
YOLO memakai format label sederhana: satu berkas teks per gambar, tiap baris berisi kelas x_tengah y_tengah lebar tinggi dengan nilai dinormalkan 0 sampai 1. Struktur foldernya:
dataset/
images/train/ images/val/
labels/train/ labels/val/
data.yaml
# data.yaml
path: /home/pengguna/dataset
train: images/train
val: images/val
names:
0: helm
1: rompi
Periksa hasil pemberian label sebelum melatih: gambar tanpa berkas label berarti "tidak ada objek" dan itu sah, tetapi berkas label dengan koordinat di luar 0 sampai 1 atau indeks kelas yang tidak ada di names akan menggagalkan pelatihan atau, lebih buruk, melatih dengan diam-diam salah. Ultralytics menampilkan ringkasan jumlah gambar dan label per kelas di awal pelatihan; baca baris itu.
Untuk memberi label, alat seperti Label Studio atau CVAT bisa mengekspor langsung ke format YOLO. Beberapa ratus gambar per kelas dengan variasi pencahayaan, sudut, dan latar biasanya sudah memberi hasil yang bisa dipakai; kualitas dan keragaman lebih menentukan daripada jumlah. Sisihkan 15 sampai 20 persen untuk validasi dari sumber yang berbeda (hari lain, kamera lain), bukan acak dari gambar yang sama.
Melatih
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
model.train(data="dataset/data.yaml", epochs=50, imgsz=640, batch=16, device="cpu")
Di CPU, satu epoch untuk beberapa ratus gambar memakan beberapa menit; 50 epoch berarti beberapa jam. Dengan GPU kelas konsumen, seluruhnya selesai dalam belasan menit. Untuk pelatihan sesekali, GPU sewaan per jam adalah jalan tengah yang masuk akal; hasilnya, berkas runs/detect/train/weights/best.pt, bisa dibawa ke mana saja. Mulailah dari model nano dan naik ke s hanya kalau akurasinya belum cukup; perbedaan kecepatannya di CPU sangat terasa.
Parameter Pelatihan yang Layak Disentuh
Ultralytics sudah menerapkan augmentasi bawaan (pembalikan, perubahan warna, mosaik), jadi biasanya tidak perlu diubah di awal. Yang sering berguna: patience=15 untuk berhenti otomatis kalau validasi tidak membaik, imgsz=960 kalau objeknya kecil di dalam gambar besar (dengan biaya waktu yang naik sekitar dua kali), dan fliplr=0 kalau arah kiri-kanan bermakna, misalnya membaca penunjuk arah. model.train(..., resume=True) melanjutkan pelatihan yang terputus dari titik terakhir. Dan seed=0 membuat hasil bisa diulang saat membandingkan dua pengaturan.
Video dan Kamera
for r in model("rtsp://kamera-lokal/stream", stream=True, conf=0.4, vid_stride=5):
jumlah = sum(1 for k in r.boxes if r.names[int(k.cls)] == "helm")
print("helm terdeteksi:", jumlah)
stream=True memproses frame satu per satu tanpa memuat seluruh video ke memori, dan vid_stride=5 hanya memproses setiap frame kelima, yang mengubah beban CPU dari tidak mungkin menjadi masuk akal untuk pemantauan yang tidak butuh setiap frame. Untuk beberapa kamera sekaligus di satu server CPU, hitung dulu: milidetik per frame dikali frame per detik yang diinginkan dikali jumlah kamera, dan bandingkan dengan 1000 dikali jumlah inti.
Membaca Hasil Evaluasi
metrik = YOLO("runs/detect/train/weights/best.pt").val(data="dataset/data.yaml")
print(metrik.box.map50, metrik.box.map)
Dua angka utama: mAP50 (akurasi saat kotak prediksi tumpang tindih setidaknya 50 persen dengan kotak sebenarnya) dan mAP50-95 (rata-rata pada ambang yang makin ketat). Untuk kebanyakan aplikasi praktis, mAP50 di atas 0,8 sudah baik. Lihat juga folder runs/detect/train/: ada grafik loss, matriks kebingungan, dan contoh prediksi pada gambar validasi. Kesalahan yang terlihat di sana, misalnya helm kuning yang dikira rompi, hampir selalu menunjuk pada kekurangan data, bukan parameter.
Inferensi di CPU dan Ekspor ONNX
model = YOLO("runs/detect/train/weights/best.pt")
model.export(format="onnx")
onnx = YOLO("runs/detect/train/weights/best.onnx")
hasil = onnx("foto.jpg", imgsz=640, conf=0.4)
Model nano di CPU 4 inti memproses satu gambar 640 piksel dalam kira-kira 50 sampai 150 milidetik, tergantung prosesor; cukup untuk beberapa gambar per detik, tidak cukup untuk video 30 fps penuh. Ekspor ke ONNX biasanya mempercepat inferensi CPU dan menghilangkan kebutuhan PyTorch di server produksi. Parameter conf menyaring deteksi dengan keyakinan rendah; setel berdasarkan kasus Anda, karena deteksi yang terlewat dan deteksi palsu punya biaya yang berbeda.
Menjadikannya Layanan
Bungkus dalam FastAPI: endpoint menerima unggahan gambar, menjalankan model yang sudah dimuat sekali di awal, dan mengembalikan daftar kotak sebagai JSON. Jalankan dengan satu worker Uvicorn per model yang dimuat, karena tiap worker memuat salinannya sendiri ke memori, sekitar beberapa ratus megabyte. Di VinzaPanel, layanan seperti ini di-deploy dengan plugin Python Deploy seperti aplikasi Python lainnya, atau sebagai kontainer lewat Docker Manager kalau Anda ingin mengunci seluruh lingkungannya.
Penutup
Dari pemasangan sampai model yang mengenali objek Anda sendiri, jalurnya kini lurus: pasang, coba model bawaan, beri label beberapa ratus gambar, latih, baca matriks kebingungan, ekspor ke ONNX. Bagian yang paling memakan waktu tetap pemberian label yang teliti, dan itu juga bagian yang paling menentukan hasil.
Selamat melatih model pertama Anda. Bagian memberi label memang melelahkan; hasilnya sepadan.