İçeriğe geç

YOLOE: Gerçek Zamanlı Her Şeyi Görme

Giriş

YOLOE İstek Seçenekleri

YOLOE (Gerçek Zamanlı Her Şeyi Görme), açık kelime dağarcığı algılama ve segmentasyon için tasarlanmış, sıfır atışlı, istemlenebilir YOLO modellerinde yeni bir gelişmedir. Sabit kategorilerle sınırlı önceki YOLO modellerinin aksine, YOLOE metin, görüntü veya dahili kelime dağarcığı istemleri kullanır ve herhangi bir nesne sınıfının gerçek zamanlı olarak algılanmasını sağlar. YOLOv10 üzerine inşa edilen ve YOLO-World'den ilham alan YOLOE, hız ve doğruluk üzerinde minimum etkiyle en son teknoloji sıfır atış performansı elde eder.



İzle: Ultralytics Python paketi ile YOLOE nasıl kullanılır: Açık Kelime Haznesi ve Gerçek Zamanlı Her Şeyi Görme 🚀

Önceki YOLO modelleriyle karşılaştırıldığında, YOLOE verimliliği ve doğruluğu önemli ölçüde artırır. Eğitim kaynaklarının sadece üçte birini kullanırken ve 1,4 kat daha hızlı çıkarım hızlarına ulaşırken, LVIS üzerinde YOLO-Worldv2'ye göre +3,5 AP iyileşme sağlar. COCO üzerinde ince ayar yapıldığında, YOLOE-v8-large, YOLOv8-L'yi 0,1 mAP ile geçer ve neredeyse 4 kat daha az eğitim süresi kullanır. Bu, YOLOE'nin olağanüstü doğruluk, verimlilik ve çok yönlülük dengesini gösterir. Aşağıdaki bölümler, YOLOE'nin mimarisini, kıyaslama karşılaştırmalarını ve Ultralytics çerçevesiyle entegrasyonunu incelemektedir.

Mimariye Genel Bakış

YOLOE Mimarisi

YOLOE, standart YOLO yapısını korur: özellik çıkarımı için evrişimsel bir backbone (örneğin, CSP-Darknet), çok ölçekli füzyon için bir neck (örneğin, PAN-FPN) ve nesnelliği, sınıfları ve kutuları bağımsız olarak tahmin eden bir anchor-free, decoupled algılama head (YOLOv8/YOLO11'de olduğu gibi). YOLOE, açık sözlüklü algılamayı sağlayan üç yeni modül sunar:

  • Yeniden Parametreleştirilebilir Bölge-Metin Hizalama (RepRTA): Küçük bir yardımcı ağ aracılığıyla metin gömme işlemlerini (örneğin, CLIP'ten) iyileştirerek metin istemli algılamayı destekler. Çıkarım sırasında, bu ağ ana modele katlanır ve sıfır ek yük sağlar. Bu nedenle YOLOE, çalışma zamanı cezaları olmadan rastgele metin etiketli nesneleri (örneğin, daha önce görülmemiş "trafik ışığı") algılar.

  • Semantik Etkinleştirilmiş Görsel İstem Kodlayıcı (SAVPE): Hafif bir gömme dalı aracılığıyla görsel istemli algılamayı sağlar. Bir referans görüntü verildiğinde, SAVPE semantik ve aktivasyon özelliklerini kodlar ve modeli görsel olarak benzer nesneleri algılayacak şekilde koşullandırır—logolar veya belirli parçalar için kullanışlı olan tek çekimlik bir algılama yeteneği.

  • Tembel Bölge-İstem Kontrastı (LRPC): İstemsiz modda, YOLOE, geniş kelime dağarcıkları (LVIS ve Objects365'ten 1200'den fazla kategori) üzerinde eğitilmiş dahili gömmelemeleri kullanarak açık küme tanıma gerçekleştirir. Harici istemler veya kodlayıcılar olmadan, YOLOE, gömme benzerliği araması yoluyla nesneleri tanımlar ve çıkarımda geniş etiket alanlarını verimli bir şekilde işler.

Ek olarak, YOLOE, algılama başlığını bir maske tahmin dalıyla (YOLACT veya YOLOv8-Seg'e benzer) genişleterek gerçek zamanlı örnek segmentasyonunu entegre eder ve minimum ek yük ekler.

Önemli olarak, YOLOE'nin açık dünya modülleri, normal kapalı küme YOLO olarak kullanıldığında çıkarım maliyeti getirmez. Eğitim sonrası, YOLOE parametreleri standart bir YOLO başlığına yeniden parametrelendirilebilir, böylece aynı FLOP'lar ve hız korunur (örneğin, tam olarak YOLO11 ile eşleşir).

Mevcut Modeller, Desteklenen Görevler ve Çalışma Modları

Bu bölüm, belirli önceden eğitilmiş ağırlıklarıyla birlikte mevcut modelleri, destekledikleri görevleri ve Çıkarım, Doğrulama, Eğitim ve Dışa Aktarma gibi çeşitli çalışma modlarıyla uyumluluklarını ayrıntılı olarak açıklar; ✅ desteklenen modları ve ❌ desteklenmeyen modları gösterir.

Metin/Görsel İstem modelleri

Model Türü Önceden Eğitilmiş Ağırlıklar Desteklenen Görevler Çıkarım Doğrulama Eğitim Dışa aktar
YOLOE-11S yoloe-11s-seg.pt Örnek Segmentasyonu
YOLOE-11M yoloe-11m-seg.pt Örnek Segmentasyonu
YOLOE-11L yoloe-11l-seg.pt Örnek Segmentasyonu
YOLOE-v8S yoloe-v8s-seg.pt Örnek Segmentasyonu
YOLOE-v8M yoloe-v8m-seg.pt Örnek Segmentasyonu
YOLOE-v8L yoloe-v8l-seg.pt Örnek Segmentasyonu

İstem Ücretsiz modeller

Model Türü Önceden Eğitilmiş Ağırlıklar Desteklenen Görevler Çıkarım Doğrulama Eğitim Dışa aktar
YOLOE-11S-PF yoloe-11s-seg-pf.pt Örnek Segmentasyonu
YOLOE-11M-PF yoloe-11m-seg-pf.pt Örnek Segmentasyonu
YOLOE-11L-PF yoloe-11l-seg-pf.pt Örnek Segmentasyonu
YOLOE-v8S-PF yoloe-v8s-seg-pf.pt Örnek Segmentasyonu
YOLOE-v8M-PF yoloe-v8m-seg-pf.pt Örnek Segmentasyonu
YOLOE-v8L-PF yoloe-v8l-seg-pf.pt Örnek Segmentasyonu

Kullanım Örnekleri

YOLOE modellerinin python uygulamalarınıza entegre edilmesi kolaydır. Ultralytics, geliştirmeyi kolaylaştırmak için kullanıcı dostu Python API ve CLI komutları sağlar.

Eğitim Kullanımı

Özel veri kümesinde İnce Ayar

Özel YOLO veri kümeniz üzerinde hem algılama hem de örnek segmentasyon görevleri için herhangi bir önceden eğitilmiş YOLOE modelini ince ayar yapabilirsiniz.

Örnek

Örnek segmentasyonu

Bir YOLOE önceden eğitilmiş kontrol noktasında ince ayar yapmak çoğunlukla standart YOLO eğitim prosedürünüizler. Temel fark, açıkça YOLOEPESegTrainer olarak trainer parametresini 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
)

Nesne algılama

Tüm önceden eğitilmiş YOLOE modelleri varsayılan olarak örnek segmentasyonu gerçekleştirir. Bu önceden eğitilmiş kontrol noktalarını bir algılama modeli eğitmek için kullanmak için, YAML yapılandırmasını kullanarak sıfırdan bir algılama modeli başlatın, ardından aynı ölçekteki önceden eğitilmiş segmentasyon kontrol noktasını yükleyin. Bir algılama modeli eğittiğimiz için YOLOEPETrainer yerine YOLOEPESegTrainer kullandığımıza dikkat edin:

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
)

Doğrusal araştırma, modelin geri kalanını dondururken yalnızca sınıflandırma dalına ince ayar yapar. Bu yaklaşım, yalnızca sınıflandırma başlığını uyarlarken önceden öğrenilmiş özellikleri kullanarak aşırı öğrenmeyi önlediği için sınırlı verilerle çalışırken kullanışlıdır.

Örnek segmentasyonu

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,
)

Nesne algılama

Nesne algılama görevi için, eğitim süreci yukarıdaki örnek bölümleme örneğiyle neredeyse aynıdır, ancak şunu kullanırız: YOLOEPETrainer yerine YOLOEPESegTrainer, ve YAML'yi kullanarak nesne algılama modelini başlatır ve ardından ağırlıkları önceden eğitilmiş örnek bölümleme kontrol noktasından yükleriz.

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,
)

Tahmin Kullanımı

YOLOE, hem metin tabanlı hem de görsel istemleri destekler. İstekleri kullanmak basittir; sadece bunları aracılığıyla iletin predict metodu aşağıda gösterildiği gibi:

Örnek

Metin istemleri, metinsel açıklamalar yoluyla algılamak istediğiniz sınıfları belirtmenize olanak tanır. Aşağıdaki kod, bir görüntüdeki insanları ve otobüsleri algılamak için YOLOE'yi nasıl kullanabileceğinizi gösterir:

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()

Görsel istekler, hedef sınıfları metinle tanımlamak yerine, görsel örneklerini göstererek modele rehberlik etmenizi sağlar.

visual_prompts argüman iki anahtarlı bir sözlük alır: bboxes ve cls. İçindeki her sınırlayıcı kutu bboxes modelin algılamasını istediğiniz nesnenin bir örneğini sıkıca çevrelemeli ve içindeki karşılık gelen girdi cls bu kutu için sınıf etiketini belirtir. Bu eşleşme, modele "Bu, X sınıfının nasıl göründüğüdür; şimdi bundan daha fazlasını bul." der.

Sınıf Kimlikleri (cls) içinde visual_prompts her sınırlayıcı kutuyu isteminizdeki belirli bir kategoriyle ilişkilendirmek için kullanılır. Bunlar sabit etiketler değil, her örneğe atadığınız geçici tanımlayıcılardır. Tek şart, sınıf kimliklerinin 0'dan başlayarak sıralı olmasıdır. Bu, modelin her kutuyu ilgili sınıfıyla doğru şekilde ilişkilendirmesine yardımcı olur.

Çıkarım yapmak istediğiniz aynı görüntü içinde doğrudan görsel istemler sağlayabilirsiniz. Örneğin:

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()

Veya şunu kullanarak ayrı bir referans görüntüsünden örnekler sağlayabilirsiniz: refer_image argümanı alır. Bu durumda, bboxes ve cls içinde visual_prompts tahminlerde bulunduğunuz hedef görüntüdeki nesneleri değil, referans görüntüsündeki nesneleri tanımlamalıdır:

Not

Eğer source bir video veya yayın ise, model otomatik olarak ilk kareyi refer_image. Bu, sizin visual_prompts modelin videonun geri kalanında ne arayacağını anlamasına yardımcı olmak için bu ilk kareye uygulanır. Alternatif olarak, herhangi bir belirli kareyi açıkça şu şekilde geçirebilirsiniz: refer_image modelin hangi görsel örnekleri referans olarak kullandığını kontrol etmek için.

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()

Kullanarak refer_image ayrıca sınıfları kalıcı olarak ayarlar, böylece aynı görsel istemleri tekrar tekrar sağlamak zorunda kalmadan tahminler yürütebilir ve dışa aktarıldıktan sonra aynı sınıfları algılama yeteneğini koruyarak modeli dışa aktarabilirsiniz:

# 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")

Tahmini çalıştırmak için birden çok hedef resim de geçirebilirsiniz:

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 ayrıca yerleşik bir sözlükle gelen istem içermeyen varyantları da içerir. Bu modeller herhangi bir istem gerektirmez ve geleneksel YOLO modelleri gibi çalışır. Kullanıcı tarafından sağlanan etiketlere veya görsel örneklere güvenmek yerine, Recognize Anything Model Plus (RAM++) tarafından kullanılan etiket kümesine dayalı olarak 4.585 sınıflık önceden tanımlanmış bir listeden nesneleri algılarlar.

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()

Değerlendirme Kullanımı

Bir veri kümesi üzerinde model doğrulaması aşağıdaki gibi kolaylaştırılmıştır:

Örnek

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")

Varsayılan olarak, her kategori için görsel gömüleri çıkarmak üzere sağlanan veri kümesini kullanır.

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)

Alternatif olarak, her kategori için görsel gömmeleri çıkarmak üzere başka bir veri kümesini referans veri kümesi olarak kullanabiliriz. Bu referans veri kümesinin sağlanan veri kümesiyle tamamen aynı kategorilere sahip olması gerektiğini unutmayın.

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)

Dışa Aktarım Kullanımı

Dışa aktarım süreci, metin ve görsel istemleri işleme esnekliği eklenmiş diğer YOLO modellerine benzer:

Örnek

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()

Resmi Modelleri Eğitin

Veri kümelerini hazırlayın

Not

Resmi YOLOE modellerini eğitmek için eğitim verileri için segment ek açıklamaları gerekir, işte burada resmi ekip tarafından sağlanan komut dosyası veri kümelerini segment ek açıklamalarına dönüştüren, gücü SAM2.1 modelleri. Veya sağlananları doğrudan indirebilirsiniz Processed Segment Annotations resmi ekip tarafından sağlanan aşağıdaki tabloda.

  • Eğitim verisi
Veri Kümesi Tür Numuneler Kutular Ham Algılama Açıklamaları İşlenmiş Segment Açıklamaları
Objects365v1 Algılama 609k 9621k objects365_train.json objects365_train_segm.json
GQA Grounding 621k 3681k final_mixed_train_no_coco.json final_mixed_train_no_coco_segm.json
Flickr30k Grounding 149k 641k final_flickr_separateGT_train.json final_flickr_separateGT_train_segm.json
  • Val verisi
Veri Kümesi Tür Açıklama Dosyaları
LVIS minival Algılama minival.txt

Sıfırdan eğitim başlatma

Not

Visual Prompt modelleri, iyi eğitilmiş modellere göre ince ayar yapılır Text Prompt modelleri.

Örnek

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",
)

Sadece SAVPE modülün eğitim sırasında güncellenmesi gerekiyor. İyi eğitilmiş Metin istemi modelini algılama modeline dönüştürme ve daha az eğitim maliyetiyle algılama hattını benimseme. Bu adımın isteğe bağlı olduğunu, doğrudan segmentasyondan da başlayabileceğinizi unutmayın.

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")

Eğitime başla:

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,
)

Eğitimden sonra segmentasyon modeline geri dönüştürün. Yalnızca eğitimden önce segmentasyon modelini algılama modeline dönüştürdüyseniz gereklidir.

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")

Görsel istem eğitimine benzer şekilde, istem içermeyen model için eğitim sırasında yalnızca özel istem gömülmesinin güncellenmesi gerekir. İyi eğitilmiş Metin istemi modelini algılama modeline dönüştürme ve daha az eğitim maliyetiyle algılama hattını benimseme. Bu adımın isteğe bağlı olduğunu, doğrudan segmentasyondan da başlayabileceğinizi unutmayın.

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")
Eğitime başla:
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
)

Eğitimden sonra segmentasyon modeline geri dönüştürün. Yalnızca eğitimden önce segmentasyon modelini algılama modeline dönüştürdüyseniz gereklidir.

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")

YOLOE Performans Karşılaştırması

YOLOE, hızdan veya model boyutundan ödün vermeden COCO gibi standart kıyaslamalarda kapalı küme YOLO modellerinin doğruluğuyla eşleşir veya onu aşar. Aşağıdaki tablo, YOLOE-L'yi (YOLO11 üzerine inşa edilmiştir) karşılık gelen YOLOv8 ve YOLO11 modelleriyle karşılaştırır:

Model COCO mAP50-95 Çıkarım Hızı (T4) Parametreler GFLOP'lar (640 piksel)
YOLOv8-L (kapalı küme) 52.9% 9.06 ms (110 FPS) 43.7 M 165.2 B
YOLO11-L (kapalı küme) 53.5% 6.2 ms (130 FPS) 26.2 M 86.9 B
YOLOE-L (açık kelime dağarcığı) 52.6% 6.2 ms (130 FPS) 26.2 M 86.9 B

YOLO11-L ve YOLOE-L aynı mimarilere sahiptir (YOLO11-L'de istem modülleri devre dışıdır), bu da aynı çıkarım hızına ve benzer GFLOPs tahminlerine yol açar.

YOLOE-L, yaklaşık %40 daha az parametre (26M - 43.7M) ile YOLOv8-L'yi (%52.9) aşarak %52.6 mAP'ye ulaşır. YOLO11'in verimliliğini vurgulayarak, 640×640 görüntüleri YOLOv8-L'nin 9.06 ms (110 FPS)'sine kıyasla 6.2 ms'de (161 FPS) işler. Kritik olarak, YOLOE'nin açık kelime dağarcığı modülleri çıkarım maliyeti oluşturmaz ve bu da "bedava öğle yemeği yok değiş tokuşu" tasarımını gösterir.

Sıfır atış ve transfer görevleri için YOLOE öne çıkıyor: LVIS'te YOLOE-small, 3 kat daha az eğitim kaynağı kullanarak YOLO-Worldv2'ye göre +3,5 AP iyileştirme sağlıyor. YOLOE-L'yi LVIS'ten COCO'ya ince ayar yapmak da YOLOv8-L'den 4 kat daha az eğitim süresi gerektirdi, bu da verimliliğini ve uyarlanabilirliğini vurguluyor. YOLOE ayrıca YOLO'nun ayırt edici hızı olan bir T4 GPU'da 300+ FPS ve CoreML aracılığıyla iPhone 12'de ~64 FPS elde ederek uç ve mobil dağıtımlar için idealdir.

Not

Benchmark koşulları: YOLOE sonuçları, Objects365, GoldG ve LVIS üzerinde önceden eğitilmiş, ardından COCO üzerinde ince ayar yapılmış veya değerlendirilmiş modellerden elde edilmiştir. YOLOE'nin YOLOv8'e göre hafif mAP avantajı, kapsamlı ön eğitimden kaynaklanmaktadır. Bu açık kelime dağarcığı eğitimi olmadan, YOLOE benzer büyüklükteki YOLO modelleriyle eşleşir ve performans cezaları olmadan SOTA doğruluğunu ve açık dünya esnekliğini doğrular.

Önceki Modellerle Karşılaştırma

YOLOE, önceki YOLO modellerine ve açık sözlüklü dedektörlere göre önemli gelişmeler sunar:

  • YOLOE vs YOLOv5: YOLOv5 iyi bir hız-doğruluk dengesi sunmuş ancak yeni sınıflar için yeniden eğitim gerektirmiş ve çapa tabanlı başlıklar kullanmıştır. Buna karşılık, YOLOE çapasızdır ve yeni sınıfları dinamik olarak tespit eder. YOLOv8'in iyileştirmeleri üzerine inşa edilen YOLOE, daha yüksek doğruluk elde eder ( YOLOv5'in COCO'daki ~%50 mAP'sine karşılık %52,6) ve YOLOv5'ten farklı olarak örnek segmentasyonunu entegre eder.

  • YOLOE vs YOLOv8: YOLOE uzanıyor YOLOv8'nin yeniden tasarlanmış mimarisi ile benzer veya daha üstün doğruluk elde etmiştir(~26M parametre ile %52,6 mAP 'ye karşılık YOLOv8'nin ~44M parametre ile %52,9'u). Daha güçlü ön eğitim sayesinde eğitim süresini önemli ölçüde azaltır. En önemli ilerleme, YOLOv8'in kapalı set tasarımının aksine, YOLOE'nin açık dünya kabiliyetidir, görünmeyen nesneleri (örneğin,"kuş scooter" veya"barış sembolü") istemler aracılığıyla tespit eder.

  • YOLOE vs YOLO11: YOLO11YOLOv8 'i gelişmiş verimlilik ve daha az parametre (~%22 azalma) ile geliştirir. YOLOE, YOLO11'in çıkarım hızı ve parametre sayısıyla (~26M parametre) eşleşirken, açık kelime tespiti ve segmentasyon ekleyerek bu kazanımları doğrudan devralır. Kapalı set senaryolarında YOLOE, YOLO11 ile eşdeğerdir, ancak önemli ölçüde görünmeyen sınıfları tespit etmek için uyarlanabilirlik ekleyerek hızdan ödün vermeden YOLO11 + açık dünya yeteneğine ulaşır.

  • YOLOE ve önceki açık kelime dedektörleri: Daha önceki açık kelime modelleri (GLIP, OWL-ViT, YOLO) büyük ölçüde görüntü-dil dönüştürücülerine dayanıyordu ve bu da yavaş çıkarıma yol açıyordu. YOLOE, önemli ölçüde daha düşük eğitim kaynaklarıyla 1,4 kat daha hızlı çalışırken sıfır atış doğruluğunda (örneğin, YOLO'ye kıyasla +3,5 AP) bunları geride bırakıyor. Transformatör tabanlı yaklaşımlarla (örn. GLIP) karşılaştırıldığında, YOLOE büyüklük sırasına göre daha hızlı çıkarım sunarak açık set tespitindeki doğruluk-verimlilik açığını etkili bir şekilde kapatır.

Özetle, YOLOE, YOLO'nun ünlü hızını ve verimliliğini korur, doğrulukta öncekileri aşar, segmentasyonu entegre eder ve güçlü açık dünya algılaması sunarak onu benzersiz şekilde çok yönlü ve pratik hale getirir.

Kullanım Alanları ve Uygulamalar

YOLOE'nin açık sözlüklü algılama ve segmentasyonu, geleneksel sabit sınıf modellerinin ötesinde çeşitli uygulamaları mümkün kılar:

  • Açık Dünya Nesne Algılama: Robotların istemleri kullanarak daha önce görülmemiş nesneleri tanıdığı robotik gibi dinamik senaryolar veya yeniden eğitim almadan yeni tehditlere (örn. tehlikeli maddeler) hızla uyum sağlayan güvenlik sistemleri için idealdir.

  • Az Çekimli ve Tek Çekimli Algılama: Görsel istemleri (SAVPE) kullanan YOLOE, tek referans görüntülerden yeni nesneleri hızla öğrenir; endüstriyel denetim (parçaları veya kusurları anında tanımlama) veya özel gözetim için mükemmeldir ve minimum kurulumla görsel aramalara olanak tanır.

  • Geniş Kelime Dağarcığı ve Uzun Kuyruklu Tanıma: 1000'den fazla sınıftan oluşan bir kelime dağarcığına sahip olan YOLOE, biyoçeşitlilik izleme (nadir türleri tespit etme), müze koleksiyonları, perakende envanteri veya e-ticaret gibi görevlerde, sınıf başına kapsamlı eğitim olmadan birçok sınıfı güvenilir bir şekilde tanımlayarak öne çıkar.

  • Etkileşimli Algılama ve Segmentasyon: YOLOE, doğal girdilerle (metin veya görsel istemler) yönlendirilen aranabilir video/görüntü alma, artırılmış gerçeklik (AR) ve sezgisel görüntü düzenleme gibi gerçek zamanlı etkileşimli uygulamaları destekler. Kullanıcılar segmentasyon maskelerini kullanarak nesneleri dinamik olarak izole edebilir, tanımlayabilir veya düzenleyebilir.

  • Otomatik Veri Etiketleme ve Bootstrapping: YOLOE, ilk sınırlayıcı kutu ve segmentasyon ek açıklamalarını sağlayarak hızlı veri kümesi oluşturmayı kolaylaştırır ve insan etiketleme çabalarını önemli ölçüde azaltır. Özellikle mevcut nesneleri otomatik olarak tanımlayabildiği ve özel modellerin daha hızlı oluşturulmasına yardımcı olduğu büyük medya koleksiyonlarının analizinde değerlidir.

  • Herhangi Bir Nesne için Segmentasyon: Tıbbi görüntüleme, mikroskopi veya uydu görüntüsü analizi için özellikle yararlı olan segmentasyon yeteneklerini, önceden eğitilmiş özel modeller olmadan yapıları otomatik olarak tanımlayan ve hassas bir şekilde segmente eden istemler aracılığıyla rastgele nesnelere genişletir. gibi modellerin aksine SAMYOLOE aynı anda nesneleri otomatik olarak tanır ve bölümlere ayırır, içerik oluşturma veya sahne anlama gibi görevlere yardımcı olur.

Tüm bu kullanım durumlarında, YOLOE'nin temel avantajı çok yönlülüğüdür; dinamik senaryolarda algılama, tanıma ve segmentasyon için birleşik bir model sağlar. Verimliliği, robotik, otonom sürüş, savunma ve ötesi için ideal olan, kaynak kısıtlı cihazlarda gerçek zamanlı performans sağlar.

İpucu

YOLOE'nin modunu ihtiyaçlarınıza göre seçin:

  • Kapalı küme modu: Sabit sınıf görevleri için (maksimum hız ve doğruluk).
  • İstemli mod: Metin veya görsel istemler aracılığıyla hızla yeni nesneler ekleyin.
  • İstem içermeyen açık küme modu: Birçok kategori genelinde algılama (kataloglama ve keşif için idealdir).

Çoğu zaman, istem içermeyen keşif ve ardından hedeflenen istemler gibi modların birleştirilmesi, YOLOE'nin tüm potansiyelinden yararlanır.

Eğitim ve Çıkarım

YOLOE, diğer YOLO modellerine (YOLOv8, YOLO-World) benzer şekilde Ultralytics Python API'si ve CLI ile sorunsuz bir şekilde entegre olur. İşte hızlı bir şekilde nasıl başlayacağınız:

YOLOE ile eğitim ve çıkarım

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

Burada, YOLOE varsayılan olarak standart bir dedektör gibi davranır, ancak sınıfları belirterek (istemli algılamaya kolayca geçer.set_classes). Sonuçlar sınırlayıcı kutular, maskeler ve etiketler içerir.

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

CLI istemleri (classes) kılavuzu, YOLOE'ye Python'unki gibi benzer şekilde set_classes. Görsel istem (görüntü tabanlı sorgular) şu anda python API'sini gerektiriyor.

Diğer Desteklenen Görevler

  • Doğrulama: Şununla doğruluğu kolayca değerlendirin: model.val() veya yolo val.
  • Dışa Aktar: YOLOE modellerini dışa aktar (model.export()) - ONNX, TensorRT, vb.'ye aktararak dağıtımı kolaylaştırır.
  • İzleme: YOLOE, nesne takibini destekler (yolo track), entegre edildiğinde videolardaki istenen sınıfları izlemek için kullanışlıdır.

Not

YOLOE otomatik olarak şunları içerir: segmentasyon maskeleri çıkarım sonuçlarında (results[0].masks), ayrı modellere ihtiyaç duymadan nesne çıkarma veya ölçüm gibi piksel hassasiyeti gerektiren görevleri basitleştirir.

Başlarken

Aşağıdaki adımları izleyerek Ultralytics ile YOLOE'yi hızla kurun:

  1. Kurulum: Ultralytics paketini kurun veya güncelleyin:

    pip install -U ultralytics
    
  2. YOLOE Ağırlıklarını İndirin: Önceden eğitilmiş YOLOE modelleri (örneğin, YOLOE-v8-S/L, YOLOE-11 varyantları) YOLOE GitHub yayınlarından edinilebilir. İstediğiniz modeli indirmeniz yeterlidir .pt dosyası Ultralytics YOLO sınıfına yüklenecek.

  3. Donanım Gereksinimleri:

    • Çıkarım: Önerilen GPU (≥4-8GB VRAM'li NVIDIA). Küçük modeller, düşük çözünürlüklerde uç GPU'larda (örn. Jetson) veya CPU'larda verimli bir şekilde çalışır.
    • Eğitim: YOLOE'yi özel veriler üzerinde ince ayar yapmak genellikle yalnızca bir GPU gerektirir. Yazarlar tarafından kullanılan kapsamlı açık kelime dağarcığı ön eğitimi (LVIS/Objects365) önemli miktarda işlem gücü gerektiriyordu (8× RTX 4090 GPU).
  4. Yapılandırma: YOLOE yapılandırmaları standart Ultralytics YAML dosyalarını kullanır. Varsayılan yapılandırmalar (örneğin, yoloe-11s-seg.yaml) genellikle yeterlidir, ancak gerektiğinde backbone'u, sınıfları veya görüntü boyutunu değiştirebilirsiniz.

  5. YOLOE Çalıştırma:

    • Hızlı çıkarım (istem içermeyen):
      yolo predict model=yoloe-11s-seg-pf.pt source="image.jpg"
      
    • İstemli algılama (metin istemi örneği):

      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. Entegrasyon İpuçları:

    • Sınıf adları: Varsayılan YOLOE çıktıları LVIS kategorilerini kullanır; şunu kullanın: set_classes() kendi etiketlerinizi belirtmek için.
    • Hız: YOLOE, istemler kullanılmadığı sürece ek yüke sahip değildir. Metin istemleri minimum etkiye sahiptir; görsel istemler biraz daha fazla etkiye sahiptir.
    • Toplu çıkarım: Doğrudan desteklenir (model.predict([img1, img2])). Görüntüye özel istemler için, görüntüleri tek tek çalıştırın.

Ultralytics belgeleri daha fazla kaynak sağlamaktadır. YOLOE, tanıdık YOLO ekosistemi içinde güçlü açık dünya yeteneklerini kolayca keşfetmenizi sağlar.

İpucu

Profesyonel İpucu: YOLOE'nin sıfır atış doğruluğunu en üst düzeye çıkarmak için, sıfırdan eğitmek yerine sağlanan kontrol noktalarından ince ayar yapın. Algılama doğruluğunu artırmak için ortak eğitim etiketleriyle (bkz. LVIS kategorileri) uyumlu istem sözcükleri kullanın.

Alıntılar ve Teşekkürler

YOLOE, araştırmanıza veya projenize katkıda bulunduysa, lütfen Tsinghua Üniversitesi'nden Ao Wang, Lihao Liu, Hui Chen, Zijia Lin, Jungong Han ve Guiguang Ding tarafından yazılan orijinal makaleye atıfta bulunun:

@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},
}

Daha fazla okuma için, orijinal YOLOE makalesi arXiv'de mevcuttur. Projenin kaynak koduna ve ek kaynaklara GitHub deposu aracılığıyla erişilebilir.

SSS

YOLOE, YOLO-World'den nasıl farklıdır?

Hem YOLOE hem de YOLO-World açık kelime dağarcığı algılamayı etkinleştirse de, YOLOE çeşitli avantajlar sunar. YOLOE, 3× daha az eğitim kaynağı kullanırken ve YOLO-Worldv2'den 1,4× daha hızlı çalışırken LVIS'te +3,5 AP daha yüksek doğruluk elde eder. YOLOE ayrıca üç istem modunu (metin, görsel ve dahili kelime dağarcığı) desteklerken, YOLO-World öncelikle metin istemlerine odaklanır. Ek olarak, YOLOE, ek yük olmadan algılanan nesneler için piksel hassasiyetinde maskeler sağlayan yerleşik örnek segmentasyon yetenekleri içerir.

YOLOE'yi normal bir YOLO modeli olarak kullanabilir miyim?

Evet, YOLOE, standart bir YOLO modeli gibi, performans kaybı olmadan çalışabilir. Kapalı küme modunda (istemler olmadan) kullanıldığında, YOLOE'nin açık kelime dağarcığı modülleri standart algılama başlığına yeniden parametrelendirilir ve bu da eşdeğer YOLO11 modelleriyle aynı hız ve doğruluğu sağlar. Bu, YOLOE'yi son derece çok yönlü hale getirir; maksimum hız için onu geleneksel bir dedektör olarak kullanabilir ve yalnızca gerektiğinde açık kelime dağarcığı moduna geçebilirsiniz.

YOLOE ile ne tür istemler kullanabilirim?

YOLOE üç tür istemi destekler:

  1. Metin istemleri: Nesne sınıflarını doğal dil kullanarak belirtin (örneğin, "kişi", "trafik ışığı", "scooter")
  2. Görsel istemler: Algılamak istediğiniz nesnelerin referans görüntülerini sağlar
  3. Dahili kelime dağarcığı: YOLOE'nin 1200'den fazla kategoriden oluşan yerleşik kelime dağarcığını harici istemler olmadan kullanın

Bu esneklik, modeli yeniden eğitmeden YOLOE'yi çeşitli senaryolara uyarlamanıza olanak tanır ve bu da onu algılama gereksinimlerinin sık sık değiştiği dinamik ortamlar için özellikle kullanışlı hale getirir.

YOLOE, örnek segmentasyonunu nasıl ele alır?

YOLOE, algılama başlığını bir maske tahmin dalıyla genişleterek örnek segmentasyonunu doğrudan mimarisine entegre eder. Bu yaklaşım YOLOv8-Seg'e benzer, ancak herhangi bir istemli nesne sınıfı için çalışır. Segmentasyon maskeleri otomatik olarak çıkarım sonuçlarına dahil edilir ve aracılığıyla erişilebilir. results[0].masks. Bu birleşik yaklaşım, ayrı algılama ve segmentasyon modellerine olan ihtiyacı ortadan kaldırır ve piksel hassasiyetinde nesne sınırları gerektiren uygulamalar için iş akışlarını kolaylaştırır.

YOLOE, özel istemlerle çıkarımı nasıl ele alır?

YOLO-World'e benzer şekilde, YOLOE verimliliği artırmak için çevrimdışı bir sözlük kullanan bir "istem-sonra-algıla" stratejisini destekler. Altyazılar veya belirli nesne kategorileri gibi özel istemler önceden kodlanır ve çevrimdışı sözlük gömme işlemleri olarak saklanır. Bu yaklaşım, yeniden eğitim gerektirmeden algılama sürecini kolaylaştırır. Modele özel algılama görevlerine uyacak şekilde dinamik olarak bu istemleri ayarlayabilirsiniz:

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()


📅 6 ay önce oluşturuldu ✏️ 19 gün önce güncellendi

Yorumlar