
FIG. 01
KAYIT KÜNYESİ
Kategori
Yazılım
TARİH
Doğrulama setimizde 0.950 mAP50 alan bir modelimiz var. Havadan görüntülerde mankenleri ve çadırları hiç zorlanmadan buluyor. Sonra irtifayı 20 metreden 60 metreye çıkarıyoruz ve model körleşiyor. Hedef hâlâ karede, gözle rahatça seçebiliyorsunuz, ama tek bir tespit kutusu bile geri gelmiyor.
İlk refleks modeli suçlamak olur: "yeterince eğitilmemiş", "daha büyük bir model lazım". İkisi de genelde yanlış. Sorun modelin ne öğrendiği değil, ona kaç piksel verdiğimiz. YOLO11m'i 1280 piksellik girdiyle eğitip uçuşta 640 tam kare beslediğimizde, 1920×1080'lik RTSP akışını 3 kat küçültmüş oluyoruz. Karede 30 piksel genişliğindeki bir manken, modelin gözünde 10 piksele düşüyor.
Bu yazıda küçük nesnelerin tam olarak nerede kaybolduğunu, SAHI'nin (Slicing Aided Hyper Inference) bunu nasıl çözdüğünü ve hesap maliyetimizi kaç katına çıkardığını tek tek geçiyoruz. Sonunda ne zaman değmediğini de konuşuyoruz. Bizim uçuş senaryomuzda çoğu zaman değmiyor.
Küçük nesneler neden kayboluyor: üç aşamalı kayıp
Kayıp tek bir yerde olmuyor. Üst üste binen üç ayrı yerde oluyor.
1. Girdi ölçekleme. Model sabit bir çözünürlükte çalışır (imgsz). 1920×1080'lik bir kareyi 640'a indirdiğinizde her yönde 3 kat kaybedersiniz; yani nesnenin alanı 9'a bölünür.
2. Stride ve alt örnekleme. YOLO11'in tespit başlıkları üç piramit seviyesinden beslenir. Resmî yolo11.yaml yapılandırması bunları açıkça etiketler: P3/8-small, P4/16-medium, P5/32-large. Üçünün en incesi olan P3 bile girdiyi 8 kat alt örnekler. Modelin girdisinde 10 piksel olan bir nesne, P3 ızgarasında yaklaşık 1.25 hücreye karşılık gelir.
3. Öznitelik haritası çözünürlüğü. Bir buçuk hücrelik bir izden sınıf ve kutu regresyonu çıkarmak, ağın elindeki bilgiyi sonuna kadar zorlar. COCO zaten alanı 32×32 = 1024 pikselin altında kalan her şeyi "küçük nesne" sayıyor; uçuşta bunun epey altına iniyoruz.
Aynı 30 piksellik nesne, farklı kurulumlarda modele şöyle görünüyor:
Kurulum (kaynak 1920×1080) | Ölçek | Modeldeki boyut | P3/8 ızgarasında |
|---|---|---|---|
Tam kare, imgsz=640 | 0.33× | ~10 px | ~1.3 hücre |
Tam kare, imgsz=1280 | 0.67× | ~20 px | ~2.5 hücre |
640 dilim, imgsz=640 | 1.00× | 30 px | ~3.8 hücre |
512 dilim, imgsz=640 | 1.25× | ~37 px | ~4.7 hücre |
O tablodaki tek değişken dilimleme. Model, ağırlıklar ve eğitim tamamen aynı.

SAHI ne yapıyor?
SAHI'nin fikri basit: modeli değiştirme, girdiyi değiştir. Üç adımı var.
Dilimleme. Görüntü, birbiriyle örtüşen sabit boyutlu karolara kesilir. Her dilim modelden tek başına geçer. Bir dilim modelin imgsz değerinden küçükse yukarı ölçeklenir; nesne de onunla birlikte büyür.
Örtüşme (overlap). Komşu dilimler birbiriyle örtüşür; böylece dilim sınırına oturan bir nesne ikiye bölünmez. Varsayılan örtüşme oranı 0.2.
Küresel birleştirme. Her dilimin kutuları özgün görüntü koordinatlarına geri taşınır ve tüm kare üzerinde tek geçişte birleştirilir. SAHI'nin varsayılan birleştiricisi GREEDYNMM, varsayılan eşleşme metriği IOS (intersection over smaller), eşiği ise 0.5. IOS'un tercih edilmesinin sebebi şu: dilim sınırında yarım kalmış bir kutunun tam kutuya karşı IoU değeri düşük çıkar, IOS değeri ise yüksek.
Sessiz ama önemli bir varsayılan daha var: perform_standard_pred=True. SAHI, dilimlerin üstüne bir de tam kare üzerinde tahmin çalıştırır. Kütüphanenin kendi dokümantasyonu gerekçeyi açıkça yazıyor: büyük nesne tespitinin doğruluğunu artırmak için. Dilimler büyük nesneleri parçaladığından, tek başına dilimli çıkarım büyükleri kaçırır.
Kurulum tarafında Ultralytics'in kendi rehberi pip install -U ultralytics sahi diyor.
Gerçekte ne kadar kazandırıyor?
SAHI makalesi (Akyon, Altinuc, Temizel, ICIP 2022), VisDrone ve xView havadan görüntü veri setlerinde üç dedektörü kıyaslıyor. Raporlanan sonuçlar:
Dedektör | Yalnızca dilimli çıkarım | + dilimli ince ayar (kümülatif) |
|---|---|---|
FCOS | %6.8 AP | %12.7 AP |
VFNet | %5.1 AP | %13.4 AP |
TOOD | %5.3 AP | %14.5 AP |
Buradaki asıl mesaj ikinci sütunda: yalnızca çıkarımı dilimlemek kazancın yarısını bile vermiyor. Eğitim verisini de dilimleyin, kazanç kabaca ikiye katlanıyor. Sebebi ölçek uyumu: modeli tam karelerde eğitip dilimlerde çalıştırırsanız, uçuşta hiç görmediği bir nesne ölçeğiyle karşılaşır.
Not: Ultralytics SAHI rehberi nicel bir AP rakamı vermiyor, faydayı yalnızca niteliksel olarak anlatıyor. Sayılar makaleden geliyor.
Eğitim verisini dilimlemek
SAHI'nin komut satırı aracı bunu tek komutta yapıyor; etiketler de otomatik olarak dilim koordinatlarına kaydırılıyor.
İki varsayılan dikkat istiyor. min_area_ratio varsayılan olarak 0.1'dir: kırpılan bir etiketin alanı özgün alanın %10'unun altına düşerse etiket sessizce atılır. Bir de --ignore_negative_samples bayrağı var. Kapalı bırakırsanız hiç nesne içermeyen dilimler de veri setine girer. Bunlar değerli negatif örneklerdir (yanlış pozitifleri azaltırlar), ama epoch süresini şişirecek ve sınıf dengenizi bozacak kadar çok olabilirler. Bizim veri setimiz zaten dengesiz (sınıflar arasında ~7:1), bu yüzden negatif dilim oranını incelemeden bunları açmak istemedik.
Maliyet: kaç ileri geçiş?
Bu, SAHI'nin faturası ve pazarlığa açık değil. 1920×1080'lik bir kare için SAHI'nin dilim üretme algoritmasının çıkardığı dilim sayıları şöyle:
Dilim boyutu | Örtüşme | Izgara | Dilim sayısı | +tam kare = toplam geçiş |
|---|---|---|---|---|
1024×1024 | 0.2 | 3×2 | 6 | 7 |
640×640 | 0.2 | 4×2 | 8 | 9 |
512×512 | 0.2 | 5×3 | 15 | 16 |
512×512 | 0.4 | 6×3 | 18 | 19 |
Uçuş kurulumumuzda (Jetson Orin NX 16GB, YOLO11m, 640 tam kare) 15-20 FPS ölçtük; yani kare başına kabaca 50-67 ms. 640 dilimle 9 geçiş çalıştırmak, kaba çarpımla, ~450-600 ms yani yaklaşık 2 FPS eder. Bu bir öngörü; araç üzerinde ölçmedik. Ama büyüklük mertebesi net: SAHI, otonom uçuş sırasında canlı tespit için çalıştıracağımız bir şey değil.
Şuna da dikkat edin: örtüşmeyi 0.2'den 0.4'e çıkarmak 512'lik dilimlerde dilim sayısını 15'ten 18'e taşıyor; %20 maliyet artışı, üstelik anlamlı bir kazanç garantisi yok.
Ne zaman değer, ne zaman değmez
Senaryo | SAHI? | Neden |
|---|---|---|
Uçuş sırasında canlı tespit (15-20 FPS hedefi) | Hayır | N kat geçiş, FPS'i kullanılamaz seviyeye düşürüyor |
Uçuş sonrası kayıt üzerinde hedef taraması | Evet | Gecikme önemli değil, kaçan hedef önemli |
FastMosaic ile üretilen büyük bir ortofoto üzerinde tespit | Evet | Girdi zaten çok yüksek çözünürlüklü; tek tam kare olarak vermek anlamsız |
Karede hedef >100 piksel (alçak irtifa yaklaşması) | Hayır | Tam kare zaten yeterli pikseli veriyor |
Az etiketli veri ve küçük hedefler | Evet, ama önce dilimlerde ince ayar yapın | Kazancın yarısından fazlası eğitim tarafında |
Model P2 başlığıyla yeniden eğitilebiliyor | Önce onu deneyin | Mimari çözüm çıkarımda ek maliyet getirmez |
Son satır önemli: SAHI tek seçenek değil. Küçük nesneler için stride-4 P2 tespit başlığı eklemek bir başka yol. Çıkarım maliyetini SAHI gibi artırmıyor, ama modeli yeniden eğitmeyi ve mimariye dokunmayı gerektiriyor.
Sık düşülen tuzaklar
Nesneden küçük bir örtüşme seçmek. 512'lik dilimde 0.2 örtüşme = 102 piksellik bant. 102 pikselden geniş bir nesne iki dilimde birden kırpılabilir. Kaba kural: örtüşme bandı, beklediğiniz en büyük nesneden geniş olmalı.
Dilimi fazla küçültmek. Bağlam yok oluyor. Model bir mankeni çevresinden yalnızca siluetiyle değil, etrafındaki zeminle de ayırır. 256'lık dilimlerde o bağlam kalmıyor ve yanlış pozitifler tırmanıyor.
Şunu kapatmak: perform_standard_pred=False. İnsanlar "zaten dilimliyorum, tam kare bana ne lazım" diye düşünüp kapatıyor. Sonuç, büyük nesnelerde doğruluk düşüşü. Kütüphanenin bu parametreyi varsayılan olarak açık bırakmasının sebebi tam olarak bu.
Tam karelerde eğitip dilimlerde çıkarım yapmak. En sık yapılan hata ve makalenin sayılarının tam olarak söylediği şey: kazancın büyük kısmı eğitim verisini de dilimlemekten geliyor.
Şunun ne yaptığını fark etmemek: min_area_ratio. sahi coco slice sonrasında, dilimlenmiş veri setindeki toplam etiket sayısını özgün veri setiyle karşılaştırın. Beklenmedik bir düşüş, kutularınızın kırpma filtresine takıldığı anlamına gelir.
Birleştirmenin sınıftan bağımsız olduğunu varsaymak. postprocess_class_agnostic varsayılan olarak False'tur; farklı sınıflardan iki kutu aynı nesnenin üzerinde duruyorsa birleştirilmezler. İki sınıflı bir modelde (bizimki manken + çadır) genelde istediğiniz davranış budur, ama bunu bilerek seçin.
Pratik özet
Önce piksel bütçesini çıkarın. Modelin girdisinde hedefiniz kaç piksel? 20'nin altındaysa sorun mimari değil, ölçek. Model değiştirmeden önce bu sayıyı bulun.
SAHI'yi bir çıkarım yaması değil, veri hattı kararı olarak görün. Eğitim setini de
sahi coco sliceile dilimleyin; makaledeki kazancın yarısından fazlası oradan geliyor.Dilim boyutunu hedef boyutundan değil, örtüşme bandından seçin. Örtüşme bandı, beklediğiniz en büyük nesneden geniş olmak zorunda. 1080p için 512 ya da 640 iyi birer başlangıç noktası.
N geçişlik maliyeti baştan hesaplayın ki sonra sürpriz olmasın. 1080p + 640 dilim + 0.2 örtüşme = 9 ileri geçiş. Bunu gerçek zamanlı bir döngüye koymadan önce FPS bütçenizi kontrol edin.
SAHI'yi uçuş sonrası analize, tam kare çıkarımı da uçuşun kendisine ayırın. Planımız bu: havada 15-20 FPS'te 640 tam kare, yerde kayıt üzerinde dilimli taramalar.
Kaynaklar: SAHI makalesi (Akyon, Altinuc, Temizel, ICIP 2022, arXiv:2202.06934); Ultralytics SAHI dilimli çıkarım rehberi; obss/sahi deposu (sahi/predict.py, sahi/slicing.py, docs/cli.md); Ultralytics yolo11.yaml model yapılandırması.
