İçeriğe geç

Teknik Yazılar

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

16.000 Görüntüyü Tek Veri Setinde Birleştirmek: Temizlik, Dedup ve Sınıf Dengesi

Birden çok veri setini birleştirmek 'hepsini bir klasöre at' değil. Sınıf kaosu, gizli kopyalar ve 32:1 dengesizlikle nasıl uğraştık.

Modelimizin uzaktaki hedefi göremediğini teşhis ettikten sonra (o hikâye burada) tek bir sonuca varmıştık: veri setini baştan kurmamız gerekiyordu. Elimizdeki veri, sahada karşılaşacağımız durumu içermiyordu.

Çözüm basit görünüyordu — daha fazla veri bul, hepsini birleştir, yeniden eğit. Uygulaması hiç öyle olmadı. Bu yazı, 16.000 görüntüyü tek ve kullanılabilir bir veri setine dönüştürürken karşılaştığımız dört problemin hikâyesi.

Problem 0: Elimizdeki veri neyi içermiyordu?

Önce mevcut veriyi anlamak için basit ama çok öğretici bir analiz yaptık: tüm etiket kutularının boyut dağılımını çıkardık.

  • Kutu boyutu medyanı: ~200 piksel
  • En küçük %10’luk dilim: ~99 piksel

Yani veride küçük/uzak nesne yoktu. Ayrıca görüntülerin büyük çoğunluğu web’den toplanmıştı; gerçek drone karesi azınlıktaydı. Model, “yerden çekilmiş büyük nesne” görerek eğitilip “havadan çekilmiş küçük nesne” bulması beklenen bir durumdaydı.

Bu analiz beş dakika sürdü ve sonraki tüm kararları belirledi. Veri setinizi tanımadan eğitmeyin.

Problem 1: Sınıf kaosu

Birkaç farklı kaynağı birleştirince ortaya çıkan sınıf listesi şuna benziyordu:

'0', '0 pedestrian', 'Lying_Person', 'Person', 'baygin', 'bicycle',
'bus', 'car', 'human', 'motobike', 'motorbik3', 'p3rson', 'people',
'person', 'tent'

15 sınıf. İçinde yazım hataları (p3rson, motorbik3), farklı diller (baygin), aynı şeyin farklı adları (Person, person, human, people) ve bizim görevimizle hiç ilgisi olmayan sınıflar (car, bus, bicycle) vardı.

Bizim görevimizde yalnızca iki hedef var: manken ve çadır. Yaptığımız eşleme:

Kaynak sınıflar Hedef sınıf
person, people, human, Person, p3rson, Lying_Person, pedestrian, baygin mannequin
tent tent
car, bus, bicycle, motorbike… atıldı

Burada dikkatli olunması gereken bir sınıf vardı: düz '0' adlı sınıf. İsminden ne olduğu anlaşılmıyordu ama 4000’den fazla kutu içeriyordu — körü körüne atmak da, körü körüne dahil etmek de risktiydi. O sınıfa ait birkaç görüntüyü kutularıyla birlikte açıp baktık: havadan çekilmiş insanlardı. Tam da ihtiyacımız olan veri. Eşlemeye dahil ettik.

Ders: Belirsiz bir sınıfı tahminle değil, gözle karara bağlayın. Beş görüntüye bakmak, 4000 kutuyu kurtarır ya da yanlış etiketten korur.

Problem 2: Görünmez kopyalar

Farklı projelerden gelen veriler birbirinin kopyasını içeriyordu. Üstelik iki farklı biçimde:

a) Augmented kopyalar. Roboflow gibi platformlar dışa aktarırken her görüntünün döndürülmüş/ parlaklığı değiştirilmiş varyantlarını üretebiliyor. Dosya adları farklı ama içerik aynı görüntünün varyasyonu.

b) Farklı isimli aynı görüntü. Aynı kaynak görüntü iki projede farklı adla duruyor.

Bunları temizlemezseniz iki şey olur: veri seti şişer (aynı bilgiyi tekrar tekrar öğretirsiniz) ve daha kötüsü, aynı görüntünün bir kopyası eğitimde, diğeri doğrulamada kalırsa sızıntı (data leakage) oluşur — model sınavda daha önce gördüğü soruyu çözer, metrikler yalancı şekilde yükselir.

İki aşamalı temizlik yaptık:

# 1) İsim tabanlı: augmented varyantlar aynı "base" adı paylaşır
#    "foo_jpg.rf.HASH.jpg" -> "foo"
def base_name(stem):
    s = re.split(r"[._]rf[._]", stem.lower())[0]
    return re.sub(r"_(jpg|jpeg|png|webp)$", "", s)

# 2) İçerik tabanlı: 8x8 average hash (aHash)
def ahash(img):
    g = cv2.cvtColor(cv2.resize(img, (8, 8)), cv2.COLOR_BGR2GRAY)
    bits = (g > g.mean()).flatten()
    h = 0
    for b in bits:
        h = (h << 1) | int(b)
    return h

aHash, görüntüyü 8×8’e küçültüp ortalamanın üstünde/altında olan pikselleri 1/0 olarak kodlar. Yeniden boyutlandırma ve JPEG sıkıştırmaya dayanıklıdır — yani “aynı görüntünün farklı kaydı” durumunu yakalar.

Sonuç: yaklaşık 2.000 kopya elendi.

Problem 3: 32’ye 1 dengesizlik

Birleştirme bittiğinde sınıf dağılımı şöyleydi:

  • mannequin (insan): ~160.000 kutu
  • tent (çadır): ~5.000 kutu

Yaklaşık 32:1. Bunun nedeni açık: havadan insan veri setleri (kalabalık sahneler) çok yaygın, havadan çadır verisi ise nadir. Bir kare onlarca insan içerebilirken, çadır genelde tek başına duruyor.

Bu dengesizlikle eğitim yapmak, modeli “çadır sınıfını görmezden gelmeye” iter — çünkü kayıp fonksiyonu açısından çadırı kaçırmanın maliyeti, insanı doğru bulmanın kazancı yanında küçük kalır.

Çözüm olarak azınlık sınıfını oversample ettik: çadır içeren eğitim karelerini 3 kat çoğalttık. Bunu otomatik yapan bir adım ekledik — hangi sınıfın azınlıkta olduğunu veri sayarak bulur, onu çoğaltır. Böylece veri seti değişse de mantık çalışmaya devam eder.

Problem 4: Doğrulama setini kirletmemek

Bu, en kolay atlanan ama en kritik karardı.

Elimizde iki tür görüntü vardı: web’den toplanan görüntüler (çoğunluk) ve kendi drone’umuzla çekilmiş gerçek hava kareleri (azınlık). Doğrulama setini rastgele seçseydik, içine ağırlıklı olarak web görüntüleri düşecekti.

Bunun sonucu şu olurdu: metrikler yüksek çıkar, saha performansı düşük kalır. Model, uçmadığımız bir domende sınav olur.

Bu yüzden doğrulama setini yalnızca gerçek hava karelerinden oluşturduk. 631 karelik bir havuzdan 31 görüntü / 121 etiketli nesne. Küçük bir set — ve bunu açıkça belirtiyoruz — ama temsil ettiği şey doğru.

Kolay metrik, iyi metrik değildir. Doğrulama seti, modelin gerçekte çalışacağı ortamı yansıtmıyorsa aldığınız sayı sizi rahatlatır ama bilgilendirmez.

Ek adımlar: tiling ve hard negative

Son iki dokunuş:

Tiled training. Büyük görüntüleri 1280×1280 karelere, %40 örtüşmeyle böldük. Bu hem küçük nesnelerin göreli boyutunu artırıyor hem de çıkarım tarafındaki dilimleme yaklaşımıyla aynı dağılımı üretiyor.

Hard negative kareler. Eğitim setine, içinde hiç hedef olmayan arka plan karelerini (%15 oranında) ekledik — çim, enkaz, gölge, çalı. Amaç modele “burada nesne yok” demeyi öğretmek. Bu kareler yanlış alarm oranını düşürüyor; enkaz arasında hedef arayan bir görevde bu doğrudan puan demek.

Veri seti dönüşümü

Sonuç

Yeniden eğitilen model, yalnızca gerçek hava karelerinden oluşan doğrulama setinde mAP50 0.950 değerine ulaştı ve saha testinde her iki hedefi de tespit edip otonom bırakma yapabildi.

Buradaki iyileşmenin ne kadarı yeni veriden, ne kadarı augmentation’dan geldi? Tam olarak ayıramıyoruz — ikisini birlikte değiştirdik. Eğer zamanınız varsa tek seferde tek değişken değiştirmek, sonucu yorumlanabilir kılar.

Çıkarılacak dersler

1. Veri setinizin dağılımını ölçün, sayısını değil. 16.000 görüntünüz olabilir ve ihtiyacınız olan durumu hiç içermeyebilir.

2. Birleştirme = sınıf eşleme + dedup + denge. Klasörleri birleştirmek işin en kolay kısmı.

3. İçerik tabanlı dedup şart. Dosya adı yeterli değil; aynı görüntü farklı isimlerle gelir ve sızıntı yaratır.

4. Azınlık sınıfını dengeleyin. 32:1 bir dağılımda model azınlığı öğrenmeyi bırakır.

5. Doğrulama seti, çalışacağınız ortamı temsil etmeli. Kolay set, yalancı metrik üretir.

6. Belirsizliği gözle çözün. İsmi anlaşılmayan bir sınıf varsa birkaç örneğini açıp bakın.

  • veri seti
  • Roboflow
  • YOLO
  • veri temizliği
  • etiketleme

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