Ultralytics YOLO27:
Get Started

Eğitici Özelleştirme#

Ultralytics eğitim işlem hattı, BaseTrainer ve DetectionTrainer gibi göreve özgü eğiticiler etrafında oluşturulmuştur. Bu sınıflar eğitim döngüsünü, doğrulamayı, kontrol noktalarını ve günlük kaydını kullanıma hazır şekilde yönetir. Özel metrikleri izlemek, kayıp ağırlıklarını ayarlamak veya öğrenme oranı çizelgeleri uygulamak gibi daha fazla denetime ihtiyaç duyduğunda eğitici sınıfından türeyebilir ve belirli yöntemleri geçersiz kılabilirsin.

Bu kılavuzda yaygın yedi özelleştirme ele alınıyor:

  1. Her dönemin sonunda özel metrikleri günlüğe kaydetme (F1 puanı)
  2. Sınıf dengesizliğini ele almak için sınıf ağırlıkları ekleme
  3. Farklı bir metriğe göre en iyi modeli kaydetme
  4. İlk N epoch boyunca omurgayı dondurma, ardından dondurmayı kaldırma
  5. Katman başına öğrenme oranlarını belirtme
  6. Çoklu GPU eğitimi için BatchNorm'u GPU'lar arasında eşitleme
  7. Kararlılık ayarı için gradyan kırpmayı yapılandırma
Ön koşullar

Bu kılavuzu okumadan önce YOLO modellerini eğitmenin temellerine ve BaseTrainer mimarisini ele alan Gelişmiş Özelleştirme sayfasına aşina olduğundan emin ol.

Özel Eğitmenler Nasıl Çalışır?#

YOLO model sınıfı, train() yönteminde bir trainer parametresi kabul eder. Bu sayede varsayılan davranışı genişleten kendi eğitmen sınıfını iletebilirsin:

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer

class CustomTrainer(DetectionTrainer):
    """A custom trainer that extends DetectionTrainer with additional functionality."""

    # Özelleştirmelerini buraya ekle

model = YOLO("yolo26n.pt")
model.train(data="coco8.yaml", epochs=10, trainer=CustomTrainer)

Özel eğitmenin, DetectionTrainer sınıfındaki tüm işlevleri devralır; bu nedenle yalnızca özelleştirmek istediğin belirli yöntemleri geçersiz kılman yeterlidir.

Özel Metrikleri Günlüğe Kaydetme#

Doğrulama adımı kesinlik, duyarlılık ve mAP değerlerini hesaplar. Sınıf başına F1 skoru gibi ek metriklere ihtiyacın varsa validate() yöntemini geçersiz kıl:

import numpy as np

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer
from ultralytics.utils import LOGGER

class MetricsTrainer(DetectionTrainer):
    """Custom trainer that computes and logs F1 score at the end of each epoch."""

    def validate(self):
        """Run validation and compute per-class F1 scores."""
        metrics, fitness = super().validate()
        if metrics is None:
            return metrics, fitness

        if hasattr(self.validator, "metrics") and hasattr(self.validator.metrics, "box"):
            box = self.validator.metrics.box
            f1_per_class = box.f1
            class_indices = box.ap_class_index
            names = self.validator.names

            mean_f1 = float(np.mean(f1_per_class)) if len(f1_per_class) else 0.0

            LOGGER.info(f"Mean F1 Score: {mean_f1:.4f}")
            per_class_str = [f"{names[i]}: {f1_per_class[j]:.3f}" for j, i in enumerate(class_indices)]
            LOGGER.info(f"Per-class F1: {per_class_str}")

        return metrics, fitness

model = YOLO("yolo26n.pt")
model.train(data="coco8.yaml", epochs=5, trainer=MetricsTrainer)

Bu işlem, doğrulamada temsil edilen tüm sınıfların ortalama F1 skorunu ve her doğrulama çalışmasından sonra sınıf başına ayrıntıları günlüğe kaydeder.

Kullanılabilir Metrikler

Doğrulayıcı, self.validator.metrics.box aracılığıyla birçok metriğe erişim sağlar:

ÖznitelikAçıklama
f1Sınıf başına F1 skoru
image_metricsKesinlik, duyarlılık, F1, TP, FP ve FN değerlerini içeren görüntü başına metrik sözlüğü
pSınıf başına kesinlik
rSınıf başına duyarlılık
ap50Sınıf başına IoU 0.5 değerindeki AP
apSınıf başına IoU 0.5:0.95 değerindeki AP
mp, mrOrtalama kesinlik ve duyarlılık
map50, mapOrtalama AP metrikleri

Sınıf Ağırlıkları Ekleme#

Sınıflandırma kaybına normalize edilmiş ters frekans ağırlıkları uygulamak için cls_pw değerini 0.0 ile 1.0 arasında ayarla. Mevcut ağırlık hesaplamasını yalnızca elle belirlenmiş oranlara ihtiyaç duyduğunda geçersiz kıl:

import numpy as np

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer

class WeightedTrainer(DetectionTrainer):
    """Detection trainer with hand-picked class-weight ratios."""

    def compute_class_weights(self, class_counts):
        """Return custom per-class weights that the detection loss applies."""
        weights = np.ones_like(class_counts)
        weights[0] = 2.0
        weights[1] = 3.0
        return weights

model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=10, cls_pw=1.0, trainer=WeightedTrainer)

set_class_weights() bu değerleri ortalaması 1.0 olacak şekilde normalize eder ve modelde saklar; mevcut algılama kaybı bu değerleri uygular. Yukarıdaki indeksler için en az iki sınıf içeren bir veri kümesi gerekir.

Özel Metrik Kullanarak En İyi Modeli Kaydetme#

Eğitici, uygunluk puanına göre best.pt değerini kaydeder; algılama için varsayılan uygunluk puanı mAP@0.5:0.95 olur ([P, R, mAP@0.5, mAP@0.5:0.95] için [0.0, 0.0, 0.0, 1.0] ağırlıkları). Farklı bir metrik (örneğin mAP@0.5 veya duyarlılık) kullanmak için validate() öğesini geçersiz kıl ve seçtiğin metriği uygunluk değeri olarak döndür. Yerleşik save_model() bunu daha sonra otomatik olarak kullanır:

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer

class CustomSaveTrainer(DetectionTrainer):
    """Trainer that saves the best model based on mAP@0.5 instead of default fitness."""

    def validate(self):
        """Override fitness to use mAP@0.5 for best model selection."""
        previous_best = self.best_fitness
        metrics, fitness = super().validate()
        if metrics is None:
            return metrics, fitness
        fitness = metrics["metrics/mAP50(B)"]
        self.best_fitness = fitness if previous_best is None else max(previous_best, fitness)
        return metrics, fitness

model = YOLO("yolo26n.pt")
model.train(data="coco8.yaml", epochs=20, trainer=CustomSaveTrainer)

BaseTrainer.validate(), best_fitness değerini varsayılan metriği kullanarak günceller; bu nedenle çağırmadan önce önceki değerini yakala.

Kullanılabilir Metrikler

Doğrulamadan sonra self.metrics içinde bulunan yaygın metrikler:

AnahtarAçıklama
metrics/precision(B)Kesinlik
metrics/recall(B)Duyarlılık
metrics/mAP50(B)IoU 0.5 değerinde mAP
metrics/mAP50-95(B)IoU 0.5:0.95 değerinde mAP

Omurgayı Dondurma ve Dondurmayı Kaldırma#

Aktarım öğrenimi iş akışlarında, çoğu zaman ilk N epoch boyunca önceden eğitilmiş omurgayı dondurmak yararlı olur; böylece tüm ağı ince ayarlamadan önce algılama başlığının uyum sağlamasına olanak tanınır. Ultralytics, eğitimin başlangıcında katmanları dondurmak için bir freeze parametresi sunar. N epoch sonra dondurmayı kaldırmak için geri çağırım kullanabilirsin:

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer
from ultralytics.utils import LOGGER

FREEZE_EPOCHS = 5

def unfreeze_backbone(trainer):
    """Callback to unfreeze the user-requested layers after FREEZE_EPOCHS."""
    if trainer.epoch == FREEZE_EPOCHS:
        user_freeze = [x for x in trainer.freeze_layer_names if x not in {".dfl", "teacher_model."}]
        LOGGER.info(f"Epoch {trainer.epoch}: Unfreezing requested layers for fine-tuning")
        for name, param in trainer.model.named_parameters():
            if (
                not param.requires_grad
                and ".dfl" not in name
                and "teacher_model." not in name
                and any(x in name for x in user_freeze)
            ):
                param.requires_grad = True
                LOGGER.info(f"  Unfroze: {name}")
        trainer.freeze_layer_names = [x for x in trainer.freeze_layer_names if x not in user_freeze]

class FreezingTrainer(DetectionTrainer):
    """Trainer with backbone freezing for first N epochs."""

    def __init__(self, *args, **kwargs):
        """Initialize and register the unfreeze callback."""
        super().__init__(*args, **kwargs)
        self.add_callback("on_train_epoch_start", unfreeze_backbone)

model = YOLO("yolo26n.pt")
model.train(data="coco8.yaml", epochs=20, freeze=10, trainer=FreezingTrainer)

freeze=10 parametresi, eğitimin başlangıcında ilk 10 katmanı (0-9 indeksleri) dondurur; bu, YOLO26 omurgasının büyük bölümünü kapsar. Omurga 0-10 katmanlarını içerdiğinden freeze=10 son C2PSA bloğunu (10. katman) eğitilebilir bırakır; omurganın tamamını dondurmak için freeze=11 kullan. on_train_epoch_start geri çağırımı her epoch'un başında çalışır ve dondurma süresi dolduğunda belirtilen katmanların dondurmasını kaldırır; DFL ve damıtma öğretmeni parametrelerinin kalıcı olarak dondurulmuş olmasını korur.

Neyi Donduracağını Seçme
  • freeze=10 ilk 10 katmanı, yani 0-9 indekslerini dondurur (YOLO26 omurgasının çoğunu; son C2PSA bloğunu, 10. katmanı da dahil etmek için freeze=11 kullan)
  • freeze=[0, 1, 2, 3] belirli katmanları indekslerine göre dondurur
  • Daha yüksek FREEZE_EPOCHS değerleri, omurga değişmeden önce başlığın uyum sağlaması için daha fazla zaman tanır

Katman Başına Öğrenme Oranları#

Ağın farklı bölümleri, farklı öğrenme oranlarından yararlanabilir. Yaygın bir strateji, öğrenilen özellikleri korumak için önceden eğitilmiş omurgada daha düşük bir öğrenme oranı kullanırken algılama başlığının daha yüksek bir oranla daha hızlı uyum sağlamasına izin vermektir:

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer
from ultralytics.utils import LOGGER
from ultralytics.utils.torch_utils import unwrap_model

class PerLayerLRTrainer(DetectionTrainer):
    """Trainer with different learning rates for backbone and head."""

    backbone_lr_ratio = 0.1

    def build_optimizer(self, model, name="auto", lr=0.001, momentum=0.9, decay=1e-5, iterations=1e5):
        """Reuse the trainer optimizer and lower its backbone parameter-group rates."""
        optimizer = super().build_optimizer(model, name, lr, momentum, decay, iterations)
        unwrapped = unwrap_model(model)
        backbone_len = len(unwrapped.yaml["backbone"])
        backbone = {
            id(p)
            for name, p in unwrapped.named_parameters()
            if any(name.startswith(f"model.{i}.") for i in range(backbone_len))
        }

        groups = []
        for group in optimizer.param_groups:
            head_params = [p for p in group["params"] if id(p) not in backbone]
            backbone_params = [p for p in group["params"] if id(p) in backbone]
            if head_params:
                groups.append({**group, "params": head_params})
            if backbone_params:
                groups.append({**group, "params": backbone_params, "lr": group["lr"] * self.backbone_lr_ratio})
        optimizer.param_groups = groups

        LOGGER.info(f"PerLayerLR: {len(backbone)} backbone params at {self.backbone_lr_ratio}x the head rate")
        return optimizer

model = YOLO("yolo26n.pt")
model.train(data="coco8.yaml", epochs=20, trainer=PerLayerLRTrainer)

RT-DETR Varyantı#

RT-DETR için, üst sınıf olarak RTDETRTrainer kullanan aynı geçersiz kılmayı uygula ve kontrol noktalarını RTDETR("rtdetr-l.pt") ile yükle.

Çoklu GPU Eğitimi için Eşitlenmiş BatchNorm#

DistributedDataParallel ile birden fazla GPU'da eğitim yaparken varsayılan BatchNorm2d katmanları istatistikleri her GPU'da bağımsız olarak hesaplar. RT-DETR ince ayarı ve GPU başına küçük yığın boyutları kullanan diğer tariflerde GPU başına yığın istatistikleri gürültülü olabilir. PyTorch SyncBatchNorm, tek bir genel yığın istatistiği elde etmek için ortalama ve varyansı tüm sıralamalar arasında eşitler; bu, az miktarda GPU'lar arası iletişim yükü karşılığında genellikle yakınsamayı iyileştirir.

Dönüşüm, model GPU'ya alındıktan sonra ancak DDP modeli sarmalamadan önce yapılmalıdır. Bunun için en uygun kanca set_model_attributes() olup BaseTrainer bu kancayı tam da bu aralıkta çağırır:

from torch import nn

from ultralytics import RTDETR
from ultralytics.models.rtdetr.train import RTDETRTrainer

class SyncBNTrainer(RTDETRTrainer):
    """RT-DETR trainer that converts BatchNorm to SyncBatchNorm for multi-GPU training."""

    def set_model_attributes(self):
        """Run the parent setup, then convert BN to SyncBatchNorm when training on multiple GPUs."""
        super().set_model_attributes()
        if self.world_size > 1:
            self.model = nn.SyncBatchNorm.convert_sync_batchnorm(self.model)

model = RTDETR("rtdetr-l.pt")
model.train(data="coco8.yaml", epochs=20, device=[0, 1], trainer=SyncBNTrainer)

world_size > 1 koruması, eğitmenin tek GPU'lu çalıştırmalarda da güvenle kullanılmasını sağlar; tek GPU'da dönüşüm atlanır ve eğitim normal BatchNorm2d ile devam eder. Üst sınıfı DetectionTrainer olarak değiştirerek aynı yaklaşımı YOLO için de kullanabilirsin.

SyncBatchNorm Ne Zaman Kullanılır?
SenaryoÖneri
Çoklu GPU eğitimi, GPU başına küçük yığın (≤ 16)Etkinleştir
Çoklu GPU eğitimi, GPU başına büyük yığın (≥ 32)İsteğe bağlı; küçük bir fayda sağlar
Tek GPU eğitimiUygulanamaz (atlandı)

Yapılandırılabilir Gradyan Kırpma#

Varsayılan eğitmen, gradyanları optimizer_step() içindeki max_norm=10.0 değerine göre kırpar. Bu, gradyanların nadiren aştığı YOLO modelleri için ayarlanmış geniş bir değerdir. DETR ailesindeki algılayıcılar (RT-DETR, DEIM, DINO), gradyan büyüklüklerinin artabildiği kod çözücünün çapraz dikkat katmanlarını kararlı hâle getirmek için genellikle 0.1 gibi çok daha düşük değerler kullanır. Kırpma değerini geçersiz kılmak için eğitmen alt sınıfı oluştur ve optimizer_step() yöntemini geçersiz kıl:

import torch

from ultralytics import RTDETR
from ultralytics.models.rtdetr.train import RTDETRTrainer
from ultralytics.utils.torch_utils import TORCH_2_0

class CustomClipTrainer(RTDETRTrainer):
    """RT-DETR trainer with configurable gradient clipping."""

    clip_grad_norm = 0.1  # maksimum gradyan normu; kırpmayı devre dışı bırakmak için 0 olarak ayarla

    def optimizer_step(self):
        """Run an optimizer step with a configurable gradient-norm clip."""
        self.scaler.unscale_(self.optimizer)
        if self.clip_grad_norm > 0:
            kwargs = {"foreach": False} if self.device.type == "npu" and TORCH_2_0 else {}
            torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=self.clip_grad_norm, **kwargs)
        self.scaler.step(self.optimizer)
        self.scaler.update()
        self.optimizer.zero_grad()
        if self.ema:
            self.ema.update(self.model)

model = RTDETR("rtdetr-l.pt")
model.train(data="coco8.yaml", epochs=20, trainer=CustomClipTrainer)

Üst sınıfı DetectionTrainer (from ultralytics.models.yolo.detect import DetectionTrainer) olarak değiştirip YOLO("yolo26n.pt") ile bir YOLO kontrol noktası yükleyerek aynı eğiticiyi YOLO için de kullanabilirsin. optimizer_step gövdesi değişmeden kalır.

Tipik `clip_grad_norm` değerleri
Mimari ailesiTipik max_norm
RT-DETR / DEIM / DETR ailesi0.1
YOLO (Ultralytics varsayılanı)10.0
Kırpmayı devre dışı bırak0

Sık Sorulan Sorular#

  • Özel eğitmen sınıfını (bir örneğini değil) model.train() içindeki trainer parametresine ilet:

    from ultralytics import YOLO
    from ultralytics.models.yolo.detect import DetectionTrainer
    
    class MyCustomTrainer(DetectionTrainer):
        """A custom trainer that extends DetectionTrainer."""
    
    model = YOLO("yolo26n.pt")
    model.train(data="coco8.yaml", trainer=MyCustomTrainer)

    YOLO sınıfı, eğitmen örneğini kendi içinde oluşturur. Eğitmen mimarisi hakkında daha fazla bilgi için Gelişmiş Özelleştirme sayfasına bak.

  • Özelleştirme için kullanılabilen temel yöntemler:

    YöntemAmaç
    validate()Doğrulamayı çalıştırıp metrikleri döndürme
    build_optimizer()Eniyileyiciyi oluşturma
    save_model()Eğitim kontrol noktalarını kaydetme
    get_model()Model örneğini döndürme
    get_validator()Doğrulayıcı örneğini döndürme
    get_dataloader()Veri yükleyiciyi oluşturma
    preprocess_batch()Girdi yığınını ön işleme tabi tutma
    label_loss_items()Günlüğe kaydetmek için kayıp öğelerini biçimlendirme

    API'nin tam başvuru belgesi için BaseTrainer belgelerine bak.

  • Evet, daha basit özelleştirmeler için geri çağırımlar çoğu zaman yeterlidir. Kullanılabilir geri çağırım olayları şunlardır: on_train_start, on_train_epoch_start, on_train_epoch_end, on_fit_epoch_end ve on_model_save. Bunlar, alt sınıf oluşturmadan eğitim döngüsüne kanca eklemeni sağlar. Yukarıdaki omurga dondurma örneği bu yaklaşımı gösterir.

  • Değişikliğin daha basitse (ör. kayıp katsayılarını ayarlamak), hiperparametreleri doğrudan değiştirebilirsin:

    from ultralytics import YOLO
    
    model = YOLO("yolo26n.pt")
    model.train(data="coco8.yaml", box=10.0, cls=1.5, dfl=2.0)

    YOLO26'da dfl, algılama başlığı reg_max: 1 kullandığı için günlüğe kaydedilen l1_loss değerini ölçeklendirir; reg_max > 1 kullanan modellerde ise dfl_loss değerini ölçeklendirir.

Yorumlar