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 (impostazione predefinita)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(), raggruppa i livelli Conv + BatchNorm per velocizzare l'inferenza e, nei modelli end-to-end, rimuove anche la testa "uno-a-molti", riducendo così le dimensioni del modello e i FLOP. Per ulteriori dettagli sull'architettura a doppia testa, consultare il Pagina del modello YOLO26.

Devo modificare il mio codice?

UtilizzoPython o CLI Ultralytics

Non sono necessarie modifiche. Se si utilizza Python standard Ultralytics o CLI, tutto funziona automaticamente: previsione, convalida ed esportazione gestiscono modelli end-to-end immediatamente.

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, quando si esegue l'inferenza con ONNX o TensorRT), dovrai aggiornarlo 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 (x centrale, y centrale, 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 inoltre il cambiamento nel formato della casella da xywh a xyxy
  • File di esportazione: consulta la sezione sulla compatibilità dei formati qui sopra per il formato di destinazione
  • TensorRT INT8: assicurati che TensorRT tua TensorRT sia superiore alla 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 passano automaticamente alla modalità uno-a-molti, quindi includi NMS tua pipeline sul dispositivo

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 impostato su 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, il modello one-to-one è stato ottimizzato durante l'addestramento per produrre fino a 300 rilevamenti accurati; pertanto, i rilevamenti oltre tale limite potrebbero risultare di qualità inferiore. Se avete bisogno di più di 300 rilevamenti per immagine, prendete in considerazione la possibilità di ripetere l'addestramento 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 affidabilità e il gioco è fatto: non NMS .

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 di box + 32 coefficienti di maschera, oltre a tensor di maschera prototipo
Posa(1, 300, 57)6 valori delle caselle + 17 punti chiave × 3 (x, y, visibilità)
OBB(1, 300, 7)6 valori di casella + 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 forme 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 0 giorni fa ✏️ Aggiornato 0 giorni fa
raimbekovm

Commenti