İçeriğe geç

Teknik Yazılar

Veri Seti ve Model Eğitimi··7 dk okuma

Veri Seti Hazırlama Rehberi: Etiketleme, Hard Negative ve Doğru Validation

Doğrulama setinde 0.950 mAP alıp sahada hedef kaçırmanın sebebi genelde model değil, veri setinin nasıl kurgulandığıdır.

Eğitim biter, terminalde mAP50 (ortalama kesinlik, IoU eşiği 0.50) 0.9’un üzerinde bir sayı görürsünüz. Ertesi gün sahaya çıkarsınız: model ağaç gölgesini hedef sanar, 20 metreden mankeni gördüğü kareyi bir sonrakinde kaçırır. İlk refleks genelde aynıdır — daha büyük model, daha çok epoch, daha agresif augmentation.

Bizim deneyimimizde sorun neredeyse hiç orada olmadı. SUAS 2026 için hazırladığımız veri setinin ilk sürümünde karelerin çok büyük bölümü web’den toplanmış yer seviyesi fotoğraflardı; havadan çekilmiş kare oranı %15’in altındaydı ve iki sınıf arasında yaklaşık 7:1’lik bir dengesizlik vardı. Bu setten rastgele ayrılan bir doğrulama kümesi yüksek bir sayı üretiyordu, ama o sayı uçuş performansı hakkında hemen hiçbir şey söylemiyordu.

Bu yazıda veri setini bir yazılım bileşeni gibi ele alıyoruz: bir sözleşmesi var (etiketleme kuralları), bir test kapsamı var (doğrulama seti) ve sessizce bozulma riski var (leakage, yani eğitim ile test arasında bilgi sızması). Sayısal hedefler Ultralytics dokümantasyonundan, kurgu kararları bizim saha deneyimimizden.

İyi bir veri setinin anatomisi

Ultralytics’in “en iyi eğitim sonuçları” kılavuzu üretim kalitesi için sınıf başına en az 1500 görüntü ve en az 10.000 etiketli örnek (instance) öneriyor. Bir öğrenci takımı için bu rakamlar çoğu zaman ulaşılamaz; önemli olan hangi eksende yaklaştığınızı bilmek.

Bileşen Hedef Neden önemli
Sınıf başına görüntü ≥ 1500 (Ultralytics önerisi) Görsel çeşitlilik tabanı
Sınıf başına örnek ≥ 10.000 (Ultralytics önerisi) Ölçek/poz varyasyonu
Nesnesiz arka plan Toplamın %0-10’u Yanlış pozitifi (FP) düşürür
Doğrulama setinin kaynağı %100 uçuş benzeri görüntü Metriğin anlamlı olması
Bozuk/çift etiket 0 Sessiz metrik kaybı

Sıralama da önemli: 500 iyi etiketlenmiş havadan kare, 5000 kötü etiketlenmiş web fotoğrafından daha faydalı oldu bizde.

Etiketleme: kutu sıkı, kural yazılı

Ultralytics’in üç temel kuralı net: bir görüntüdeki tüm sınıfların tüm örnekleri etiketlenmeli, kutular nesneyi boşluk bırakmadan sarmalı ve hiçbir nesne etiketsiz kalmamalı. Kısmi etiketleme çalışmaz, çünkü etiketlenmemiş bir nesne modele “burada nesne yok” sinyali verir.

Etiket dosyası formatı, görüntüyle aynı adı taşıyan bir .txt dosyasıdır; her satır bir nesnedir ve koordinatlar 0-1 aralığına normalize edilmiş x_center y_center width height biçimindedir. Sınıf indeksleri sıfırdan başlar.

# labels/train/flight_042_0187.txt
0 0.412500 0.633333 0.031250 0.055556
1 0.784375 0.211111 0.048437 0.041667

Asıl mesele format değil, tutarlılık. İki kişi aynı kareyi etiketlediğinde aynı kutuyu çizmiyorsa, model gürültü öğrenir. Bu yüzden kararları yazılı bir kural sayfasında topladık:

Durum Kuralımız Gerekçe
Nesne kare kenarından kesilmiş Görünen kısmı etiketle Kenar tespiti gerçek senaryo
Nesnenin %50’den fazlası kapalı Etiketleme, kareyi arka plan sayma Belirsiz sinyal üretir
Gölge dahil mi Hayır, sadece cisim Gölge yükseklikle değişir
Çok küçük nesne (< 8 px) Etiketle ama ayrı listede takip et Metrik yorumunu bozar
Şüpheli kare “review” klasörüne, tek kişi karar verir Tutarlılık > hız

Kural sayfası olmadan geçirilen her etiketleme haftası, sonradan yeniden etiketleme haftası olarak geri gelir.

Sınıf dengesi: 7:1 sessizce cezalandırır

Sınıflar arası oran bizde yaklaşık 7:1’di. Bu durumda toplam mAP, baskın sınıfın performansıyla domine olur ve azınlık sınıfının kötü gittiğini fark etmezsiniz. En basit teşhis: metrikleri her zaman sınıf bazında okuyun, val çıktısındaki per-class satırlarına bakın.

Yöntem Ne zaman tercih edilir Riski
Hedefli veri toplama Zaman varsa — en iyi çözüm Yavaş, saha uçuşu gerektirir
Azınlık sınıfını çoğaltma (oversampling) Veri toplama imkânı yoksa Aynı karelere ezber
Sınıfları birleştirme Ayrım görev için gerekmiyorsa Görev şartını ihlal edebilir
Kopyala-yapıştır augmentation Nesne küçük ve arka plan homojense Gerçekçi olmayan yerleşim

Bizim tercihimiz sırasıyla hedefli toplama ve ölçülü oversampling oldu; sınıf birleştirmeyi görev şartı nedeniyle masadan kaldırdık.

Hard negative: nesnesiz kareler neden şart

Hard negative, modelin yanlışlıkla nesne sandığı ama aslında hedef içermeyen karedir — çim üzerindeki bir çöp poşeti, çadıra benzeyen bir gölgelik, insan silüetine benzeyen bir işaret levhası. Bu kareleri veri setine etiketsiz olarak eklersiniz: arka plan görüntüleri için etiket dosyası gerekmez.

Ultralytics’in önerisi toplam veri setinin %0-10’u kadar arka plan görüntüsü; referans olarak COCO’da yaklaşık 1000 arka plan karesi bulunur, bu da setin yaklaşık %1’ine denk gelir. Daha yüksek oranlar bazı alanlarda yanlış pozitifi belirgin biçimde düşürebiliyor, ancak bu tamamen alana özgü ve dikkatli seçilmiş karelerle yapılan bir tercih — körlemesine arka plan yığmak recall’ü düşürür.

En değerli arka planlar rastgele toplanmaz, modelin kendi hatalarından madenlenir. Akış şu:

from ultralytics import YOLO

model = YOLO("runs/detect/train/weights/best.pt")
# Hedef içermediğini bildiğimiz uçuş kayıtlarını tarat
results = model.predict("flights/clean_pass/", conf=0.25, stream=True)

for r in results:
    if len(r.boxes):                     # burada tespit olmamalıydı -> FP
        r.save(f"hard_negatives/{r.path.stem}.jpg")
# Bu kareler dataset'e etiket dosyası OLMADAN eklenir.
Arka plan oranı Beklenen etki Ne zaman
%0 FP yüksek, sahada gereksiz bırakma Hiçbir zaman
%1-5 Dengeli — bizim başlangıç noktamız Genel kullanım
%5-10 FP daha düşük, recall’e dikkat FP maliyeti yüksekse
%10 üzeri Kaçırma riski artar Yalnızca ölçerek

Kritik nokta: bu oranı da ölçerek değiştirin. Arka plan eklemek doğrulama setinizde FP sayısını düşürmüyorsa, eklediğiniz kareler “hard” değil demektir.

Bölmeyi doğru yapmak: rastgele bölme bir tuzaktır

Yaygın öneri 70/20/10 veya 70/15/15 (eğitim/doğrulama/test) şeklinde. Oran seçimi ikincil; asıl mesele neyi bölme birimi olarak aldığınız.

Bir videodan çıkardığınız ardışık kareler birbirinin neredeyse kopyasıdır. Bunları görüntü bazında rastgele bölerseniz, 187. kare eğitimde, 188. kare doğrulamada olur. Model doğrulama karesini zaten görmüştür; ölçtüğünüz şey genelleme değil, ezberdir. Literatürde bu, video kaynaklı veri setlerinde uzamsal-zamansal korelasyondan doğan bilgi sızması olarak tanımlanıyor ve metrikleri sistematik biçimde şişiriyor.

Çözüm, kareyi değil grubu bölmek: aynı uçuş, aynı video, aynı sahne tek bir tarafa gider.

from sklearn.model_selection import GroupShuffleSplit

# groups: her görüntünün ait olduğu uçuş/video kimliği
gss = GroupShuffleSplit(n_splits=1, test_size=0.30, random_state=42)
train_idx, rest_idx = next(gss.split(images, groups=groups))
# rest_idx daha sonra aynı mantıkla val/test olarak ikiye ayrılır

Sınıf dengesizliği de varsa StratifiedGroupKFold sınıf oranlarını korurken grupları ayrık tutar.

Doğrulama seti çalışılacak ortamı temsil etmeli

Bir metrik, ancak ölçtüğü dağılım kadar anlamlıdır. Web fotoğraflarıyla dolu bir doğrulama setinde alınan yüksek skor, 100 metre irtifadan 81° HFOV bir gimbal kameranın gördüğü sahne hakkında bilgi vermez.

Biz doğrulama setini yalnızca havadan çekilmiş karelerden kurduktan sonra ölçtüğümüz değer mAP50 0.950 oldu. Bu sayının kıymeti büyüklüğünden değil, neyi ölçtüğünün belli olmasından geliyor: aynı model, saha testinde yaklaşık 20 metre irtifadan iki hedefi tespit edip otonom bırakma yapabildi. Web ağırlıklı bir doğrulama setiyle bu bağı asla kuramazdık.

Pratik kural: doğrulama ve test setleri uçuş koşullarını (irtifa aralığı, günün saati, zemin dokusu, kamera) temsil etmeli. Test setini oluşturduğunuz gün kilitleyin — bir kez karar vermek için baktıysanız, o artık eğitim verisidir.

Veri temizliği: duplicate ve bozuk etiket

Ultralytics eğitim başlarken veri setini tarar ve ... images, ... backgrounds, ... corrupt biçiminde bir özet basar; ayrıca normalize edilmemiş veya sınır dışı koordinatlar ile yinelenen etiketler için uyarı verir. Bu satırı okumadan geçmeyin — sessizce atlanan yüzlerce kare olabilir.

Kontrol listemiz:

# 1) Etiketi olmayan görüntü / görüntüsü olmayan etiket
# 2) Sınır dışı koordinat (0-1 aralığı ihlali)
python - <<'PY'
from pathlib import Path
for f in Path("labels/train").glob("*.txt"):
    for i, line in enumerate(f.read_text().split("\n")):
        if not line.strip(): continue
        c, *v = line.split()
        if any(not (0.0 <= float(x) <= 1.0) for x in v):
            print("SINIR DISI:", f.name, "satir", i + 1)
PY

Birebir aynı kareler için dosya hash’i yeterli. Yakın kopyalar (near-duplicate) için FiftyOne Brain’in compute_exact_duplicates() ve compute_near_duplicates() fonksiyonları işi kolaylaştırıyor. Aynı sahnenin bir kopyası eğitimde, diğeri doğrulamada durduğunda ölçüm güvenilirliğini kaybediyor.

Sık düşülen tuzaklar

Tuzak Belirti Çözüm
Rastgele kare bölme Val mAP çok yüksek, saha kötü Grup bazlı bölme
Kısmi etiketleme Recall düşük, kayıp dalgalı Tüm örnekleri etiketle
Gevşek kutu Lokalizasyon kayması, mAP50-95 düşük Kutuyu nesneye yapıştır
Hiç arka plan yok Boş sahada tespit üretiyor %1-5 hard negative ekle
Temsil etmeyen val seti Metrik ile saha uyuşmuyor Val’i uçuş görüntüsüyle kur
Test setine sürekli bakmak Nihai sayı iyimser çıkıyor Test setini kilitle
Augmentation’ı bölmeden önce yapmak Aynı karenin varyantı iki tarafta Önce böl, sonra augment

Pratik özet

  1. Önce bölme birimini seç, sonra oranı. Uçuş/video bazında grupla; GroupShuffleSplit veya StratifiedGroupKFold kullan. 70/15/15 makul bir başlangıç.
  2. Doğrulama ve test setini yalnızca uçuş görüntüsünden kur. Web fotoğrafları eğitimde kalabilir, ölçümde kalamaz.
  3. Etiketleme kurallarını tek sayfada yaz ve iki kişinin aynı kareyi etiketlemesini karşılaştırarak doğrula. Kutular nesneyi boşluksuz sarsın.
  4. Toplamın %1-5’i kadar hard negative ekle, bunları modelin kendi yanlış pozitiflerinden madenle ve oranı ölçerek artır (üst sınır ~%10).
  5. Her eğitimden önce temizlik koş: duplicate hash kontrolü, sınır dışı koordinat taraması ve Ultralytics’in tarama özetindeki corrupt sayısı sıfır olsun.

Kaynaklar: Ultralytics — Tips for Best Training Results, Ultralytics — Detection Datasets, Ultralytics — Data Collection and Annotation, Ultralytics — Preprocessing Annotated Data, scikit-learn — Cross-validation, FiftyOne Brain

  • veri-seti
  • etiketleme
  • hard-negative
  • validation
  • yolo

Zor bir mühendislik probleminiz mi var?

Yapılabilir mi, ne kadar sürer, nasıl kurulur: konuşarak başlayalım.

Projenizi Konuşalım