Görüntü İşleme··4 dk okuma
Yakında Görüyor, Uzakta Kör: Bir Tespit Hatasının Kök-Neden Analizi
Modelimiz yakındaki hedefi buluyor, uzaktakini hiç görmüyordu. Eşikle oynamak yerine nedenini kazdık — ve sorun modelde değildi.
Elimizde eğitilmiş bir nesne tespit modeli vardı ve doğrulama metrikleri iyi görünüyordu. Ama sahada tuhaf bir davranış sergiliyordu:
- Hedefe yakınken yüksek güvenle buluyordu
- Mesafe biraz açılınca hiçbir şey üretmiyordu
- Arada geçiş yoktu. “Şüpheli bir tespit” bile çıkmıyordu
Bu davranış aslında bir ipucu. Model kademeli olarak zorlanmıyor, bir eşikten sonra tamamen susuyordu. Bu yazı, o sessizliğin nedenini nasıl bulduğumuzun hikâyesi.
İlk refleks: eşiği düşürmek (ve neden işe yaramadı)
Herkesin ilk aklına gelen çözüm: güven eşiğini (confidence threshold) düşür. Model 0.4’te susuyorsa 0.15’e indir, belki zayıf tespitler ortaya çıkar.
Denedik. Hiçbir şey değişmedi.
Nedeni sonradan çok net anlaşıldı: eşik taraması, ağın hiç üretmediği bir tespiti geri getiremez. Eşik, var olan çıktıları filtreler. Model o bölgede hiç aday üretmiyorsa, filtreyi gevşetmenin filtrelenecek bir şeyi yoktur.
Bu, hata ayıklamada sık düşülen bir tuzak: semptomun ayarını değiştirmek, nedenini aramanın yerine geçiyor. Ölçüm yapmadan ayar çevirmek, sorunu çözmüş gibi hissettirir ama çözmez.
Adım 1: Fizik ne diyor?
Önce şunu sorduk: hedef, kameranın gördüğü karede kaç piksel?
Nadir (dik aşağı) bakan bir kamera için karenin yer ayak izi ve piksel başına düşen yer mesafesi (GSD, Ground Sampling Distance) şöyle hesaplanır:
W_yer = 2 · h · tan(HFOV / 2)
GSD = W_yer / N_piksel
Bizim kamerada (SIYI A8 mini, 81° yatay görüş açısı, 1920 piksel genişlik):
| İrtifa | GSD | Manken (1.7 m) 1080p’de | Model girişine küçültülünce (640 px) |
|---|---|---|---|
| 20 m | 17.8 mm/px | ~95 px | ~32 px |
| 46 m | 40.9 mm/px | ~42 px | ~14 px |
İşte ilk kritik bulgu: model, kareyi olduğu gibi görmüyor. Giriş boyutuna küçültülmüş halini görüyor. 46 metrede 1080p karede 42 piksel olan manken, ağın önüne 14 piksel olarak geliyor.
14 piksellik bir nesne, evrişimli bir ağın derin katmanlarında (stride-32 aşamasında) neredeyse tek bir hücreye denk düşüyor. Yani bilgi, ağ karar vermeye başlamadan önce eriyip gidiyor.

Adım 2: Veri ne diyor?
Fizik “zor” diyordu ama “imkânsız” demiyordu. O halde ikinci soru: model bu boyutta bir nesne görmeyi hiç öğrendi mi?
Eğitim veri setindeki tüm etiket kutularının boyut dağılımını çıkardık. Sonuç çarpıcıydı:
- Kutu boyutu medyanı: ~200 piksel
- En küçük %10’luk dilim bile ~99 piksel
Yani veri setinde operasyonel boyuta yakın tek bir örnek bile yoktu. Model 100-300 piksellik nesneler görerek eğitilmiş, sahada ondan 14 piksellik nesne bulması bekleniyordu.
Bu, modelin “kötü” olduğu anlamına gelmiyor. Kendisine öğretilen işi yapıyordu. Sadece öğretilen iş, sahadaki iş değildi.
Adım 3: Eğitim ayarları ne diyor?
Son parça, eğitim konfigürasyonunda çıktı. Modelin checkpoint’indeki kayıtlı parametrelere baktığımızda augmentation (veri çoğaltma) ayarlarının kapalı olduğunu gördük:
scale: 0 # ölçek çeşitliliği yok
fliplr: 0 # yatay çevirme yok
flipud: 0 # dikey çevirme yok
degrees: 0 # döndürme yok
imgsz: 960
scale = 0 özellikle önemli. Bu parametre eğitim sırasında görüntüleri rastgele
büyütüp küçülterek ağa “aynı nesne farklı boyutlarda da olabilir” demeyi sağlıyor. Kapalı
olduğunda ağ, her nesneyi veri setindeki tek boyutuyla öğreniyor.
Teşhis: iki neden, tek semptom
Elimizdeki tablo netleşti:
- Veride küçük/uzak örnek yok (medyan ~200 px)
- Ölçek çeşitliliği kapalı (
scale=0)
Bu ikisi birbirini besliyordu. Veri küçük nesne içermiyor, augmentation da onu sentezlemiyor. Sonuç: ağın “uzaktaki hedef” diye bir kavramı hiç oluşmamış. Sahadaki binary davranışın — yakında mükemmel, uzakta sıfır — açıklaması tam olarak buydu.
Dikkat çekici olan şu: doğrulama metrikleri bunu göstermiyordu. Çünkü doğrulama seti de aynı veriden geliyordu; yani modele, öğrendiği boyut aralığında sınav yapılıyordu. Metrik yalan söylemiyordu, sadece yanlış soruyu soruyordu.
Çözüm
Teşhis veri ve ölçeği işaret ettiği için, mimariye dokunmadık. Aynı model ailesini koruyup şunları değiştirdik:
- Giriş çözünürlüğünü artırdık (960 → 1280)
- Augmentation’ı açtık:
scale 0.5,fliplr/flipud 0.5,degrees 15,mosaic 1.0,mixup 0.1 - Veri setini yeniden kurduk (ayrı yazı: “16.000 Görüntüyü Tek Veri Setinde Birleştirmek”)
- Doğrulama setini yalnızca gerçek hava görüntülerinden oluşturduk
scale ve mosaic burada kilit rol oynuyor: veride bulunmayan küçük-nesne popülasyonunu
sentezliyorlar. Model artık aynı hedefi çok farklı boyutlarda görerek eğitiliyor.
Mimariyi bilerek sabit tuttuk. Hem veriyi hem mimariyi aynı anda değiştirseydik, iyileşmenin hangisinden geldiğini asla bilemezdik. Hata ayıklamada tek değişkenli ilerlemek, sonucu yorumlanabilir kılıyor.
Sonuç
Yeniden eğitilen model, yalnızca gerçek hava karelerinden oluşan doğrulama setinde mAP50 0.950 değerine ulaştı. Daha önemlisi, saha testinde her iki hedefi de tespit edip otonom bırakma yapabildik.
Çıkarılacak dersler
1. Semptomun ayarını çevirmeden nedenini ölç. Eşik düşürmek, kök nedeni aramanın yerine geçemez.
2. Fizik hesabını yap. “Hedef kaç piksel?” sorusu, saatlerce model denemekten daha hızlı yol gösterir. Kamera görüş açısı, irtifa ve model giriş boyutu birlikte bir bütçe oluşturur.
3. Veri setinin dağılımına bak, sadece sayısına değil. 16.000 görüntünüz olabilir ve yine de ihtiyacınız olan durumu hiç içermeyebilir.
4. Doğrulama seti, çalışacağınız ortamı temsil etmiyorsa metrikleriniz sizi yanıltır. Kolay metrik, iyi metrik değildir.
- YOLO
- nesne tespiti
- hata ayıklama
- GSD
- küçük nesne