Passer au contenu

YOLOE : Voir n'importe quoi en temps réel

Introduction

Options d'invite YOLOE

YOLOE (Real-Time Seeing Anything) est une nouvelle avancée dans les modèles YOLO zéro-shot et incitables, conçus pour la détection et la segmentation à vocabulaire ouvert. Contrairement aux modèles YOLO précédents limités à des catégories fixes, YOLOE utilise des invites de texte, d'image ou de vocabulaire interne, permettant la détection en temps réel de toute classe d'objet. Construit sur YOLOv10 et inspiré par YOLO-World, YOLOE atteint des performances zéro-shot de pointe avec un impact minimal sur la vitesse et la précision.



Regarder : Comment utiliser YOLOE avec le package python Ultralytics : vocabulaire ouvert et voir tout en temps réel 🚀

Comparé aux modèles YOLO précédents, YOLOE améliore considérablement l'efficacité et la précision. Il surpasse YOLO-Worldv2 de +3,5 AP sur LVIS tout en utilisant seulement un tiers des ressources d'entraînement et en atteignant des vitesses d'inférence 1,4 fois plus rapides. Ajusté sur COCO, YOLOE-v8-large surpasse YOLOv8-L de 0,1 mAP, en utilisant près de 4 fois moins de temps d'entraînement. Cela démontre l'équilibre exceptionnel de YOLOE en termes de précision, d'efficacité et de polyvalence. Les sections ci-dessous explorent l'architecture de YOLOE, les comparaisons de benchmarks et l'intégration avec le framework Ultralytics.

Aperçu de l'architecture

Architecture YOLOE

YOLOE conserve la structure YOLO standard—un backbone convolutionnel (par exemple, CSP-Darknet) pour l'extraction de caractéristiques, un neck (par exemple, PAN-FPN) pour la fusion multi-échelle, et une tête de détection sans ancrage et découplée (comme dans YOLOv8/YOLO11) prédisant l'objectivité, les classes et les boîtes indépendamment. YOLOE introduit trois nouveaux modules permettant la détection à vocabulaire ouvert :

  • Alignement région-texte reparamétrable (RepRTA): Prend en charge la détection basée sur des invites textuelles en affinant les intégrations de texte (par exemple, à partir de CLIP) via un petit réseau auxiliaire. Lors de l'inférence, ce réseau est intégré au modèle principal, ce qui garantit une surcharge nulle. YOLOE détecte ainsi les objets arbitraires étiquetés par du texte (par exemple, un « feu de circulation » invisible) sans pénalité d'exécution.

  • Encodeur d’invite visuelle à activation sémantique (SAVPE) : Permet la détection à invite visuelle via une branche d’intégration légère. Étant donné une image de référence, SAVPE encode les caractéristiques sémantiques et d’activation, conditionnant le modèle pour détecter des objets visuellement similaires : une capacité de détection unique utile pour les logos ou des parties spécifiques.

  • Contraste de région-prompt paresseux (LRPC) : En mode sans prompt, YOLOE effectue une reconnaissance d’ensemble ouvert à l’aide d’intégrations internes entraînées sur de grands vocabulaires (plus de 1 200 catégories de LVIS et Objects365). Sans invites ni encodeurs externes, YOLOE identifie les objets via la recherche de similarité d’intégration, gérant efficacement de grands espaces d’étiquettes lors de l’inférence.

De plus, YOLOE intègre la segmentation d'instance en temps réel en étendant la tête de détection avec une branche de prédiction de masque (similaire à YOLACT ou YOLOv8-Seg), ce qui ajoute une surcharge minimale.

Surtout, les modules open-world de YOLOE n'introduisent aucun coût d'inférence lorsqu'ils sont utilisés comme un YOLO à ensemble fermé régulier. Après l'entraînement, les paramètres YOLOE peuvent être reparamétrés dans un head YOLO standard, préservant des FLOPs et une vitesse identiques (par exemple, correspondant exactement à YOLO11).

Modèles disponibles, tâches prises en charge et modes de fonctionnement

Cette section détaille les modèles disponibles avec leurs poids pré-entraînés spécifiques, les tâches qu'ils prennent en charge et leur compatibilité avec divers modes de fonctionnement tels que l'Inférence, la Validation, l'Entraînement et l'Exportation, indiqués par ✅ pour les modes pris en charge et ❌ pour les modes non pris en charge.

Modèles d'invite texte/visuelle

Type de modèle Poids pré-entraînés Tâches prises en charge Inférence Validation Entraînement Exporter
YOLOE-11S yoloe-11s-seg.pt Segmentation d'instance
YOLOE-11M yoloe-11m-seg.pt Segmentation d'instance
YOLOE-11L yoloe-11l-seg.pt Segmentation d'instance
YOLOE-v8S yoloe-v8s-seg.pt Segmentation d'instance
YOLOE-v8M yoloe-v8m-seg.pt Segmentation d'instance
YOLOE-v8L yoloe-v8l-seg.pt Segmentation d'instance

Modèles sans invite

Type de modèle Poids pré-entraînés Tâches prises en charge Inférence Validation Entraînement Exporter
YOLOE-11S-PF yoloe-11s-seg-pf.pt Segmentation d'instance
YOLOE-11M-PF yoloe-11m-seg-pf.pt Segmentation d'instance
YOLOE-11L-PF yoloe-11l-seg-pf.pt Segmentation d'instance
YOLOE-v8S-PF yoloe-v8s-seg-pf.pt Segmentation d'instance
YOLOE-v8M-PF yoloe-v8m-seg-pf.pt Segmentation d'instance
YOLOE-v8L-PF yoloe-v8l-seg-pf.pt Segmentation d'instance

Exemples d'utilisation

Les modèles YOLOE sont faciles à intégrer dans vos applications python. Ultralytics fournit une API python et des commandes CLI conviviales pour rationaliser le développement.

Utilisation de l'entraînement

Finetuning sur un jeu de données personnalisé

Vous pouvez affiner n'importe quel modèle YOLOE pré-entraîné sur votre ensemble de données YOLO personnalisé pour les tâches de détection et de segmentation d'instances.

Exemple

Segmentation d'instance

L'affinage d'un point de contrôle YOLOE pré-entraîné suit principalement la procédure d'entraînement YOLO standard. La principale différence est de passer explicitement YOLOEPESegTrainer comme trainer paramètre à model.train():

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPESegTrainer

model = YOLOE("yoloe-11s-seg.pt")

# Fine-tune on your segmentation dataset
results = model.train(
    data="coco128-seg.yaml",  # Segmentation dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPESegTrainer,  # <- Important: use segmentation trainer
)

Détection d'objets

Tous les modèles YOLOE pré-entraînés effectuent la segmentation d'instance par défaut. Pour utiliser ces points de contrôle pré-entraînés pour entraîner un modèle de détection, initialisez un modèle de détection à partir de zéro en utilisant la configuration YAML, puis chargez le point de contrôle de segmentation pré-entraîné de la même échelle. Notez que nous utilisons YOLOEPETrainer au lieu de YOLOEPESegTrainer puisque nous entraînons un modèle de détection :

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPETrainer

# Initialize a detection model from a config
model = YOLOE("yoloe-11s.yaml")

# Load weights from a pretrained segmentation checkpoint (same scale)
model.load("yoloe-11s-seg.pt")

# Fine-tune on your detection dataset
results = model.train(
    data="coco128.yaml",  # Detection dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPETrainer,  # <- Important: use detection trainer
)

Le probing linéaire affine uniquement la branche de classification tout en gelant le reste du modèle. Cette approche est utile lorsque vous travaillez avec des données limitées, car elle empêche le surapprentissage en exploitant les caractéristiques apprises précédemment tout en adaptant uniquement l'en-tête de classification.

Segmentation d'instance

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPESegTrainer

# Load a pretrained segmentation model
model = YOLOE("yoloe-11s-seg.pt")

# Identify the head layer index
head_index = len(model.model.model) - 1

# Freeze all backbone and neck layers (i.e. everything before the head)
freeze = [str(i) for i in range(0, head_index)]

# Freeze parts of the segmentation head, keeping only the classification branch trainable
for name, child in model.model.model[-1].named_children():
    if "cv3" not in name:
        freeze.append(f"{head_index}.{name}")

# Freeze detection branch components
freeze.extend(
    [
        f"{head_index}.cv3.0.0",
        f"{head_index}.cv3.0.1",
        f"{head_index}.cv3.1.0",
        f"{head_index}.cv3.1.1",
        f"{head_index}.cv3.2.0",
        f"{head_index}.cv3.2.1",
    ]
)

# Train only the classification branch
results = model.train(
    data="coco128-seg.yaml",  # Segmentation dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPESegTrainer,  # <- Important: use segmentation trainer
    freeze=freeze,
)

Détection d'objets

Pour la tâche de détection d'objets, le processus d'entraînement est presque le même que l'exemple de segmentation d'instance ci-dessus, mais nous utilisons YOLOEPETrainer au lieu de YOLOEPESegTrainer, et initialisons le modèle de détection d'objets en utilisant le YAML, puis chargeons les poids à partir du point de contrôle de segmentation d'instance pré-entraîné.

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEPETrainer

# Initialize a detection model from a config
model = YOLOE("yoloe-11s.yaml")

# Load weights from a pretrained segmentation checkpoint (same scale)
model.load("yoloe-11s-seg.pt")

# Identify the head layer index
head_index = len(model.model.model) - 1

# Freeze all backbone and neck layers (i.e. everything before the head)
freeze = [str(i) for i in range(0, head_index)]

# Freeze parts of the segmentation head, keeping only the classification branch trainable
for name, child in model.model.model[-1].named_children():
    if "cv3" not in name:
        freeze.append(f"{head_index}.{name}")

# Freeze detection branch components
freeze.extend(
    [
        f"{head_index}.cv3.0.0",
        f"{head_index}.cv3.0.1",
        f"{head_index}.cv3.1.0",
        f"{head_index}.cv3.1.1",
        f"{head_index}.cv3.2.0",
        f"{head_index}.cv3.2.1",
    ]
)

# Train only the classification branch
results = model.train(
    data="coco128.yaml",  # Detection dataset
    epochs=80,
    patience=10,
    trainer=YOLOEPETrainer,  # <- Important: use detection trainer
    freeze=freeze,
)

Utilisation de la prédiction

YOLOE prend en charge les invites textuelles et visuelles. L'utilisation des invites est simple : il suffit de les transmettre via le predict méthode comme indiqué ci-dessous :

Exemple

Les invites textuelles vous permettent de spécifier les classes que vous souhaitez détecter à travers des descriptions textuelles. Le code suivant montre comment vous pouvez utiliser YOLOE pour détecter des personnes et des bus dans une image :

from ultralytics import YOLOE

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Set text prompt to detect person and bus. You only need to do this once after you load the model.
names = ["person", "bus"]
model.set_classes(names, model.get_text_pe(names))

# Run detection on the given image
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()

Les invites visuelles vous permettent de guider le modèle en lui montrant des exemples visuels des classes cibles, plutôt qu'en les décrivant par du texte.

L'argument visual_prompts argument prend un dictionnaire avec deux clés: bboxes et cls. Chaque boîte englobante dans bboxes doit entourer étroitement un exemple de l'objet que vous voulez que le modèle détecte, et l'entrée correspondante dans cls spécifie l'étiquette de classe pour cette boîte. Ce jumelage indique au modèle : « Voici à quoi ressemble la classe X : trouvez-en d'autres comme elle. »

ID de classe (cls) dans visual_prompts sont utilisés pour associer chaque bounding box à une catégorie spécifique dans votre prompt. Ce ne sont pas des étiquettes fixes, mais des identifiants temporaires que vous attribuez à chaque exemple. La seule exigence est que les ID de classe doivent être séquentiels, en commençant par 0. Cela aide le modèle à associer correctement chaque boîte à sa classe respective.

Vous pouvez fournir des invites visuelles directement dans la même image sur laquelle vous souhaitez exécuter l’inférence. Par exemple :

import numpy as np

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")

# Define visual prompts using bounding boxes and their corresponding class IDs.
# Each box highlights an example of the object you want the model to detect.
visual_prompts = dict(
    bboxes=np.array(
        [
            [221.52, 405.8, 344.98, 857.54],  # Box enclosing person
            [120, 425, 160, 445],  # Box enclosing glasses
        ],
    ),
    cls=np.array(
        [
            0,  # ID to be assigned for person
            1,  # ID to be assigned for glassses
        ]
    ),
)

# Run inference on an image, using the provided visual prompts as guidance
results = model.predict(
    "ultralytics/assets/bus.jpg",
    visual_prompts=visual_prompts,
    predictor=YOLOEVPSegPredictor,
)

# Show results
results[0].show()

Vous pouvez également fournir des exemples à partir d'une image de référence distincte en utilisant le refer_image argument. Dans ce cas, le bboxes et cls dans visual_prompts doit décrire les objets dans l'image de référence, et non l'image cible sur laquelle vous effectuez des prédictions :

Remarque

Si source est une vidéo ou un flux, le modèle utilise automatiquement la première image comme refer_image. Cela signifie que votre visual_prompts sont appliqués à cette image initiale pour aider le modèle à comprendre ce qu'il doit rechercher dans le reste de la vidéo. Alternativement, vous pouvez explicitement passer n'importe quelle image spécifique comme le refer_image pour contrôler quels exemples visuels le modèle utilise comme référence.

import numpy as np

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")

# Define visual prompts based on a separate reference image
visual_prompts = dict(
    bboxes=np.array([[221.52, 405.8, 344.98, 857.54]]),  # Box enclosing person
    cls=np.array([0]),  # ID to be assigned for person
)

# Run prediction on a different image, using reference image to guide what to look for
results = model.predict(
    "ultralytics/assets/zidane.jpg",  # Target image for detection
    refer_image="ultralytics/assets/bus.jpg",  # Reference image used to get visual prompts
    visual_prompts=visual_prompts,
    predictor=YOLOEVPSegPredictor,
)

# Show results
results[0].show()

L'utilisation de refer_image définit également les classes de façon permanente, de sorte que vous pouvez exécuter des prédictions sans avoir à fournir à nouveau les mêmes invites visuelles, et exporter le modèle tout en conservant la capacité de détecter les mêmes classes après l’exportation :

# After making prediction with `refer_image`, you can run predictions without passing visual_prompts again and still get the same classes back
results = model("ultralytics/assets/bus.jpg")

# Or export it to a different format while retaining the classes
model.export(format="onnx")

Vous pouvez également transmettre plusieurs images cibles pour exécuter la prédiction :

import numpy as np

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOEVPSegPredictor

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")

# Define visual prompts using bounding boxes and their corresponding class IDs.
# Each box highlights an example of the object you want the model to detect.
visual_prompts = dict(
    bboxes=[
        np.array(
            [
                [221.52, 405.8, 344.98, 857.54],  # Box enclosing person
                [120, 425, 160, 445],  # Box enclosing glasses
            ],
        ),
        np.array([[150, 200, 1150, 700]]),
    ],
    cls=[
        np.array(
            [
                0,  # ID to be assigned for person
                1,  # ID to be assigned for glasses
            ]
        ),
        np.array([0]),
    ],
)

# Run inference on multiple image, using the provided visual prompts as guidance
results = model.predict(
    ["ultralytics/assets/bus.jpg", "ultralytics/assets/zidane.jpg"],
    visual_prompts=visual_prompts,
    predictor=YOLOEVPSegPredictor,
)

# Show results
results[0].show()

YOLOE inclut également des variantes sans invite qui sont livrées avec un vocabulaire intégré. Ces modèles ne nécessitent aucune invite et fonctionnent comme les modèles YOLO traditionnels. Au lieu de s'appuyer sur des étiquettes ou des exemples visuels fournis par l'utilisateur, ils détectent les objets à partir d'une liste prédéfinie de 4 585 classes basée sur l'ensemble de balises utilisé par le Recognize Anything Model Plus (RAM++).

from ultralytics import YOLOE

# Initialize a YOLOE model
model = YOLOE("yoloe-11l-seg-pf.pt")

# Run prediction. No prompts required.
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()

Utilisation de Val

La validation du modèle sur un ensemble de données est simplifiée comme suit :

Exemple

from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml")

Par défaut, il utilise l'ensemble de données fourni pour extraire les embeddings visuels pour chaque catégorie.

from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml", load_vp=True)

Alternativement, nous pourrions utiliser un autre jeu de données comme jeu de données de référence pour extraire les embeddings visuels pour chaque catégorie. Notez que ce jeu de données de référence doit avoir exactement les mêmes catégories que le jeu de données fourni.

from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg.pt")  # or select yoloe-11s/m-seg.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml", load_vp=True, refer_data="coco.yaml")
from ultralytics import YOLOE

# Create a YOLOE model
model = YOLOE("yoloe-11l-seg-pf.pt")  # or select yoloe-11s/m-seg-pf.pt for different sizes

# Conduct model validation on the COCO128-seg example dataset
metrics = model.val(data="coco128-seg.yaml", single_cls=True)

Utilisation de l'exportation

Le processus d'exportation est similaire à celui des autres modèles YOLO, avec la flexibilité supplémentaire de gérer les invites textuelles et visuelles :

Exemple

from ultralytics import YOLOE

# Select yoloe-11s/m-seg.pt for different sizes
model = YOLOE("yoloe-11l-seg.pt")

# Configure the set_classes() before exporting the model
names = ["person", "bus"]
model.set_classes(names, model.get_text_pe(names))

export_model = model.export(format="onnx")
model = YOLOE(export_model)

# Run detection on the given image
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()

Entraîner des modèles officiels

Préparer les jeux de données

Remarque

L'entraînement des modèles YOLOE officiels nécessite des annotations de segment pour les données d'entraînement, voici le script fourni par l'équipe officielle qui convertit les ensembles de données en annotations de segment, alimenté par Modèles SAM2.1. Ou vous pouvez télécharger directement le Processed Segment Annotations dans le tableau suivant fourni par l'équipe officielle.

  • Données d'entraînement
Ensemble de données Type Échantillons Boîtes Annotations de détection brutes Annotations de segments traitées
Objects365v1 Détection 609k 9621k objects365_train.json objects365_train_segm.json
GQA Ancrage sémantique 621k 3681k final_mixed_train_no_coco.json final_mixed_train_no_coco_segm.json
Flickr30k Ancrage sémantique 149k 641k final_flickr_separateGT_train.json final_flickr_separateGT_train_segm.json
  • Données Val
Ensemble de données Type Fichiers d'annotations
LVIS minival Détection minival.txt

Lancement de l'entraînement à partir de zéro

Remarque

Visual Prompt les modèles sont affinés sur la base de modèles bien entraînés Text Prompt modèles.

Exemple

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOESegTrainerFromScratch

data = dict(
    train=dict(
        yolo_data=["Objects365.yaml"],
        grounding_data=[
            dict(
                img_path="flickr/full_images/",
                json_file="flickr/annotations/final_flickr_separateGT_train_segm.json",
            ),
            dict(
                img_path="mixed_grounding/gqa/images",
                json_file="mixed_grounding/annotations/final_mixed_train_no_coco_segm.json",
            ),
        ],
    ),
    val=dict(yolo_data=["lvis.yaml"]),
)

model = YOLOE("yoloe-11l-seg.yaml")
model.train(
    data=data,
    batch=128,
    epochs=30,
    close_mosaic=2,
    optimizer="AdamW",
    lr0=2e-3,
    warmup_bias_lr=0.0,
    weight_decay=0.025,
    momentum=0.9,
    workers=4,
    trainer=YOLOESegTrainerFromScratch,
    device="0,1,2,3,4,5,6,7",
)

Puisque seulement le SAVPE le module doit être mis à jour pendant l'entraînement. Conversion d'un modèle Text-prompt bien entraîné en modèle de détection et adoption d'un pipeline de détection avec un coût d'entraînement moindre. Notez que cette étape est facultative, vous pouvez également commencer directement à partir de la segmentation.

from ultralytics import YOLOE
from ultralytics.utils.patches import torch_load

det_model = YOLOE("yoloe-11l.yaml")
state = torch_load("yoloe-11l-seg.pt")
det_model.load(state["model"])
det_model.save("yoloe-11l-seg-det.pt")

Démarrer l'entraînement :

from ultralytics import YOLOE
from ultralytics.models.yolo.yoloe import YOLOESegVPTrainer

data = dict(
    train=dict(
        yolo_data=["Objects365.yaml"],
        grounding_data=[
            dict(
                img_path="flickr/full_images/",
                json_file="flickr/annotations/final_flickr_separateGT_train_segm.json",
            ),
            dict(
                img_path="mixed_grounding/gqa/images",
                json_file="mixed_grounding/annotations/final_mixed_train_no_coco_segm.json",
            ),
        ],
    ),
    val=dict(yolo_data=["lvis.yaml"]),
)

model = YOLOE("yoloe-11l-seg.pt")
# replace to yoloe-11l-seg-det.pt if converted to detection model
# model = YOLOE("yoloe-11l-seg-det.pt")

# freeze every layer except of the savpe module.
head_index = len(model.model.model) - 1
freeze = list(range(0, head_index))
for name, child in model.model.model[-1].named_children():
    if "savpe" not in name:
        freeze.append(f"{head_index}.{name}")

model.train(
    data=data,
    batch=128,
    epochs=2,
    close_mosaic=2,
    optimizer="AdamW",
    lr0=16e-3,
    warmup_bias_lr=0.0,
    weight_decay=0.025,
    momentum=0.9,
    workers=4,
    trainer=YOLOESegVPTrainer,  # use YOLOEVPTrainer if converted to detection model
    device="0,1,2,3,4,5,6,7",
    freeze=freeze,
)

Revenir au modèle de segmentation après l'entraînement. Nécessaire uniquement si vous avez converti le modèle de segmentation en modèle de détection avant l'entraînement.

from copy import deepcopy

from ultralytics import YOLOE

model = YOLOE("yoloe-11l-seg.yaml")
model.load("yoloe-11l-seg.pt")

vp_model = YOLOE("yoloe-11l-vp.pt")
model.model.model[-1].savpe = deepcopy(vp_model.model.model[-1].savpe)
model.eval()
model.save("yoloe-11l-seg.pt")

Similaire à la formation d'invite visuelle, pour le modèle sans invite, seule l'intégration d'invite spécialisée doit être mise à jour pendant la formation. Conversion d'un modèle d'invite textuelle bien entraîné en modèle de détection et adoption d'un pipeline de détection avec un coût de formation moindre. Notez que cette étape est facultative, vous pouvez également commencer directement à partir de la segmentation.

from ultralytics import YOLOE
from ultralytics.utils.patches import torch_load

det_model = YOLOE("yoloe-11l.yaml")
state = torch_load("yoloe-11l-seg.pt")
det_model.load(state["model"])
det_model.save("yoloe-11l-seg-det.pt")
Démarrer l'entraînement :
from ultralytics import YOLOE

data = dict(
    train=dict(
        yolo_data=["Objects365.yaml"],
        grounding_data=[
            dict(
                img_path="flickr/full_images/",
                json_file="flickr/annotations/final_flickr_separateGT_train_segm.json",
            ),
            dict(
                img_path="mixed_grounding/gqa/images",
                json_file="mixed_grounding/annotations/final_mixed_train_no_coco_segm.json",
            ),
        ],
    ),
    val=dict(yolo_data=["lvis.yaml"]),
)

model = YOLOE("yoloe-11l-seg.pt")
# replace to yoloe-11l-seg-det.pt if converted to detection model
# model = YOLOE("yoloe-11l-seg-det.pt")

# freeze layers.
head_index = len(model.model.model) - 1
freeze = [str(f) for f in range(0, head_index)]
for name, child in model.model.model[-1].named_children():
    if "cv3" not in name:
        freeze.append(f"{head_index}.{name}")

freeze.extend(
    [
        f"{head_index}.cv3.0.0",
        f"{head_index}.cv3.0.1",
        f"{head_index}.cv3.1.0",
        f"{head_index}.cv3.1.1",
        f"{head_index}.cv3.2.0",
        f"{head_index}.cv3.2.1",
    ]
)

model.train(
    data=data,
    batch=128,
    epochs=1,
    close_mosaic=1,
    optimizer="AdamW",
    lr0=2e-3,
    warmup_bias_lr=0.0,
    weight_decay=0.025,
    momentum=0.9,
    workers=4,
    trainer=YOLOEPEFreeTrainer,
    device="0,1,2,3,4,5,6,7",
    freeze=freeze,
    single_cls=True,  # this is needed
)

Revenir au modèle de segmentation après l'entraînement. Nécessaire uniquement si vous avez converti le modèle de segmentation en modèle de détection avant l'entraînement.

from copy import deepcopy

from ultralytics import YOLOE

model = YOLOE("yoloe-11l-seg.pt")
model.eval()

pf_model = YOLOE("yoloe-11l-seg-pf.pt")
names = ["object"]
tpe = model.get_text_pe(names)
model.set_classes(names, tpe)
model.model.model[-1].fuse(model.model.pe)

model.model.model[-1].cv3[0][2] = deepcopy(pf_model.model.model[-1].cv3[0][2]).requires_grad_(True)
model.model.model[-1].cv3[1][2] = deepcopy(pf_model.model.model[-1].cv3[1][2]).requires_grad_(True)
model.model.model[-1].cv3[2][2] = deepcopy(pf_model.model.model[-1].cv3[2][2]).requires_grad_(True)
del model.model.pe
model.save("yoloe-11l-seg-pf.pt")

Comparaison des performances de YOLOE

YOLOE égale ou dépasse la précision des modèles YOLO à ensemble fermé sur des benchmarks standard comme COCO, sans compromettre la vitesse ou la taille du modèle. Le tableau ci-dessous compare YOLOE-L (basé sur YOLO11) aux modèles YOLOv8 et YOLO11 correspondants :

Modèle COCO mAP50-95 Vitesse d'inférence (T4) Paramètres GFLOPs (640px)
YOLOv8-L (ensemble fermé) 52.9% 9,06 ms (110 FPS) 43.7 M 165.2 B
YOLO11-L (ensemble fermé) 53.5% 6,2 ms (130 FPS) 26.2 M 86.9 B
YOLOE-L (vocabulaire ouvert) 52.6% 6,2 ms (130 FPS) 26.2 M 86.9 B

YOLO11-L et YOLOE-L ont des architectures identiques (modules d'invite désactivés dans YOLO11-L), ce qui entraîne une vitesse d'inférence identique et des estimations GFLOP similaires.

YOLOE-L atteint 52,6 % de mAP, surpassant YOLOv8-L (52,9 %) avec environ 40 % de paramètres en moins (26M contre 43,7M). Il traite des images de 640×640 en 6,2 ms (161 FPS) contre 9,06 ms (110 FPS) pour YOLOv8-L, soulignant ainsi l'efficacité de YOLO11. De manière cruciale, les modules de vocabulaire ouvert de YOLOE n'entraînent aucun coût d'inférence, démontrant une conception "sans déjeuner gratuit".

Pour les tâches zéro-shot et de transfert, YOLOE excelle : sur LVIS, YOLOE-small s'améliore par rapport à YOLO-Worldv2 de +3,5 AP en utilisant 3× moins de ressources d'entraînement. Le réglage fin de YOLOE-L de LVIS à COCO a également nécessité 4× moins de temps d'entraînement que YOLOv8-L, soulignant son efficacité et son adaptabilité. YOLOE conserve en outre la vitesse caractéristique de YOLO, atteignant plus de 300 FPS sur un GPU T4 et ~64 FPS sur iPhone 12 via CoreML, idéal pour les déploiements en périphérie et mobiles.

Remarque

Conditions de référence : Les résultats de YOLOE proviennent de modèles pré-entraînés sur Objects365, GoldG et LVIS, puis affinés ou évalués sur COCO. Le léger avantage mAP de YOLOE par rapport à YOLOv8 provient d’un pré-entraînement approfondi. Sans cette formation en vocabulaire ouvert, YOLOE correspond aux modèles YOLO de taille similaire, ce qui confirme sa précision SOTA et sa flexibilité dans le monde ouvert sans pénalité de performance.

Comparaison avec les modèles précédents

YOLOE introduit des avancées notables par rapport aux modèles YOLO précédents et aux détecteurs à vocabulaire ouvert :

  • YOLOE vs YOLOv5 :
    YOLOv5 offrait un bon équilibre vitesse-précision, mais nécessitait un réentraînement pour les nouvelles classes et utilisait des têtes basées sur l'ancrage. En revanche, YOLOE est sans ancrage et détecte dynamiquement les nouvelles classes. YOLOE, s'appuyant sur les améliorations de YOLOv8, atteint une précision plus élevée (52,6 % contre environ 50 % mAP de YOLOv5 sur COCO) et intègre la segmentation d'instance, contrairement à YOLOv5.

  • YOLOE vs YOLOv8 :
    YOLOE étend l'architecture repensée de YOLOv8, atteignant une précision similaire ou supérieure (52,6 % mAP avec environ 26 millions de paramètres contre 52,9 % avec environ 44 millions de paramètres pour YOLOv8-L). Il réduit considérablement le temps de formation grâce à un pré-apprentissage plus fort. L'avancée clé est la capacité de monde ouvert de YOLOE, détectant les objets invisibles (par exemple, « trottinette à oiseaux » ou « symbole de paix ») via des invites, contrairement à la conception d'ensemble fermé de YOLOv8.

  • YOLOE vs YOLO11 :
    YOLO11 améliore YOLOv8 avec une efficacité accrue et moins de paramètres (réduction d'environ 22 %). YOLOE hérite directement de ces gains, égalant la vitesse d'inférence et le nombre de paramètres de YOLO11 (environ 26 millions de paramètres), tout en ajoutant la détection et la segmentation de vocabulaire ouvert. Dans les scénarios d'ensembles fermés, YOLOE est équivalent à YOLO11, mais ajoute surtout une capacité d'adaptation pour détecter les classes invisibles, atteignant YOLO11 + capacité de monde ouvert sans compromettre la vitesse.

  • YOLOE vs les détecteurs de vocabulaire ouvert précédents :
    Les modèles de vocabulaire ouvert antérieurs (GLIP, OWL-ViT, YOLO-World) reposaient fortement sur les transformers vision-langage, ce qui entraînait une inférence lente. YOLOE les surpasse en précision zéro-shot (par exemple, +3,5 AP vs. YOLO-Worldv2) tout en fonctionnant 1,4 fois plus vite avec des ressources de formation considérablement inférieures. Par rapport aux approches basées sur les transformateurs (par exemple, GLIP), YOLOE offre une inférence plus rapide de plusieurs ordres de grandeur, comblant efficacement le fossé entre la précision et l'efficacité dans la détection d'ensembles ouverts.

En résumé, YOLOE conserve la vitesse et l'efficacité reconnues de YOLO, surpasse ses prédécesseurs en précision, intègre la segmentation et introduit une puissante détection open-world, ce qui le rend particulièrement polyvalent et pratique.

Cas d'utilisation et applications

La détection et la segmentation à vocabulaire ouvert de YOLOE permettent diverses applications au-delà des modèles traditionnels à classes fixes :

  • Détection d'objets en monde ouvert :
    Idéal pour les scénarios dynamiques tels que la robotique, où les robots reconnaissent des objets jamais vus auparavant à l'aide d'invites, ou les systèmes de sécurité s'adaptant rapidement aux nouvelles menaces (par exemple, les éléments dangereux) sans réentraînement.

  • Détection « Few-Shot » et « One-Shot » :
    À l’aide d’invites visuelles (SAVPE), YOLOE apprend rapidement de nouveaux objets à partir d’images de référence uniques, ce qui est parfait pour l’inspection industrielle (identification instantanée des pièces ou des défauts) ou la surveillance personnalisée, permettant des recherches visuelles avec une configuration minimale.

  • Reconnaissance de vocabulaire étendu et de longue traîne :
    Doté d'un vocabulaire de plus de 1 000 classes, YOLOE excelle dans des tâches telles que la surveillance de la biodiversité (détection d'espèces rares), les collections de musées, l'inventaire de vente au détail ou le commerce électronique, identifiant de manière fiable de nombreuses classes sans formation approfondie par classe.

  • Détection et segmentation interactives :
    YOLOE prend en charge les applications interactives en temps réel telles que la recherche de vidéos/images, la réalité augmentée (RA) et l'édition d'images intuitive, pilotées par des entrées naturelles (textes ou invites visuelles). Les utilisateurs peuvent isoler, identifier ou modifier dynamiquement des objets avec précision à l'aide de masques de segmentation.

  • Étiquetage et amorçage automatisés des données :
    YOLOE facilite la création rapide d’ensembles de données en fournissant des annotations initiales de boîtes englobantes et de segmentation, ce qui réduit considérablement les efforts d’étiquetage humain. Particulièrement utile dans l’analyse de grandes collections de médias, où il peut identifier automatiquement les objets présents, aidant ainsi à construire des modèles spécialisés plus rapidement.

  • Segmentation pour tout objet :
    Étend les capacités de segmentation à des objets arbitraires via des invites, ce qui est particulièrement utile pour l’imagerie médicale, la microscopie ou l’analyse d’imagerie satellite, en identifiant et en segmentant automatiquement et précisément les structures sans modèles pré-entraînés spécialisés. Contrairement aux modèles tels que SAM, YOLOE reconnaît et segmente simultanément les objets automatiquement, ce qui facilite les tâches telles que la création de contenu ou la compréhension de scènes.

Dans tous ces cas d'utilisation, l'avantage principal de YOLOE est sa polyvalence, fournissant un modèle unifié pour la détection, la reconnaissance et la segmentation dans des scénarios dynamiques. Son efficacité assure des performances en temps réel sur les appareils aux ressources limitées, idéal pour la robotique, la conduite autonome, la défense et au-delà.

Astuce

Choisissez le mode de YOLOE en fonction de vos besoins :

  • Mode à ensemble fermé : Pour les tâches à classes fixes (vitesse et précision maximales).
  • Mode incité : Ajoutez rapidement de nouveaux objets via des invites textuelles ou visuelles.
  • Mode open-set sans invite : Détection générale dans de nombreuses catégories (idéal pour le catalogage et la découverte).

Souvent, la combinaison de modes, tels que la découverte sans invite suivie d'invites ciblées, exploite tout le potentiel de YOLOE.

Entraînement et inférence

YOLOE s'intègre de manière transparente avec l'API Python Ultralytics et la CLI, de la même manière que les autres modèles YOLO (YOLOv8, YOLO-World). Voici comment démarrer rapidement :

Entraînement et inférence avec YOLOE

from ultralytics import YOLO

# Load pre-trained YOLOE model and train on custom data
model = YOLO("yoloe-11s-seg.pt")
model.train(data="path/to/data.yaml", epochs=50, imgsz=640)

# Run inference using text prompts ("person", "bus")
model.set_classes(["person", "bus"])
results = model.predict(source="test_images/street.jpg")
results[0].save()  # save annotated output

Ici, YOLOE se comporte comme un détecteur standard par défaut, mais passe facilement à la détection incitée en spécifiant des classes (set_classes). Les résultats contiennent des boîtes englobantes, des masques et des étiquettes.

# Training YOLOE on custom dataset
yolo train model=yoloe-11s-seg.pt data=path/to/data.yaml epochs=50 imgsz=640

# Inference with text prompts
yolo predict model=yoloe-11s-seg.pt source="test_images/street.jpg" classes="person,bus"

Invites de la CLI (classes) guide YOLOE de la même manière que set_classes. L'invite visuelle (requêtes basées sur des images) nécessite actuellement l'API Python.

Autres tâches prises en charge

  • Validation : Évaluez facilement la précision avec model.val() ou yolo val.
  • Exporter : Exporter les modèles YOLOE (model.export()) vers ONNX, TensorRT, etc., facilitant le déploiement.
  • Suivi : YOLOE prend en charge le suivi d'objets (yolo track) une fois intégré, utile pour suivre les classes demandées dans les vidéos.

Remarque

YOLOE inclut automatiquement masques de segmentation dans les résultats d'inférence (results[0].masks), simplifiant les tâches de précision au pixel près comme l'extraction ou la mesure d'objets sans avoir besoin de modèles distincts.

Démarrage

Configurez rapidement YOLOE avec Ultralytics en suivant ces étapes:

  1. Installation : Installer ou mettre à jour le package Ultralytics :

    pip install -U ultralytics
    
  2. Télécharger les poids YOLOE: Les modèles YOLOE pré-entraînés (par exemple, YOLOE-v8-S/L, les variantes YOLOE-11) sont disponibles dans les versions GitHub de YOLOE. Téléchargez simplement votre .pt fichier à charger dans la classe Ultralytics YOLO.

  3. Configuration matérielle requise :

    • Inférence : GPU recommandé (NVIDIA avec ≥4-8 Go de VRAM). Les petits modèles fonctionnent efficacement sur les GPU de périphérie (par exemple, Jetson) ou les CPU à des résolutions inférieures.
    • Entraînement : L'ajustement précis de YOLOE sur des données personnalisées ne nécessite généralement qu'un seul GPU. La pré-formation étendue en vocabulaire ouvert (LVIS/Objects365) utilisée par les auteurs a nécessité une puissance de calcul considérable (8× GPU RTX 4090).
  4. Configuration: Les configurations YOLOE utilisent les fichiers YAML Ultralytics standard. Les configurations par défaut (par exemple, yoloe-11s-seg.yaml) suffisent généralement, mais vous pouvez modifier le backbone, les classes ou la taille de l'image selon vos besoins.

  5. Exécution de YOLOE :

    • Inférence rapide (sans invite) :
      yolo predict model=yoloe-11s-seg-pf.pt source="image.jpg"
      
    • Détection incitée (exemple d'invite textuelle) :

      from ultralytics import YOLO
      
      model = YOLO("yoloe-11s-seg.pt")
      names = ["bowl", "apple"]
      model.set_classes(names, model.get_text_pe(names))
      results = model.predict("kitchen.jpg")
      results[0].save()
      
  6. Conseils d'intégration :

    • Noms des classes: Les sorties YOLOE par défaut utilisent les catégories LVIS ; utilisez set_classes() pour spécifier vos propres étiquettes.
    • Vitesse : YOLOE n’a pas de surcharge, sauf si vous utilisez des invites. Les invites de texte ont un impact minimal ; les invites visuelles un peu plus.
    • Inférence par lots: Pris en charge directement (model.predict([img1, img2])). Pour les invites spécifiques à l'image, exécutez les images individuellement.

La documentation Ultralytics fournit des ressources supplémentaires. YOLOE vous permet d'explorer facilement de puissantes capacités open-world au sein de l'écosystème YOLO familier.

Astuce

Conseil de pro : Pour maximiser la précision zéro-shot de YOLOE, affinez à partir des points de contrôle fournis plutôt que d'entraîner à partir de zéro. Utilisez des mots-clés s'alignant sur les étiquettes d'entraînement courantes (voir les catégories LVIS) pour améliorer la précision de la détection.

Citations et remerciements

Si YOLOE a contribué à votre recherche ou projet, veuillez citer l'article original de Ao Wang, Lihao Liu, Hui Chen, Zijia Lin, Jungong Han, et Guiguang Ding de l'Université de Tsinghua :

@misc{wang2025yoloerealtimeseeing,
      title={YOLOE: Real-Time Seeing Anything},
      author={Ao Wang and Lihao Liu and Hui Chen and Zijia Lin and Jungong Han and Guiguang Ding},
      year={2025},
      eprint={2503.07465},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2503.07465},
}

Pour approfondir le sujet, l'article original de YOLOE est disponible sur arXiv. Le code source du projet et des ressources supplémentaires sont accessibles via leur dépôt GitHub.

FAQ

En quoi YOLOE diffère-t-il de YOLO-World ?

Bien que YOLOE et YOLO-World permettent la détection de vocabulaire ouvert, YOLOE offre plusieurs avantages. YOLOE atteint une précision supérieure de +3,5 AP sur LVIS tout en utilisant 3 fois moins de ressources d'entraînement et en fonctionnant 1,4 fois plus rapidement que YOLO-Worldv2. YOLOE prend également en charge trois modes d'invite (texte, visuel et vocabulaire interne), tandis que YOLO-World se concentre principalement sur les invites textuelles. De plus, YOLOE inclut des capacités de segmentation d'instance intégrées, fournissant des masques précis au pixel près pour les objets détectés sans surcharge supplémentaire.

Puis-je utiliser YOLOE comme un modèle YOLO standard ?

Oui, YOLOE peut fonctionner exactement comme un modèle YOLO standard sans perte de performance. Lorsqu'il est utilisé en mode ensemble fermé (sans invites), les modules de vocabulaire ouvert de YOLOE sont reparamétrés dans l'en-tête de détection standard, ce qui donne une vitesse et une précision identiques aux modèles YOLO11 équivalents. Cela rend YOLOE extrêmement polyvalent—vous pouvez l'utiliser comme un détecteur traditionnel pour une vitesse maximale, puis passer en mode vocabulaire ouvert uniquement lorsque cela est nécessaire.

Quels types de prompts puis-je utiliser avec YOLOE ?

YOLOE prend en charge trois types d'invites :

  1. Invites textuelles : Spécifiez les classes d’objets en utilisant le langage naturel (p. ex., « personne », « feu de circulation », « scooter d’oiseau »)
  2. Invites visuelles : Fournissez des images de référence des objets que vous souhaitez détecter
  3. Vocabulaire interne : Utilisez le vocabulaire intégré de YOLOE de plus de 1 200 catégories sans invites externes

Cette flexibilité vous permet d'adapter YOLOE à divers scénarios sans réentraîner le modèle, ce qui le rend particulièrement utile pour les environnements dynamiques où les exigences de détection changent fréquemment.

Comment YOLOE gère-t-il la segmentation d'instances ?

YOLOE intègre la segmentation d'instance directement dans son architecture en étendant la tête de détection avec une branche de prédiction de masque. Cette approche est similaire à YOLOv8-Seg, mais fonctionne pour toute classe d'objet demandée. Les masques de segmentation sont automatiquement inclus dans les résultats d'inférence et sont accessibles via results[0].masks. Cette approche unifiée élimine le besoin de modèles de détection et de segmentation distincts, rationalisant ainsi les flux de travail pour les applications nécessitant des limites d'objets précises au pixel près.

Comment YOLOE gère-t-il l'inférence avec des invites personnalisées ?

Semblable à YOLO-World, YOLOE prend en charge une stratégie "prompt-then-detect" (invite puis détection) qui utilise un vocabulaire hors ligne pour améliorer l'efficacité. Les invites personnalisées telles que les légendes ou les catégories d'objets spécifiques sont pré-encodées et stockées sous forme d'intégrations de vocabulaire hors ligne. Cette approche rationalise le processus de détection sans nécessiter de réentraînement. Vous pouvez définir dynamiquement ces invites dans le modèle pour l'adapter à des tâches de détection spécifiques :

from ultralytics import YOLO

# Initialize a YOLOE model
model = YOLO("yoloe-11s-seg.pt")

# Define custom classes
names = ["person", "bus"]
model.set_classes(names, model.get_text_pe(names))

# Execute prediction on an image
results = model.predict("path/to/image.jpg")

# Show results
results[0].show()


📅 Créé il y a 5 mois ✏️ Mis à jour il y a 11 jours

Commentaires