İçeriğe geç

Teknik Yazılar

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

Augmentation Rehberi: scale, mosaic, flip — Hangisi Ne İşe Yarar?

Bir forumdan kopyaladığınız augmentation satırları mAP'inizi düşürüyor olabilir. Her parametrenin ne yaptığını, ne zaman açılacağını ve ne zaman zarar verdiğini varsayılan değerleriyle birlikte açıyoruz.

Eğitim komutunu yazarken herkesin yaptığı bir şey var: bir forum gönderisinden ya da bir Kaggle notebook’undan augmentation (veri çoğaltma — aynı görüntüden yapay varyasyonlar üretme) satırlarını kopyalayıp yapıştırmak. degrees=15, mixup=0.15, erasing=0.4… Çalışır gibi görünür. Sonra doğrulama mAP’i beklediğinizin altında kalır ve nedenini bulamazsınız.

Bizim başımıza da geldi. İlk veri setimiz ağırlıklı olarak web’den toplanmış, yalnızca küçük bir kısmı gerçek havadan çekim olan bir karışımdı. Üzerine “ne kadar çok augmentation o kadar iyi” mantığıyla agresif ayarlar bindirince, model havadan görüntüde daha da kötüleşti. Sorun augmentation’ın kendisi değildi; hangi dönüşümün bizim problemimizde fiziksel olarak mümkün olduğunu hiç sormamış olmamızdı.

Bu yazıda Ultralytics’in augmentation parametrelerini tek tek geçiyoruz: ne yaptıkları, resmî varsayılanları ve — asıl önemlisi — hangi durumda zarar verdikleri. Tüm değerler Ultralytics’in default.yaml dosyası ve resmî dokümantasyonundan doğrulandı (2026 itibarıyla).

Tam parametre tablosu

Ultralytics’te augmentation ayrı bir kütüphane değil; doğrudan eğitim konfigürasyonunun içinde yaşıyor. Varsayılanlar şunlar:

Parametre Varsayılan Aralık Ne yapar
hsv_h 0.015 0.0–1.0 Ton (renk) kaydırma
hsv_s 0.7 0.0–1.0 Doygunluk kaydırma
hsv_v 0.4 0.0–1.0 Parlaklık kaydırma
degrees 0.0 0–180 ±N derece döndürme
translate 0.1 0.0–1.0 Görüntü boyutunun oranı kadar kaydırma
scale 0.5 0.0–1.0 (1−scale)–(1+scale) arası ölçekleme
shear 0.0 −180–+180 Eğme (kesme dönüşümü)
perspective 0.0 0.0–0.001 Perspektif bozma
flipud 0.0 0.0–1.0 Dikey çevirme olasılığı
fliplr 0.5 0.0–1.0 Yatay çevirme olasılığı
bgr 0.0 0.0–1.0 RGB↔BGR kanal takası olasılığı
mosaic 1.0 0.0–1.0 4 görüntüyü tek tuvalde birleştirme olasılığı
close_mosaic 10 tam sayı Son N epoch’ta mosaic’i kapat (0 = hiç kapatma)
mixup 0.0 0.0–1.0 İki görüntüyü ve etiketlerini harmanlama
cutmix 0.0 0.0–1.0 Dikdörtgen bölgeleri görüntüler arası kes-yapıştır
copy_paste 0.0 0.0–1.0 Nesne kopyalama (yalnızca segmentasyon)
copy_paste_mode flip flip / mixup Kopyalanan nesnenin kaynağı
auto_augment randaugment Yalnızca sınıflandırma
erasing 0.4 0.0–0.9 Yalnızca sınıflandırma

Dikkat çeken nokta: varsayılan olarak yalnızca mosaic, fliplr, scale, translate ve HSV üçlüsü aktif. Geri kalan her şey kapalı. Ultralytics’in agresif olmayan bir taban seçmesi tesadüf değil.

scale: en çok işe yarayan, en çok gözden kaçan

scale=0.5 görüntüyü rastgele 0.5x ile 1.5x arasında yeniden boyutlandırır. Nesne tespitinde ölçek çeşitliliği doğrudan işe yarar, çünkü aynı hedef 20 metreden ve 60 metreden bambaşka piksel boyutlarında görünür.

Bizim durumumuzda bu kritikti: veri setimizin büyük kısmı yerden çekilmiş, nesnelerin kadrajı doldurduğu görsellerden oluşuyordu. Uçuşta ise hedefler kare içinde çok daha küçük. scale, bu boşluğun bir kısmını kapatan en ucuz araç.

scale float yerine (min, max) demeti de kabul ediyor — yani asimetrik bir aralık verebilirsiniz. Küçük nesne problemi yaşıyorsanız küçültme yönüne ağırlık vermek mantıklı:

model.train(
    data="suas.yaml",
    imgsz=1280,
    scale=(0.4, 1.2),   # küçültmeye ağırlık ver
    mosaic=1.0,
    close_mosaic=10,
)

Uyarı: mosaic zaten dört görüntüyü tek tuvale sıkıştırdığı için nesneleri küçültür. Üstüne agresif scale binince nesneler birkaç piksele düşebilir ve etiket filtrelerine takılıp tamamen kaybolabilir. İkisini birlikte ayarlayın, ayrı ayrı değil.

fliplr ve flipud: havadan görüntüde ikisi de geçerli

fliplr (yatay çevirme) varsayılan olarak 0.5, yani görüntülerin yarısı aynalanıyor. Bu çoğu problemde güvenlidir — ama metin, plaka ya da sol/sağ ayrımı taşıyan sınıflarda sinyali bozar.

flipud (dikey çevirme) varsayılan olarak 0.0 ve bunun sebebi net: yerden çekilmiş görüntülerde yerçekimi gerçek bir kısıttır. Baş aşağı bir insan, eğitim setinde olmaması gereken bir sahnedir.

Havadan bakışta bu kısıt ortadan kalkar. Nadir kamera aşağı bakıyorsa, drone’un irtifa sabit tutarak hangi yönde uçtuğu görüntüdeki nesne yönelimini keyfî kılar. Aynı çadır, kuzeye giden bir geçişte ve güneye giden bir geçişte 180 derece farkla görünür. Bu yüzden havadan veri setlerinde flipud=0.5 yalnızca güvenli değil, aktif olarak faydalıdır — üstelik döndürme gibi kutu geometrisini bozmadan.

degrees: kutuyu gevşeten sessiz maliyet

Döndürme masum görünür ama etiket formatıyla çatışır. YOLO etiketleri eksene hizalı (axis-aligned) kutulardır — kenarları her zaman görüntü kenarlarına paraleldir. Döndürülmüş bir kutuyu saklayacak bir alan yoktur.

Ultralytics’in kaynak kodunda RandomPerspective.apply_bboxes tam olarak şunu yapıyor: kutunun dört köşesini dönüşüm matrisiyle taşıyor, sonra taşınmış köşelerin x.min(), y.min(), x.max(), y.max() değerlerinden yeni bir eksene hizalı kutu üretiyor. Yani döndürülmüş nesnenin etrafına çizilen kutu, orijinalinden geniştir ve içinde nesneye ait olmayan piksel taşır.

Kayıp en fazla 45 derecede olur ve uzun-ince nesnelerde (yatan bir insan figürü gibi) çok daha belirgindir. Kare gibi nesnelerde önemsizdir. Pratik sonuç: degrees değerini küçük tutun (5–10 aralığı çoğu senaryo için yeterli), ya da gerçekten 360 derece yönelim çeşitliliği gerekiyorsa döndürme yerine flipud + fliplr kombinasyonunu tercih edin — bu ikisi kutuyu hiç gevşetmez.

mosaic ve close_mosaic: aç, sonra kapat

mosaic=1.0 her eğitim örneğinde dört görüntüyü 2x2 bir tuvale birleştirir. Bu, tek karede sınıf çeşitliliğini ve bağlam varyasyonunu artırır; küçük nesne performansına da yardım eder çünkü nesneler doğal olarak küçülür.

Ama ürettiği kare gerçek bir kare değildir. Dört farklı sahnenin dikişli birleşimidir ve uçuşta kameradan asla böyle bir görüntü gelmez. close_mosaic=10 (varsayılan) tam bu yüzden var: son 10 epoch’ta mosaic kapanır ve model gerçek, tek parça karelerle ince ayar yapar. Doğrulama metrikleriniz genellikle bu noktada belirgin biçimde toparlanır.

close_mosaic değerini 0 yaparsanız mosaic sonuna kadar açık kalır — kısa eğitimlerde bu, modelin hiçbir zaman “temiz” bir kare görmemesi anlamına gelir. 100 epoch’luk bir eğitimde varsayılan 10’u değiştirmek için özel bir sebebiniz olmalı.

mixup ve cutmix: sınıflandırmadan gelen misafirler

mixup iki görüntüyü şeffaflıkla harmanlar ve etiketleri de karıştırır. cutmix bir görüntüden dikdörtgen bir bölgeyi kesip diğerine yapıştırır. İkisi de varsayılan olarak 0.0 — kapalı.

Bunlar sınıflandırma literatüründen gelen tekniklerdir ve tespit görevinde daha tartışmalıdır. mixup yarı saydam hayalet nesneler üretir. İkisini de yalnızca aşırı öğrenme (overfitting) gözlemlediğinizde ve küçük değerlerle (0.05–0.15) deneyin.

copy_paste: segmentasyon maskesi olmadan çalışmaz

Bu, en sık yanlış anlaşılan parametre. copy_paste, bir görüntüden nesneleri kesip başka bir sahneye yapıştırarak sınıf dengesizliğini düzeltmenin doğrudan yoludur — kulağa tam bizim 7:1 sınıf dengesizliğimizin çözümü gibi geliyor.

Sorun şu: nesneyi temiz kesebilmek için piksel seviyesinde segmentasyon maskesi gerekir, kutu yetmez. Ultralytics kaynak kodu bunu sessizce ele alıyor:

if len(labels["instances"].segments) == 0 or self.p == 0:
    return labels

Yani sadece kutu etiketli bir tespit veri setinde copy_paste=0.5 yazarsanız hiçbir hata almazsınız; augmentation sessizce hiç uygulanmaz. Etkisi olduğunu sanıp epoch’larca beklersiniz.

copy_paste_mode iki değer alır: flip (varsayılan) nesneleri aynı görüntüden kopyalar, mixup farklı görüntülerden. Her ikisinde de yapıştırma, mevcut nesnelerle örtüşme oranı %30’un altındaysa yapılır.

erasing ve auto_augment: sınıflandırmaya ait

erasing=0.4 ve auto_augment='randaugment' varsayılanları dokümantasyonda “Sınıflandırmaya Özgü Augmentasyonlar” başlığı altında yer alıyor. Tespit eğitiminde bu satırları yazmanın bir etkisi olmaz.

Bir sınıflandırma modeli eğitiyorsanız yine de dikkat: nesne kadrajın büyük kısmını dolduruyorsa silme, kısmi örtülmeye karşı dayanıklılık kazandırır. Nesne zaten küçükse silinen dikdörtgen nesnenin tamamını kapatabilir ve modele “bu görüntüde X var” diyen bir etiketle birlikte X’siz bir görüntü verirsiniz — doğrudan gürültü. Ayrıca erasing’in scale, ratio ve value alt parametreleri mevcut implementasyonda değiştirilemiyor.

Hangi durumda hangisi zarar verir

Parametre Şu durumda zarar verir Ne yapmalı
scale (yüksek) Nesneler zaten küçük; mosaic de açık Aralığı daralt, mosaic ile birlikte ayarla
fliplr Sol/sağ anlam taşıyor (metin, plaka, ok işareti) 0.0 yap
flipud Yerden/eğik bakış, yerçekimi görünür Nadir bakış değilse 0.0’da bırak
degrees Uzun-ince nesneler; kamera zaten sabit yönelimli 0–10 arası tut, ya da flip’leri tercih et
shear, perspective Kamera geometrisi sabit ve bilinen Kapalı bırak
hsv_s / hsv_h (yüksek) Renk sınıfı ayırt ediyor (kırmızı vs yeşil hedef) Ton kaydırmayı düşür, parlaklığı koru
mosaic (son epoch’larda) Model hiç temiz kare görmüyor close_mosaic’i 0 yapma
mixup / cutmix Küçük veri seti, tespit görevi Kapalı başla, sadece overfit varsa aç
copy_paste Maske etiketi yok Sessizce çalışmaz — segmentasyon etiketi üret
erasing Nesne kare içinde küçük Sınıflandırmada bile düşür

Sık düşülen tuzaklar

Augmentation’ı veri eksikliği için kullanmak. Bir sınıfın örneği azsa augmentation onu çoğaltmaz, sadece aynı birkaç örneği tekrar tekrar gösterir. Bizim veri setimizde sınıflar arası 7:1 fark vardı ve bunu augmentation ile kapatmaya çalışmak işe yaramadı; çözüm daha fazla gerçek havadan kare toplamak oldu.

Augmentation’ı doğrulama setine sızdırmak. Ultralytics doğrulamada augmentation uygulamaz, ama kendi ön işleme adımınızı yazıp veri setine yazılmış (offline) augmentasyon üretiyorsanız, aynı görüntünün varyantlarının hem train hem val tarafına düşmemesine dikkat edin. Bölmeyi varyant değil kaynak görüntü bazında yapın.

Fiziksel olarak imkânsız sahneler üretmek. Ultralytics’in kendi eğitim materyalindeki test basit: bu görüntü dağıtımda gerçekten oluşabilir mi? Oluşamıyorsa model kapasitesini boşa harcıyorsunuz demektir.

Her şeyi aynı anda değiştirmek. Beş parametreyi birlikte değiştirip mAP’e bakarsanız hangisinin ne yaptığını asla öğrenemezsiniz. Varsayılandan başlayıp tek seferde tek parametre oynatın.

Eğitim çözünürlüğüyle uçuş çözünürlüğünü karıştırmak. Biz imgsz=1280 ile eğitip uçuşta 640 tam-kare çıkarım yapıyoruz. Augmentation’ın ürettiği efektif nesne boyutunu değerlendirirken eğitim çözünürlüğünü esas alın; ama neyin işe yaradığını uçuş koşullarına yakın bir doğrulama setinde ölçün. Bizde aerial-only doğrulama setinde mAP50 0.950’ye çıkan konfigürasyon, karışık doğrulama setinde ölçtüğümüzde bambaşka görünüyordu.

Pratik özet

  1. Varsayılanlarla başlayın. mosaic=1.0, fliplr=0.5, scale=0.5, translate=0.1, HSV üçlüsü — geri kalanı kapalı. Bu taban çoğu tespit problemi için makul.
  2. Nadir (aşağı bakan) kamera kullanıyorsanız flipud=0.5 açın. Kutu geometrisini bozmadan yönelim çeşitliliği kazandıran tek dönüşüm bu.
  3. degrees yerine flip’leri tercih edin. Döndürme, eksene hizalı kutuyu genişletir ve etikete arka plan pikseli katar.
  4. close_mosaic’i 0 yapmayın. Son epoch’larda gerçek karelerle ince ayar, mosaic’in dikiş izlerini temizler.
  5. copy_paste için önce maske üretin. Segmentasyon etiketiniz yoksa parametre sessizce yok sayılır; hata mesajı beklemeyin.
  6. Her değişikliği aynı doğrulama setinde ölçün ve o setin uçuş koşullarını temsil ettiğinden emin olun.
  • augmentation
  • ultralytics
  • yolo
  • veri-seti
  • egitim

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