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 kututent(ç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.

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