D-FINE
Un detection transformer che riformula la regressione dei box come una distribuzione di probabilità su ogni bordo del box, raffinata attraverso i layer del decoder. LibreYOLO lo supporta per il rilevamento e per la segmentazione di istanze.
- Task
- detection, instance segmentation
- Dimensioni
- n, s, m, l, x at 640 px
- Installa
pip install libreyolo- Livello di supporto
- Principale, dalla v1.1.0. Rilevatori addestrabili principali: le funzionalità seguono i modelli di punta nella stessa ondata di release.
- Licenze
- Codice Apache-2.0, pesi Apache-2.0. Uso commerciale
Installazione
D-FINE non richiede nessun extra opzionale. Tutto ciò che importa è già nell'installazione di base.
pip install libreyoloIl fine-tuning con adattatori tramite lora=True è l'eccezione, e richiede
l'extra lora.
pip install "libreyolo[lora]"Predizione
I pesi vengono scaricati da Hugging Face al primo utilizzo e restano nella cache locale.
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreDFINEn.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreDFINEn.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Il suffisso -seg nel nome del file seleziona la testa delle maschere,# quindi qui non serve l'argomento task.model = LibreYOLO("LibreDFINEn-seg.pt")result = model(SAMPLE_IMAGE, save=True) print(result.masks.data.shape)L'oggetto Results restituito è quello che restituisce ogni famiglia, quindi
passare a un rilevatore diverso è una modifica di una riga. Un nome di file con
-seg risolve da solo al task di segmentazione, e result.masks porta allora
le maschere di istanza insieme ai box. conf e max_det filtrano la selezione
delle query; iou è accettato per parità di API ma non ha effetto, perché il
decoder è un predittore di insiemi senza passaggio di NMS. Vedi
predizione per sorgenti, streaming e gestione dei risultati.
Varianti
Cinque dimensioni. Girano tutte alla stessa risoluzione di input, quindi la tabella le separa per numero di parametri e accuratezza.
| Checkpoint | Ingresso (px) | mAP 50-95 | Parametri (M) |
|---|---|---|---|
| LibreDFINEl | 640 | 60.0 | 31.24 |
| LibreDFINEm | 640 | 57.8 | 19.59 |
| LibreDFINEn | 640 | 45.8 | 3.78 |
| LibreDFINEs | 640 | 53.4 | 10.32 |
| LibreDFINEx | 640 | 61.4 | 62.62 |
COCO val2017, 500 images. Misurato con il sistema di benchmark di LibreYOLO e pubblicato su Vision Analysis, dove vengono confrontate le latenze tra hardware e runtime e sono disponibili i record completi delle esecuzioni.
La segmentazione riutilizza il backbone, l'encoder e il decoder del rilevamento
e aggiunge una testa per le maschere, quindi un checkpoint -seg accetta gli
stessi argomenti del suo equivalente di rilevamento. La famiglia RT-DETRv4 di
LibreYOLO è scritta come sottoclasse del wrapper di D-FINE: eredita questa linea
di decoder e poi riporta la sua lista di task al solo rilevamento, perché non
porta una testa delle maschere.
Addestramento
L'addestramento parte da un checkpoint pubblicato, per entrambi i task.
from libreyolo import LibreYOLO model = LibreYOLO("LibreDFINEn.pt")model.train(data="my-dataset.yaml", epochs=50, imgsz=640, batch=8, lr0=2e-4)libreyolo train model=LibreDFINEn.pt data=my-dataset.yaml \ epochs=50 imgsz=640 batch=8 lr0=2e-4# Continua dai pesi di segmentazione pubblicati, testa delle maschere inclusa.libreyolo train model=LibreDFINEn-seg.pt data=my-dataset.yaml \ task=segment epochs=50 imgsz=640# I pesi di rilevamento non portano una testa delle maschere, quindi# questo è un trasferimento esplicito: la testa parte non addestrata ed# è utile solo una volta addestrata. Chiedere task=segment qui è ciò# che autorizza il trasferimento.libreyolo train model=LibreDFINEn.pt data=my-dataset.yaml \ task=segment epochs=50 imgsz=640from libreyolo import LibreYOLO model = LibreYOLO("LibreDFINEn.pt")model.train(data="my-dataset.yaml", epochs=50, lora=True)libreyolo train model=LibreDFINEn.pt data=my-dataset.yaml \ epochs=50 device=0,1 batch=16Senza modifiche, il trainer esegue 132 epoche con lr0=2e-4, amp=True e amp_dtype="float16", un batch di 16 e early stopping dopo 50 epoche senza miglioramenti. libreyolo train parte dalla stessa ricetta per entrambi i task: AdamW con una schedule coseno piatta, weight_decay=1e-4, 2 epoche di warmup, un clip della norma del gradiente a 0.1, e nessuna augmentation con mosaic, MixUp, HSV o affine. Senza name=, le sue esecuzioni vanno in runs/train/dfine_exp. I pesi di rilevamento sono un punto di partenza valido per l'addestramento della segmentazione, ma solo con un trasferimento esplicito: la testa delle maschere parte senza addestramento e altrimenti restituirebbe maschere prive di significato. Passare task=segment alla CLI autorizza il trasferimento. Il percorso Python è più limitato: occorre costruire direttamente LibreDFINE con allow_detect_to_segment_transfer=True, perché la factory LibreYOLO() non accetta questo argomento; la costruzione diretta non scarica i pesi, quindi il file deve essere già sul disco.
lora=True si applica al rilevamento. L'addestramento di segmentazione lo
rifiuta e rimanda invece a freeze='backbone', perché la testa delle maschere
non è stata testata con gli adattatori. Su Apple silicon il trainer sposta
l'intera esecuzione su CPU: il backward pass del matmul a bin dell'Integral
incontra un errore di compilazione Metal. L'inferenza su MPS non ne risente.
Vedi addestramento per dataset, data augmentation, multi-GPU e logger.
Validazione
val() restituisce un dizionario indicizzato per nome della metrica, e stampa i
risultati per classe se verbose resta attivo.
from libreyolo import LibreYOLO model = LibreYOLO("LibreDFINEn.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])libreyolo val model=LibreDFINEn.pt data=my-dataset.yamlfrom libreyolo import LibreYOLO model = LibreYOLO("LibreDFINEn-seg.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95(M)"]) # maschereprint(metrics["metrics/mAP50-95(B)"]) # boxSu un checkpoint -seg la chiave metrics/mAP50-95 da sola contiene il
punteggio delle maschere, e la stessa esecuzione riporta anche i box sotto (B)
e le maschere sotto (M), così entrambi sono disponibili da una sola passata.
Esportazione
| Task | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: supportato | Detection to TorchScript: supportato | Detection to ExecuTorch: non supportato | Detection to TensorRT: supportato | Detection to OpenVINO: supportato | Detection to Paddle: supportato | Detection to MNN: supportato | Detection to RKNN: non supportato | Detection to ncnn: non supportato | Detection to TFLite: non supportato | Detection to CoreML: non supportato | Detection to Core AI: supportato |
| Instance segmentation | Instance segmentation to ONNX: supportato | Instance segmentation to TorchScript: supportato | Instance segmentation to ExecuTorch: non supportato | Instance segmentation to TensorRT: supportato | Instance segmentation to OpenVINO: supportato | Instance segmentation to Paddle: non supportato | Instance segmentation to MNN: non supportato | Instance segmentation to RKNN: non supportato | Instance segmentation to ncnn: non supportato | Instance segmentation to TFLite: non supportato | Instance segmentation to CoreML: non supportato | Instance segmentation to Core AI: non supportato |
Un artefatto esportato si ricarica con LibreYOLO() in base al suffisso del
file, quindi un file .onnx o .engine si comporta come un checkpoint e
restituisce lo stesso Results. I percorsi OpenVINO, Paddle, MNN e Core AI
esportano a canvas fisso invece che con forme dinamiche.
Esportazione elenca gli argomenti che ogni formato accetta e gli
extra che qualcuno di essi aggiunge.
from libreyolo import LibreYOLO model = LibreYOLO("LibreDFINEn.pt")model.export(format="onnx", imgsz=640)model.export(format="tensorrt", imgsz=640, half=True)libreyolo export model=LibreDFINEn.pt format=onnx imgsz=640libreyolo export model=LibreDFINEn.pt format=tensorrt imgsz=640 half=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE # La factory smista in base al suffisso del file, quindi un artefatto# esportato si carica come qualsiasi checkpoint e restituisce lo stesso# oggetto Results.model = LibreYOLO("LibreDFINEn.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Input e output ONNX
| Tensore | images float32 [batch, 3, height, width] |
|---|---|
| Colore | RGB |
| Scala | pixel / 255 |
| Normalizzazione | nessuna |
| Ridimensionamento | allungare a larghezza x altezza (senza riempimento, il rapporto d'aspetto non viene mantenuto), Pillow bilinear |
Come riprodurre il ridimensionamento bilineare di Pillow
LibreYOLO ridimensiona con il filtro BILINEAR di Pillow (Image.resize). Non è OpenCV INTER_LINEAR né INTER_AREA: in riduzione, Pillow allarga il filtro del fattore di riduzione, e i ridimensionamenti di OpenCV cambiano le rilevazioni e spostano i riquadri di diversi pixel. Per riprodurlo senza Pillow, ridimensiona un asse, arrotonda a 8 bit, poi ridimensiona l'altro asse e arrotonda di nuovo. Per ogni asse, siano s = in_size / out_size e f = max(s, 1). Il pixel di uscita i ha centro c = (i + 0.5) * s e legge i pixel sorgente j da int(c - f + 0.5) a int(c + f + 0.5) - 1, limitati all'immagine, ciascuno con peso max(0, 1 - |j + 0.5 - c| / f), diviso per la somma dei pesi. Pillow lavora in virgola fissa e sceglie l'ordine degli assi dalla forma dell'immagine, quindi i pesi in virgola mobile possono differire di un livello su pochi pixel. Questo non cambia i risultati nei nostri controlli.
Square input only. Export rejects a non-square imgsz, and height and width are 640 by default.
Batch size 1 only. The graph declares a dynamic batch axis, but batches of 2 or more fail in 1.7.0.
Divide by 255 after the resize. There is no mean or std normalization.
Detection, esportazione predefinita
| Output | Forma | Significato |
|---|---|---|
pred_logits | [batch, queries, nc] | One logit per query and class. Sigmoid is not applied. queries is 300 for every size. |
pred_boxes | [batch, queries, 4] | cx, cy, w, h of each query, normalized 0 to 1 of the input. The input is the whole image stretched, so these are also fractions of the original image. |
Post-elaborazione
- Apply sigmoid to pred_logits.
- Flatten the [queries, nc] scores and take the top 300 (max_det, 300 by default). For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
- Keep the pairs whose score is above the confidence threshold (0.25 by default).
- Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2. Multiply x by the original image width and y by the original image height.
- There is no NMS and the iou threshold is not used. D-FINE predicts a set of boxes, and export with nms=True raises NotImplementedError.
- LibreYOLO does not clip these boxes, so an edge can sit slightly outside the image.
Instance segmentation, esportazione predefinita
| Output | Forma | Significato |
|---|---|---|
pred_logits | [batch, queries, nc] | One logit per query and class. Sigmoid is not applied. queries is 300 for every size. |
pred_boxes | [batch, queries, 4] | cx, cy, w, h of each query, normalized 0 to 1 of the input. The input is the whole image stretched, so these are also fractions of the original image. |
pred_masks | [batch, queries, mask_h, mask_w] | One mask per query, sigmoid already applied. mask_h is height / 4 and mask_w is width / 4, 160 x 160 at 640 x 640. |
Post-elaborazione
- Apply sigmoid to pred_logits.
- Flatten the [queries, nc] scores and take the top 300 (max_det, 300 by default). For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
- Keep the pairs whose score is above the confidence threshold (0.25 by default).
- Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2. Multiply x by the original image width and y by the original image height.
- For each kept pair, take its query's mask. Resize it with bilinear interpolation and half-pixel centers (align_corners=False, no antialiasing) to height x width, then again to the original image size.
- A pixel belongs to the mask when its value is 0.5 or more.
- Clear every mask pixel outside the box. Pixel (x, y) stays only when x1 <= x < x2 and y1 <= y < y2, in original-image pixels.
- There is no NMS and the iou threshold is not used. D-FINE predicts a set of boxes, and export with nms=True raises NotImplementedError.
- LibreYOLO does not clip the boxes of a .pt predict, so an edge can sit slightly outside the image. Its ONNX backend clips them to the image.
Per verificare la tua implementazione, passa lo stesso file a LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") restituisce i risultati di riferimento. Verificato con LibreYOLO 1.7.0.
Checkpoint
Tutti i file di pesi pubblicati per questa famiglia.
| File | Ingresso (px) | Licenza dei pesi |
|---|---|---|
| Detection | ||
| LibreDFINEn.pt | 640 | apache-2.0 |
| LibreDFINEs.pt | 640 | apache-2.0 |
| LibreDFINEm.pt | 640 | apache-2.0 |
| LibreDFINEl.pt | 640 | apache-2.0 |
| LibreDFINEx.pt | 640 | apache-2.0 |
| Instance segmentation | ||
| LibreDFINEn-seg.pt | 640 | apache-2.0 |
| LibreDFINEs-seg.pt | 640 | apache-2.0 |
| LibreDFINEm-seg.pt | 640 | apache-2.0 |
| LibreDFINEl-seg.pt | 640 | apache-2.0 |
| LibreDFINEx-seg.pt | 640 | apache-2.0 |
Oggi tutti i file elencati sopra sono presenti nell<link>organizzazione LibreYOLO</link> e vengono scaricati al primo utilizzo.
Licenze
Controlla la licenza nel repository Hugging Face degli specifici pesi che scarichi. Ogni checkpoint nell<link>organizzazione LibreYOLO</link> ne include una e non è sempre la stessa per tutta la famiglia. Quel repository è la fonte autorevole; il riepilogo seguente descrive le condizioni applicabili al momento dellultima verifica di questa pagina.
Questa è una descrizione delle licenze coinvolte, non una consulenza legale. Se la risposta è importante a fini commerciali, leggi personalmente le licenze e chiedi una consulenza indipendente.
- Lavoro originale
- D-FINE, University of Science and Technology of China
- Licenza upstream
- Apache-2.0
- Sorgente upstream
- github.com/Peterande/D-FINE
- Codice LibreYOLO
- MIT
- Pesi
- Apache-2.0, ripubblicati su huggingface.co/LibreYOLO
- Interpretazione
- Apache-2.0 is a permissive license, so these weights can be used in commercial and closed-source products. It asks you to keep its license text and attribution notices with any copy of the weights you redistribute, and it grants a patent license. It places no obligation on your own application code, and weights you train yourself on your own data are yours. The segmentation weights carry a second Apache-2.0 upstream, ArgoHA/D-FINE-seg, under the same terms.
I pesi di segmentazione hanno un secondo upstream: il loro decoder delle maschere, il matching delle maschere e la loss delle maschere vengono da ArgoHA/D-FINE-seg, anch'esso Apache-2.0, il cui maintainer ha approvato il riutilizzo con attribuzione.
Citazione
@misc{peng2024dfine,
title={D-FINE: Redefine Regression Task in DETRs as Fine-grained Distribution Refinement},
author={Yansong Peng and Hebei Li and Peixi Wu and Yueyi Zhang and Xiaoyan Sun and Feng Wu},
year={2024},
eprint={2410.13842},
archivePrefix={arXiv},
primaryClass={cs.CV}
}Copiato dal blocco di citazione degli autori disponibile su github.com/Peterande/D-FINE#citation.