Vai al contenuto

Comprendere il rilevamento end-to-end in Ultralytics

Introduzione

Se stai effettuando l'aggiornamento a YOLO26 da un modello precedente come YOLOv8 o YOLO11, uno dei cambiamenti più evidenti che noterai è la rimozione della Non-Maximum Suppression (NMS). YOLO tradizionali producono migliaia di previsioni sovrapposte che richiedono una fase NMS separata per filtrare i risultati e ottenere i rilevamenti finali. Ciò aggiunge latenza, complica l'esportazione dei grafici e può comportarsi in modo incoerente su piattaforme hardware diverse.

YOLO26 adotta un approccio diverso. Fornisce i risultati finali del rilevamento direttamente dal modello, senza bisogno di alcun filtraggio esterno. Si tratta del cosiddetto " rilevamento di oggetti end-to-end", abilitato di default in tutti i modelli YOLO26. Il risultato è una pipeline di implementazione più semplice, una minore latenza e un'inferenza fino al 43% più veloce sulle CPU.

Questa guida illustra le modifiche apportate, indica se è necessario aggiornare il codice, spiega quali formati di esportazione supportano l'inferenza end-to-end e spiega come effettuare una migrazione senza intoppi dai YOLO precedenti.

Per approfondire le ragioni alla base di questo cambiamento architettonico, consulta il postUltralytics che spiega perché YOLO26 elimina NMS.

Sintesi

  • Utilizzi Ultralytics o CLI Ultralytics ? Non occorre modificare nulla: basta sostituire il nome del modello con yolo26n.pt.
  • Utilizzi codice di inferenza personalizzato (ONNX , TensorRT, ecc.)? Aggiorna la tua post-elaborazione: l'output del rilevamento ora è (N, 300, 6) in xyxy formato, non NMS . Altre operazioni aggiungono dati supplementari (coefficienti di maschera, punti chiave o angoli).
  • Vuoi esportare? La maggior parte dei formati supporta nativamente l'output end-to-end. Tuttavia, alcuni formati (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX ed Edge TPU) ricorrono automaticamente all'output tradizionale a causa di vincoli degli operatori non supportati (ad es., torch.topk).

Come funziona il rilevamento end-to-end

YOLO26 utilizza un'architettura a doppia testa durante l'addestramento. Entrambe le teste condividono la stessa struttura di base e lo stesso "collo", ma generano output in modi diversi:

TestaScopoUscita di rilevamentoPost-elaborazione
Uno-a-Uno (predefinito)Inferenza end-to-end(N, 300, 6)Solo soglia di confidenza
Uno a moltiYOLO tradizionale(N, nc + 4, 8400)Richiede NMS

Le forme sopra riportate servono al rilevamento. Altre attività ampliano l'output uno a uno con dati aggiuntivi per ogni rilevamento:

TaskRisultato finaleDati aggiuntivi
Rilevamento(N, 300, 6)
Segmentazione(N, 300, 6 + nm) + proto (N, nm, H, W)nm coefficienti di maschera (impostazione predefinita: 32)
Posa(N, 300, 57)17 punti chiave × 3 (x, y, visibilità)
OBB(N, 300, 7)Angolo di rotazione

Durante l'addestramento, entrambe le reti funzionano contemporaneamente: la rete "uno-a-molti" fornisce un segnale di apprendimento più ricco, mentre la rete "uno-a-uno" impara a generare previsioni precise e non sovrapposte. Durante inferenza e export, solo il testina singola è attiva per impostazione predefinita e genera fino a 300 rilevamenti per immagine nel formato [x1, y1, x2, y2, confidence, class_id].

Quando chiami model.fuse(), ripiega i layer Conv + BatchNorm per un'inferenza più rapida e, nei modelli end-to-end, rimuove anche l'head one-to-many — riducendo le dimensioni del modello e i FLOPs. Per maggiori dettagli sull'architettura dual-head, consultare il Pagina del modello YOLO26.

Devo modificare il mio codice?

UtilizzoPython o CLI Ultralytics

Nessuna modifica necessaria. Se utilizzi l'API Ultralytics python standard o la CLI, tutto funziona automaticamente — previsione, validazione ed esportazione gestiscono tutti i modelli end-to-end out of the box.

Ultralytics di Ultralytics non richiede alcuna modifica al codice

from ultralytics import YOLO

# Load a YOLO26 model
model = YOLO("yolo26n.pt")

# Predict — no NMS step, no code changes
results = model.predict("image.jpg")
yolo predict model=yolo26n.pt source=image.jpg

Utilizzo di codice di inferenza personalizzato

Sì, il formato di output è diverso. Se hai scritto una logica di post-elaborazione personalizzata per YOLOv8 o YOLO11 (ad esempio, durante l'esecuzione dell'inferenza con ONNX Runtime o TensorRT), dovrai aggiornarla per gestire la nuova forma dell'output:

YOLOv8 YOLO11YOLO26 (end-to-end)
Segnale di rilevamento(N, nc + 4, 8400)(N, 300, 6)
Formato della confezionexywh (centro x, centro y, larghezza, altezza)xyxy (x in alto a sinistra, y in alto a sinistra, x in basso a destra, y in basso a destra)
ImpaginazioneCoordinate delle caselle + punteggi delle classi per ogni punto di riferimento[x1, y1, x2, y2, conf, class_id]
NMSNo
Post-elaborazioneNMS filtro di confidenzaSolo filtro di affidabilità

Per le attività di segmentazione, posa e OBB, YOLO26 aggiunge dati specifici per ciascuna attività a ogni rilevamento — si veda la tabella delle forme di output sopra riportata.

Dove N è il dimensione del batch e nc è il numero di classi (ad esempio, 80 per COCO).

Con i modelli end-to-end, la post-elaborazione diventa molto più semplice — ad esempio, quando si utilizza ONNX :

import onnxruntime as ort

# Load and run the exported end-to-end model
session = ort.InferenceSession("yolo26n.onnx")
output = session.run(None, {session.get_inputs()[0].name: input_tensor})

# End-to-end output: (batch, 300, 6) → [x1, y1, x2, y2, confidence, class_id]
detections = output[0][0]  # first image in batch
detections = detections[detections[:, 4] > conf_threshold]  # confidence filter — that's it!

Passaggio alla testina "uno a molti"

Se hai bisogno del formato YOLO tradizionale YOLO (ad esempio, per riutilizzare il codice di post-elaborazione esistente NMS), puoi passare in qualsiasi momento alla configurazione "one-to-many" impostando end2end=False:

Utilizzo dell'interfaccia "uno-a-molti" per l'output tradizionale NMS

from ultralytics import YOLO

model = YOLO("yolo26n.pt")

# Prediction with NMS (traditional behavior)
results = model.predict("image.jpg", end2end=False)

# Validation with NMS
metrics = model.val(data="coco.yaml", end2end=False)

# Export without end-to-end
model.export(format="onnx", end2end=False)
yolo predict model=yolo26n.pt source=image.jpg end2end=False
yolo val model=yolo26n.pt data=coco.yaml end2end=False
yolo export model=yolo26n.pt format=onnx end2end=False

Compatibilità dei formati di esportazione

La maggior parte dei formati di esportazione supporta l'inferenza end-to-end fin da subito, tra cui ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js e MNN.

I seguenti formati non supportano l'end-to-end e passano automaticamente alla configurazione one-to-many: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX e Edge TPU.

Cosa succede quando la modalità end-to-end non è supportata

Quando esporti in uno di questi formati, Ultralytics passa Ultralytics alla configurazione "uno-a-molti" e registra un avviso: non è necessario alcun intervento manuale. Ciò significa che per questi formati dovrai includere NMS tua pipeline di inferenza, proprio come con YOLOv8 o YOLO11.

TensorRT INT8

TensorRT supporta l'end-to-end, ma è disattivato automaticamente quando si esporta con int8=True su TensorRT .3.0.

Compromessi tra precisione e velocità

Il rilevamento end-to-end offre notevoli vantaggi in termini di implementazione con un impatto minimo sulla precisione:

MetricaEnd-to-End (impostazione predefinita)Uno-a-molti + NMSend2end=False)
Velocità CPUFino al 43% più veloceBaseline
mAPcirca 0,5 mAPEguaglia o supera YOLO11
Post-elaborazioneSolo filtro di affidabilitàNMS completa
Complessità di implementazioneMinimaleRichiede NMS )

Per la maggior parte delle applicazioni pratiche, il valore di circa 0,5 mAP La differenza è trascurabile, soprattutto se si considerano i vantaggi in termini di velocità e semplicità. Se la massima precisione è la tua priorità assoluta, puoi sempre ricorrere alla testa "uno a molti" utilizzando end2end=False.

Consulta le metriche di prestazione di YOLO26 per un confronto dettagliato tra tutte le dimensioni del modello (n, s, m, l, x).

Migrazione da YOLOv8 YOLO11

Se stai aggiornando un progetto esistente a YOLO26, ecco una breve lista di controllo per garantire una transizione senza intoppi:

  • CLI Ultralytics / CLI Ultralytics : Non sono necessarie modifiche: basta aggiornare il nome del modello in yolo26n.pt (o yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Codice personalizzato di post-elaborazione: Aggiornamento per gestire i nuovi formati di output — (N, 300, 6) per il rilevamento, oltre a dati specifici per l'attività segmentazione, pose, e OBB. Si noti anche il cambiamento del formato del box da xywh a xyxy
  • Pipeline di Esportazione: Controlla la sezione di compatibilità del formato sopra per il tuo formato di destinazione.
  • TensorRT + INT8: Verifica che la tua versione di TensorRT sia >10.3.0 per il supporto end-to-end.
  • Esportazioni FP16: Se hai bisogno che tutti i risultati siano in FP16, esporta con end2end=False — vedi perché output0 rimane in FP32
  • iOS CoreML: È supportato l'intero processo. Se hai bisogno del supporto per l'anteprima di Xcode, usa end2end=False con nms=True
  • Dispositivi Edge (NCNN, RKNN): Questi formati eseguono un fallback automatico da uno-a-molti, quindi includi NMS nella tua pipeline on-device.

FAQ

Posso usare end2end=True e nms=True contemporaneamente?

No. Queste opzioni si escludono a vicenda. Se si imposta nms=True in un modello end-to-end durante export, verrà automaticamente forzato a nms=False con un avviso. Il dispositivo end-to-end gestisce già internamente il filtraggio dei duplicati, quindi non NMS necessario NMS esterno.

Tuttavia, end2end=False insieme a nms=True è una configurazione valida: integra NMS tradizionale NMS grafico di esportazione. Ciò può essere utile per CoreML esportazioni, poiché consente di utilizzare direttamente la funzione di anteprima in Xcode con il modello di rilevamento.

Cosa regola il parametro max_det nei modelli end-to-end?

Il max_det Il parametro (impostazione predefinita: 300) definisce il numero massimo di rilevamenti che il modello one-to-one può generare per ogni immagine. È possibile modificarlo in fase di inferenza o di esportazione:

model.predict("image.jpg", max_det=100)  # fewer detections, slightly faster
model.export(format="onnx", max_det=500)  # more detections for dense scenes

Si noti che i checkpoint predefiniti di YOLO26 sono stati addestrati con max_det=300. Sebbene sia possibile aumentare questo valore, la head uno-a-uno è stata ottimizzata durante l'addestramento per produrre fino a 300 rilevamenti puliti, pertanto i rilevamenti oltre tale limite potrebbero essere di qualità inferiore. Se necessiti di più di 300 rilevamenti per immagine, considera di riaddestrare con un valore più alto max_det valore.

ONNX mio ONNX esportato restituisce (1, 300, 6): è corretto?

Sì, questo è il formato di output end-to-end previsto per il rilevamento: dimensione del batch da 1 a un massimo di 300 rilevamenti, ciascuno con 6 valori [x1, y1, x2, y2, confidence, class_id]. Basta filtrare in base alla soglia di confidenza e il gioco è fatto — nessuna NMS necessaria.

Per altre operazioni, la struttura dei risultati varia:

TaskForma dell'uscitaDescrizione
Rilevamento(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
Segmentazione(1, 300, 38) + (1, 32, 160, 160)6 valori del box + 32 coefficienti della maschera, più un tensor prototipo della maschera
Posa(1, 300, 57)6 valori del box + 17 punti chiave × 3 (x, y, visibilità)
OBB(1, 300, 7)6 valori del box + 1 angolo di rotazione

Come faccio a verificare se il mio modello esportato è end-to-end?

È possibile verificarlo utilizzandoPython Ultralytics oppure esaminando direttamente i metadati ONNX esportato:

Verifica se un modello è end-to-end

from ultralytics import YOLO

model = YOLO("yolo26n.onnx")
model.predict(verbose=False)  # run predict to setup predictor first
print(model.predictor.model.end2end)  # True if end-to-end is enabled
import onnxruntime as ort

session = ort.InferenceSession("yolo26n.onnx")
metadata = session.get_modelmeta().custom_metadata_map
print(metadata.get("end2end"))  # 'True' if end-to-end is enabled

In alternativa, controlla la struttura dei dati in uscita: i modelli di rilevamento end-to-end generano (1, 300, 6), mentre i modelli tradizionali producono (1, nc + 4, 8400). Per altre tipologie di attività, consultare il Domande frequenti sulle forme di output.

È disponibile il supporto end-to-end per le attività di segmentazione, posa e OBB?

Sì. Tutte le varianti delle attività di YOLO26 — detection, segmentazione, stima della posa, e rilevamento di oggetti orientati (obb) — supportano di default l'inferenza end-to-end. Il end2end=False Il fallback è disponibile anche in tutte le attività.

Ogni attività integra i risultati di rilevamento di base con dati specifici dell'attività:

TaskModelloRisultato finale
Rilevamentoyolo26n.pt(N, 300, 6)
Segmentazioneyolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
Posayolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)


📅 Creato 12 giorni fa ✏️ Aggiornato 10 giorni fa
glenn-jocherraimbekovm

Commenti