Ultralytics YOLO27: Bekleme listesine katıl.
Get Started
Dersorta düzey

Anlamsal Segmentasyon: Her Piksele Etiket Ver

yolo26n-sem.pt ile piksel başına bir sınıf haritası tahmin et, bunu kapsama değerlerine dönüştür, PNG sınıf haritası veri kümeleri oluştur ve piksel doğruluğuna aldanmadan mIoU değerini yorumla.

Bazı soruların sayılacak nesneleri yoktur: kaldırımın ne kadarı kapalı, bir tarlanın ne kadarı yabani otlarla kaplı, araçla gidilebilir yol nerede bitiyor? Anlamsal segmentasyon, her piksele bir sınıf kimliği atayarak bu soruları yanıtlar. Ancak öne çıkan metriği yanlış yorumlamak kolaydır: bu derste eğittiğin model, tek bir kişi bile bulamazken %91 piksel doğruluğu elde ediyor.

Sonuç

Bir yolo26n-sem.pt sınıf haritasını karenin bir bölgesi için kapsama değerine dönüştür, Cityscapes8 üzerinde eğitim yap ve mIoU, piksel doğruluğu ile modelin kaçırdığı sınıfları bildir.

Hızlı Başlangıç
Nasıl ilerleyeceğini zaten biliyorsan, işte kısa sürüm.
  1. yolo26n-sem.pt ile tahmin yap ve result.semantic_mask.data değerini oku: özgün boyutta sınıf kimliklerinden oluşan H × W tensörü; 255 = yoksay.

  2. Sınıf haritasını result.names içindeki sınıf kimlikleriyle karşılaştırarak kapsama sorularını yanıtla.

  3. Etiketleri, images/ yapısını dosya dosya yansıtacak şekilde masks/ altında kayıpsız PNG sınıf haritaları olarak sakla ve YAML dosyasında masks_dir: masks kullan.

  4. Sürümleri yalnızca piksel doğruluğuna göre değil, mIoU ve sınıf başına IoU değerlerine göre onayla.

Uygulamalı

Örnek mi, anlamsal mı?#

Her pikselin yol, kaldırım, araba, kişi, bisiklet, bitki örtüsü, bina ve gökyüzü sınıflarına göre renklendirildiği, bir şehir sokağının anlamsal segmentasyonu

Örnek segmentasyonu (segment)Anlamsal segmentasyon (semantic)
Çıktıher nesne için bir maske ve bir kutuher piksel için bir sınıf kimliği
Nesneleri sayarevethayır — birbirine değen iki araba tek bir “araba” bölgesidir
“Şeyleri” (yol, gökyüzü, çimen) ele alırzayıf — doğal örnekler yokevet
EtiketlerçokgenlerPNG sınıf haritaları veya çokgenler
Eşik metriğimaske mAP50-95mIoU
Önceden eğitilmiş ağırlıklaryolo26n-seg.pt (COCO, 80 sınıf)yolo26n-sem.pt (Cityscapes, 19 sınıf)
Kaç tane, yoksa ne kadar mı?

Sonraki aşamadaki soru "kaç tane" ise örnek segmentasyonu kullan. Soru "ne kadar" veya "nerede" ise semantik segmentasyonun etiketlenmesi ve okunması daha kolaydır. Model tablosu için Semantik Segmentasyon görev sayfasına bak.

Bir sınıf haritası tahmin et#

result.semantic_mask.data, özgün görüntü boyutlarında bir H × W tensörüdür; her değer bir sınıf kimliğidir ve 255 yoksay anlamına gelir. result.summary() bunu sınıf başına piksel oranlarına dönüştürür:

from ultralytics import YOLO

model = YOLO("yolo26n-sem.pt")  # Cityscapes, 19 classes
result = model("https://ultralytics.com/images/bus.jpg")[0]

class_map = result.semantic_mask.data  # H x W tensor of class ids, 255 = ignore
print("class map:", tuple(class_map.shape), class_map.dtype)
for row in result.summary():
    if row["pixel_ratio"] >= 0.02:
        print(f"{row['name']:12s} {row['pixel_ratio']:.1%}")
class map: (1080, 810) torch.uint8
road         27.5%
sidewalk     2.0%
building     19.3%
vegetation   4.5%
person       14.6%
train        30.9%

Son satıra bak. Cityscapes'te bir bus sınıfı var, ancak model otobüsü train olarak adlandırıyor. Model, çoğunlukla Alman sokaklarının araçlara monte edilmiş kameralardan çekilmiş görüntüleriyle öğrenmiş; kaldırımdan yakından fotoğraflanan bir otobüs bu dağılımın dışında kalıyor. Anlamsal modeller, eğitim kümelerinin bakış açısını ve sınıf tanımlarını — yani veri kümesi yanlılığını — dedektörlere kıyasla daha katı biçimde devralır. Bu nedenle haritaya güvenmeden önce kendi kamerandan gelen verilerle ince ayar yap.

Sınıf haritasını bir yanıta dönüştür#

Sınıf haritası, basit tensör karşılaştırmalarıyla bir ürün metriğine dönüşür. İşte “bir yayanın üzerine yürüyeceği alanın ne kadarı yol veya kaldırım, ne kadarı insan?” sorusunun yanıtı:

from ultralytics import YOLO

result = YOLO("yolo26n-sem.pt")("https://ultralytics.com/images/bus.jpg", verbose=False)[0]
class_map = result.semantic_mask.data  # H x W class ids at the original size, 255 = ignore
ids = {name: i for i, name in result.names.items()}

h = class_map.shape[0]
lower = class_map[h // 2 :]  # the half of the frame a pedestrian would walk into
walkable = (lower == ids["road"]) | (lower == ids["sidewalk"])
people = lower == ids["person"]
print(f"lower half: {walkable.float().mean():.0%} road or sidewalk, {people.float().mean():.0%} person")
result.save("semantic_overlay.jpg")  # colored class map over the photo, for a visual check
lower half: 59% road or sidewalk, 23% person

Bu sayıların güvenilir olması için üç alışkanlık edin:

  • Kimlikleri ada göre bul: result.names içinden al; sabit kodlanmış sayıları asla kullanma. Kendi sınıflarınla eğitilmiş bir model, sınıfları farklı numaralandırır.
  • Önemli bölgeyle sınırla. Tüm kareye ait oranlar gökyüzünü ve binaları da içerir; önce sınıf haritasını dilimle (veya bir bölge maskesiyle çarp).
  • Bindirmeyi aç. semantic_overlay.jpg, sayının “yol” olarak saydığı bölgenin gerçekten yol olup olmadığını tek bakışta gösterir.

Veri kümesi biçimi#

Anlamsal veri kümelerinde her görüntü, piksel değerlerinin sınıf kimlikleri olduğu tek kanallı bir maske görüntüsüyle eşleştirilir. Anlamsal veri kümesi kılavuzu başvuru kaynağıdır; dizin yapısı images/ ile dosya dosya aynıdır:

cityscapes8/
├── images/
│   ├── train/aachen_000000_000019.png
│   └── val/aachen_000004_000019.png
└── masks/
    ├── train/aachen_000000_000019.png
    └── val/aachen_000004_000019.png

YAML dosyasında masks_dir bulunur; maskelerinde saklanan kimlikler eğitim kimliklerinden farklıysa ayrıca bir label_mapping bloğu eklenir:

path: cityscapes8
train: images/train
val: images/val
masks_dir: masks # semantic mask directory

names:
  0: road
  1: sidewalk
  # ... 19 classes in total

label_mapping: # raw mask value -> training id
  0: ignore_label
  7: 0 # road
  8: 1 # sidewalk
  # ...

Cityscapes maskeleri -1 ile 33 arasındaki ham etiket kimliklerini saklar; eşleme bunlardan 19'unu tutar ve geri kalanları 255 olarak saklanan ignore_label değerine yönlendirir. 255 olarak ayarlanmış pikseller hem kayıp hem de metrik hesaplamalarından çıkarılır; etiketleyicilerin karar veremediği bölgeler için de aynı değeri kullan.

Poligon etiketlerin varsa ancak masks_dir yoksa, yükleyici poligonları senin için rasterleştirir ve kaplanmamış piksellere background sınıfını ekler.

Maskeleri asla JPEG olarak kaydetme

Kayıplı sıkıştırma, komşu piksel değerlerini birbirine karıştırır; 7. sınıf ile 8. sınıf arasındaki sınırı 7'ler, 8'ler ve mevcut olmayan kimliklerden oluşan bir bulanıklığa dönüştürür. Her maskeyi PNG veya TIFF olarak kaydet.

mIoU değerini eğit ve yorumla#

Cityscapes8, 4'ü eğitim ve 4'ü doğrulama için kullanılan 8 şehir sahnesi görüntüsü içerir; CPU üzerinde hızlı bir test yapmak için yeterlidir:

from ultralytics import YOLO

model = YOLO("yolo26n-sem.pt")
model.train(data="cityscapes8.yaml", epochs=1, imgsz=320, device="cpu")
metrics = model.val()
print(f"mIoU: {metrics.miou:.3f}  pixel accuracy: {metrics.pixel_accuracy:.3f}")
                 Class     Images     Pixels       mIoU     PixAcc
                   all          4     192315      0.415      0.906
                  road          4      78529      0.974      0.996
            vegetation          4      37602      0.844      0.936
                person          3        722          0          0
                 rider          1         21          0          0
mIoU: 0.415  pixel accuracy: 0.906

(Sınıf başına satırlar kısaltıldı.) Piksel doğruluğu %91 gösteriyor; mIoU %42; sınıf başına satırlar ise modelin tek bir kişi bile bulamadığını gösteriyor. Üçü de doğru. Piksellerin çoğu yol, bina ve bitki örtüsüne aittir — yalnızca yol 192,315 pikselin 78,529'unu oluşturur — dolayısıyla bu bölgeleri iyi boyayan bir model, tüm küçük sınıfları kaçırırken yüksek piksel doğruluğu elde eder. mIoU, sınıf başına IoU değerlerinin eşit ağırlıklı ortalamasını alır; bu nedenle kaçırılan her sınıf mIoU değerini düşürür.

Bir kuş üzerinde Birleşim Üzerinde Kesişim: hem kutular hem de maskeler için tahmin edilen ve gerçek bölgelerin kesişiminin birleşimlerine oranı

Karar kuralı

mIoU ve ürününün işlem yaptığı sınıfların IoU değeri için eşik belirle. Kişi IoU değeri 0 olan bir yaya güvenliği özelliği başarısızdır; piksel doğruluğu ne gösterirse göstersin.

Dene

semantic.py aracını kendi sokak fotoğrafında çalıştır ve en büyük üç sınıfı listele. Fotoğrafınla ilgili bir kapsama sorusunu yanıtlayacak şekilde walkable.py kodunu uyarla; örneğin alt yarının ne kadarının yol olduğunu bul. Ardından cityscapes8.yaml üzerinde bir epoch eğitim yap ve mIoU, piksel doğruluğu ile IoU değeri 0 olan tüm sınıfları not et.

Tamamlanma ölçütü
Aşağıdakilerin tümü doğru olduğunda dersi tamamlamış olursun.
  • Kendi görüntün için sınıf başına piksel oranlarını ve bölgeye ait bir kapsama değerini elde ettin ve bunları kaydedilmiş bindirmeyle kontrol ettin.

  • Eğitim çalıştırmasından mIoU ve piksel doğruluğunu kaydettin ve IoU değeri sıfır olan sınıfları listeledin.

  • Bu çalıştırmada piksel doğruluğunun neden mIoU'dan yüksek olduğunu tek cümleyle açıklayabilirsin.

Çözümü göster

Çalıştırmamızda: mIoU 0.415, piksel doğruluğu 0.906; duvar, kişi, binici, motosiklet ve bisiklet için IoU 0. Ayrıca dört doğrulama görüntüsünde hiç pikseli bulunmayan tüm sınıfların IoU değeri de 0.

Piksel doğruluğu daha yüksektir çünkü pikselleri sayar ve her Cityscapes karesinin büyük kısmını yol, bina, bitki örtüsü ve gökyüzü oluşturur. mIoU her sınıfa eşit ağırlık verir; bu nedenle kaçırılan beş küçük sınıf yalnızca birkaç yüz piksel kaplasa da ortalamayı düşürür. İnsanlar üzerinde işlem yapan bir ürün için bu model, yalnızca kişi IoU değerinden dolayı onay eşiğini geçemez.

Sırada ne var

Ardından bölgelerden noktalara geçip bir poz modelini etiketleyecek ve eğiteceğiz.

İlerlemeni kaydetmek için giriş yap