Ultralytics YOLO27: Iscriviti alla lista d'attesa.
Get Started
Lezioneintermedio

Segmentazione semantica: etichettare ogni pixel

Prevedi una mappa delle classi per pixel con yolo26n-sem.pt, trasformala in valori di copertura, crea dataset di mappe delle classi PNG e interpreta mIoU senza lasciarti ingannare dall'accuratezza dei pixel.

Alcune domande non riguardano il conteggio degli oggetti: quanta parte del marciapiede è bloccata, quanta parte di un campo è invasa dalle erbacce, dove finisce la strada percorribile. La segmentazione semantica risponde assegnando un ID di classe a ogni pixel. La sua metrica principale, però, può essere interpretata male facilmente: il modello che addestri in questa lezione raggiunge un'accuratezza dei pixel del 91% senza mai rilevare una persona.

Esito

Trasforma una mappa delle classi di yolo26n-sem.pt in un valore di copertura per una regione del fotogramma, addestra il modello su Cityscapes8 e riporta mIoU, l'accuratezza dei pixel e le classi che il modello non rileva.

Percorso rapido
Se sai già come muoverti, ecco la versione breve.
  1. Esegui la previsione con yolo26n-sem.pt e leggi result.semantic_mask.data: un tensore H × W di ID di classe alle dimensioni originali, con 255 = ignora.

  2. Rispondi alle domande sulla copertura confrontando la mappa delle classi con gli ID di classe di result.names.

  3. Salva le etichette come mappe delle classi PNG senza perdita in masks/, rispecchiando images/, con masks_dir: masks nel file YAML.

  4. Vincola i rilasci a mIoU e IoU per classe, mai alla sola accuratezza dei pixel.

Pratico

Segmentazione di istanze o semantica?#

Segmentazione semantica di una strada cittadina, con ogni pixel colorato in base alla classe: strada, marciapiede, automobile, persona, bicicletta, vegetazione, edificio e cielo

Segmentazione di istanze (segment)Segmentazione semantica (semantic)
Outputuna maschera per oggetto, più un riquadroun ID di classe per pixel
Conta gli oggettisìno — due auto a contatto formano un'unica regione "auto"
Gestisce le classi di tipo "stuff" (strada, cielo, erba)male — non esistono istanze naturalisì
Etichettepoligonimappe delle classi PNG o poligoni
Metrica di sogliamAP50-95 delle mascheremIoU
Pesi preaddestratiyolo26n-seg.pt (COCO, 80 classi)yolo26n-sem.pt (Cityscapes, 19 classi)
Quanti o quanto?

Se la domanda a valle include «quanti», usa la segmentazione di istanze. Se invece chiede «quanto» o «dove», la segmentazione semantica è più semplice da etichettare e interpretare. La pagina del task di segmentazione semantica contiene la tabella dei modelli.

Prevedere una mappa delle classi#

result.semantic_mask.data è un tensore H × W alle dimensioni originali dell'immagine; ogni valore è un ID di classe e 255 significa ignora. result.summary() lo trasforma in rapporti di pixel per classe:

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%

Guarda l'ultima riga. Cityscapes contiene una classe bus, ma il modello classifica l'autobus come train. Il modello è stato addestrato su riprese effettuate da automobili, perlopiù su strade tedesche, e un autobus fotografato da vicino dal marciapiede è fuori da tale distribuzione. I modelli semantici ereditano il punto di vista e le definizioni delle classi del set di addestramento — il suo bias del dataset — in modo più rigido rispetto ai rilevatori. Perciò, prima di affidarti alla mappa, esegui il fine-tuning usando la tua telecamera.

Trasforma la mappa delle classi in una risposta#

Una mappa delle classi diventa un valore utile al prodotto con semplici confronti tra tensori. Ecco la domanda: "quanta parte dell'area in cui camminerebbe un pedone è strada o marciapiede, e quanta è occupata da persone?"

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

Tre abitudini rendono affidabili questi valori:

  • Cerca gli ID per nome in result.names, mai usando un numero codificato direttamente: un modello addestrato sulle tue classi assegnerà loro numeri diversi.
  • Limita l'analisi alla regione rilevante. I rapporti sull'intero fotogramma includono cielo ed edifici; prima ritaglia la mappa delle classi oppure moltiplicala per una maschera della regione.
  • Apri la sovrapposizione. semantic_overlay.jpg ti mostra subito se la "strada" conteggiata dal valore è davvero una strada.

Il formato del dataset#

I dataset semantici associano a ogni immagine una maschera a canale singolo, i cui valori dei pixel sono ID di classe. La guida ai dataset semantici è il riferimento; la struttura rispecchia quella di images/ file per file:

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

Il file YAML aggiunge masks_dir e, quando gli ID memorizzati nelle maschere differiscono dagli ID usati per l'addestramento, un blocco label_mapping:

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
  # ...

Le maschere Cityscapes memorizzano gli ID grezzi delle etichette da -1 a 33; la mappatura ne conserva 19 e assegna gli altri a ignore_label, memorizzato come 255. I pixel impostati su 255 vengono esclusi sia dalla loss sia dalle metriche: usa lo stesso valore per le regioni su cui i tuoi annotatori non sono riusciti a decidere.

Se hai già etichette poligonali ma non hai masks_dir, il caricatore rasterizza i poligoni e aggiunge una classe background per i pixel non coperti.

Non salvare mai le maschere in JPEG

La compressione con perdita altera i valori dei pixel adiacenti, trasformando il confine tra la classe 7 e la classe 8 in una sfumatura di 7, 8 e ID inesistenti. Salva tutte le maschere in PNG o TIFF.

Addestramento e interpretazione di mIoU#

Cityscapes8 contiene 8 immagini di scene urbane, 4 per l'addestramento e 4 per la validazione: un numero sufficiente per un test rapido su CPU:

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

(Righe per classe abbreviate.) L'accuratezza dei pixel indica il 91%; mIoU indica il 42%; le righe per classe mostrano che il modello non ha rilevato nemmeno una persona. Sono tutti e tre risultati corretti. Strada, edificio e vegetazione occupano la maggior parte dei pixel: la sola strada ne copre 78,529 su 192,315. Perciò, un modello che le classifica bene ottiene un'accuratezza dei pixel elevata anche se non rileva nessuna delle classi piccole. mIoU calcola la media di IoU per classe assegnando a tutte lo stesso peso, quindi ogni classe non rilevata abbassa il risultato.

Intersezione sull'unione su un uccello: l'intersezione tra le regioni previste e quelle di riferimento divisa per la loro unione, sia per i riquadri sia per le maschere

Regola decisionale

Imponi una soglia su mIoU e su IoU per le classi su cui interviene il tuo prodotto. Se una funzione di sicurezza per i pedoni ha IoU 0 per la classe persona, non è accettabile, a prescindere dall'accuratezza sui pixel.

Provalo

Esegui semantic.py su una tua foto di strada e indica le tre classi più numerose. Adatta walkable.py per rispondere a una domanda sulla copertura della foto, per esempio quale percentuale della metà inferiore è occupata dalla strada. Poi addestra per un'epoca su cityscapes8.yaml e annota mIoU, l'accuratezza dei pixel e tutte le classi con IoU pari a 0.

Criteri di completamento
La lezione è completata quando tutte le seguenti condizioni sono soddisfatte.
  • Hai i rapporti di pixel per classe e un valore di copertura di una regione della tua immagine, verificato confrontandolo con la sovrapposizione salvata.

  • Hai annotato mIoU e l'accuratezza dei pixel dall'esecuzione dell'addestramento e hai elencato le classi con IoU pari a zero.

  • Sai spiegare in una frase perché in questa esecuzione l'accuratezza dei pixel è superiore a mIoU.

Mostra la soluzione

Nella nostra esecuzione: mIoU 0.415, accuratezza dei pixel 0.906 e IoU pari a 0 per muro, persona, ciclista, motocicletta e bicicletta, oltre a tutte le classi senza pixel nelle quattro immagini di validazione.

L'accuratezza dei pixel è più alta perché conta i pixel e strada, edificio, vegetazione e cielo costituiscono la maggior parte di ogni fotogramma Cityscapes. mIoU assegna lo stesso peso a ogni classe, quindi cinque classi piccole non rilevate abbassano la media anche se coprono solo poche centinaia di pixel. Per un prodotto che prende decisioni sulle persone, questo modello non supera il criterio di accettazione basandosi solo sull'IoU della classe persona.

Prossimi passi

Ora passiamo dalle regioni ai punti ed etichettiamo e addestriamo un modello di posa.

Accedi per salvare i progressi