İçeriğe geç

Özelleştirme Eğitmeni

Ultralytics süreci şu unsurlar etrafında şekillenmiştir: BaseTrainer ve göreve özel eğitmenler gibi DetectionTrainer. Bu sınıflar, eğitim döngüsünü, doğrulamayı, kontrol noktasını ve oturum kapatmayı hazır olarak ele alır. Daha fazla kontrol gerektiğinde (özel metrikleri izleme, kayıp ağırlığını ayarlama veya öğrenme oranı programlarını uygulama gibi), eğiticiyi alt sınıfa alabilir ve belirli yöntemleri geçersiz kılabilirsiniz.

Bu kılavuz, beş yaygın özelleştirme işlemini adım adım açıklamaktadır:

  1. Her dönemin sonunda özel metrikleri (F1 puanı) kaydetme
  2. Sınıf dengesizliğini gidermek için sınıf ağırlıkları ekleme
  3. Farklı bir metrik temelinde en iyi modeli kaydetme
  4. İlk N dönem boyunca backbone dondurmak, ardından dondurmayı kaldırmak
  5. Katman başına öğrenme oranlarını belirleme

Ön koşullar

Bu kılavuzu okumadan önce, temel bilgilere aşina olduğunuzdan emin olun. YOLO eğitimi ve Gelişmiş Özelleştirme sayfası, aşağıdakileri kapsar: BaseTrainer mimarlık.

Özel Antrenörler Nasıl Çalışır?

YOLO model sınıfı bir trainer parametresi içinde train() yöntemi. Bu, varsayılan davranışı genişleten kendi eğitmen sınıfınızı aktarmanıza olanak tanır:

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


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

    pass  # Add your customizations here


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

Özel eğitmeniniz tüm işlevleri miras alır. DetectionTrainer, bu nedenle yalnızca özelleştirmek istediğiniz belirli yöntemleri geçersiz kılmanız yeterlidir.

Özel Metrikleri Günlüğe Kaydetme

doğrulama adım hesaplar kesinlik, duyarlılık (recall)ve mAP. Sınıf başına gibi ek metriklere ihtiyacınız varsa F1 skoru, geçersiz kıl validate():

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

            valid_f1 = f1_per_class[f1_per_class > 0]
            mean_f1 = np.mean(valid_f1) if len(valid_f1) > 0 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) if f1_per_class[j] > 0
            ]
            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, her doğrulama çalışmasından sonra tüm sınıflar için ortalama F1 puanını ve sınıf başına dağılımı kaydeder.

Mevcut Metrikler

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

ÖzellikAçıklama
f1Sınıf başına F1 puanı
pSınıf başına hassasiyet
rSınıf başına geri çağırma
ap50Sınıf AP IoU ,5 IoU
apAP IoU ,5:0,95 AP sınıf
mp, mrOrtalama hassasiyet ve geri çağırma
map50, mapOrtalama AP

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

Veri kümenizde dengesiz sınıflar varsa (örneğin, üretim denetiminde nadir görülen bir kusur), kayıp fonksiyonunda yeterince temsil edilmeyen sınıfların ağırlığını artırabilirsiniz. Bu, modelin nadir görülen sınıflardaki yanlış sınıflandırmaları daha ağır bir şekilde cezalandırmasını sağlar.

Kaybı özelleştirmek için, kayıp sınıflarını, modeli ve eğiticiyi alt sınıflara ayırın:

import torch
from torch import nn

from ultralytics import YOLO
from ultralytics.models.yolo.detect import DetectionTrainer
from ultralytics.nn.tasks import DetectionModel
from ultralytics.utils import RANK
from ultralytics.utils.loss import E2ELoss, v8DetectionLoss


class WeightedDetectionLoss(v8DetectionLoss):
    """Detection loss with class weights applied to BCE classification loss."""

    def __init__(self, model, class_weights=None, tal_topk=10, tal_topk2=None):
        """Initialize loss with optional per-class weights for BCE."""
        super().__init__(model, tal_topk=tal_topk, tal_topk2=tal_topk2)
        if class_weights is not None:
            self.bce = nn.BCEWithLogitsLoss(
                pos_weight=class_weights.to(self.device),
                reduction="none",
            )


class WeightedE2ELoss(E2ELoss):
    """E2E Loss with class weights for YOLO26."""

    def __init__(self, model, class_weights=None):
        """Initialize E2E loss with weighted detection loss."""

        def weighted_loss_fn(model, tal_topk=10, tal_topk2=None):
            return WeightedDetectionLoss(model, class_weights=class_weights, tal_topk=tal_topk, tal_topk2=tal_topk2)

        super().__init__(model, loss_fn=weighted_loss_fn)


class WeightedDetectionModel(DetectionModel):
    """Detection model that uses class-weighted loss."""

    def init_criterion(self):
        """Initialize weighted loss criterion with per-class weights."""
        class_weights = torch.ones(self.nc)
        class_weights[0] = 2.0  # upweight class 0
        class_weights[1] = 3.0  # upweight rare class 1
        return WeightedE2ELoss(self, class_weights=class_weights)


class WeightedTrainer(DetectionTrainer):
    """Trainer that returns a WeightedDetectionModel."""

    def get_model(self, cfg=None, weights=None, verbose=True):
        """Return a WeightedDetectionModel."""
        model = WeightedDetectionModel(cfg, nc=self.data["nc"], verbose=verbose and RANK == -1)
        if weights:
            model.load(weights)
        return model


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

Veri Setinden Ağırlıkları Hesaplama

Veri kümenizin etiket dağılımından sınıf ağırlıklarını otomatik olarak hesaplayabilirsiniz. Yaygın bir yaklaşım, ters frekans ağırlıklandırmasıdır:

import numpy as np

# class_counts: number of instances per class
class_counts = np.array([5000, 200, 3000])
# Inverse frequency: rarer classes get higher weight
class_weights = max(class_counts) / class_counts
# Result: [1.0, 25.0, 1.67]

Özel Metrik ile En İyi Modeli Kaydetme

Eğitmen kaydeder best.pt fitness temelinde, varsayılan olarak 0.9 × mAP@0.5:0.95 + 0.1 × mAP@0.5. Farklı bir ölçü birimi kullanmak için (örneğin mAP@0.5 veya geri çağırma), geçersiz kılma validate() ve seçtiğiniz metriği uygunluk değeri olarak döndürür. Yerleşik save_model() daha sonra otomatik olarak kullanacaktı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."""
        metrics, fitness = super().validate()
        if metrics:
            fitness = metrics.get("metrics/mAP50(B)", fitness)
            if self.best_fitness is None or fitness > self.best_fitness:
                self.best_fitness = fitness
        return metrics, fitness


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

Mevcut Metrikler

Yaygın olarak kullanılan ölçütler self.metrics doğrulama sonrasında şunları içerir:

AnahtarAçıklama
metrics/precision(B)Kesinlik
metrics/recall(B)Duyarlılık (Recall)
metrics/mAP50(B)IoU ,5mAP
metrics/mAP50-95(B)IoU ,5:0,95'te mAP

Omurganın Backboneondurulması ve Dondurmanın Kaldırılması

Transfer öğrenimi iş akışları genellikle ilk N dönem backbone önceden eğitilmiş backbone dondurmaktan yararlanır, böylece algılama başlığı uyum sağlayabilir. ince ayar tüm ağ. Ultralytics bir freeze parametresini kullanarak eğitimin başlangıcında katmanları dondurmak ve geri çağırma (callback) N dönemden sonra onları çözmek için:

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 all layers after FREEZE_EPOCHS."""
    if trainer.epoch == FREEZE_EPOCHS:
        LOGGER.info(f"Epoch {trainer.epoch}: Unfreezing all layers for fine-tuning")
        for name, param in trainer.model.named_parameters():
            if not param.requires_grad:
                param.requires_grad = True
                LOGGER.info(f"  Unfroze: {name}")
        trainer.freeze_layer_names = [".dfl"]


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ğitim başlangıcında ilk 10 katmanı ( backbone) dondurur. on_train_epoch_start geri arama her dönemin başında tetiklenir ve dondurma süresi tamamlandığında tüm parametreleri çözdürür.

Ne Dondurulacağını Seçmek

  • freeze=10 ilk 10 katmanı dondurur (genellikle YOLO backbone )
  • freeze=[0, 1, 2, 3] belirli katmanları indekse göre dondurur
  • Daha Yüksek FREEZE_EPOCHS değerler, backbone önce kafanın uyum sağlaması için daha fazla zaman tanır

Katman Başına Öğrenme Oranları

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

import torch

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

    def build_optimizer(self, model, name="auto", lr=0.001, momentum=0.9, decay=1e-5, iterations=1e5):
        """Build optimizer with separate learning rates for backbone and head."""
        backbone_params = []
        head_params = []

        for k, v in unwrap_model(model).named_parameters():
            if not v.requires_grad:
                continue
            is_backbone = any(k.startswith(f"model.{i}.") for i in range(10))
            if is_backbone:
                backbone_params.append(v)
            else:
                head_params.append(v)

        backbone_lr = lr * 0.1

        optimizer = torch.optim.AdamW(
            [
                {"params": backbone_params, "lr": backbone_lr, "weight_decay": decay},
                {"params": head_params, "lr": lr, "weight_decay": decay},
            ],
        )

        LOGGER.info(
            f"PerLayerLR optimizer: backbone ({len(backbone_params)} params, lr={backbone_lr}) "
            f"| head ({len(head_params)} params, lr={lr})"
        )
        return optimizer


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

Öğrenme Hızı Planlayıcı

Yerleşik öğrenme oranı zamanlayıcı (cosine veya linear) grup başına temel öğrenme oranlarının üzerine eklenir. Hem backbone baş öğrenme oranları aynı azalma programını takip eder ve eğitim boyunca aralarındaki oranı korur.

Teknikleri Birleştirme

Bu özelleştirmeler, birden fazla yöntemi geçersiz kılarak ve gerektiğinde geri aramalar ekleyerek tek bir eğitmen sınıfında birleştirilebilir.

SSS

YOLO'ya özel bir eğitmen nasıl aktarılır?

Özel eğitmen sınıfınızı (örnek değil) trainer parametresi içinde model.train():

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model.train(data="coco8.yaml", trainer=MyCustomTrainer)

YOLO sınıf, eğitmen örneklenmesini dahili olarak yönetir. Bkz. Gelişmiş Özelleştirme Eğitmen mimarisi hakkında daha fazla bilgi için sayfasına bakın.

Hangi BaseTrainer yöntemlerini geçersiz kılabilirim?

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

MetotAmaç
validate()Doğrulama çalıştır ve metrikleri döndür
build_optimizer()Optimize ediciyi oluşturun
save_model()Eğitim kontrol noktalarını kaydet
get_model()Model örneğini döndür
get_validator()Doğrulayıcı örneğini döndür
get_dataloader()Veri yükleyiciyi oluşturun
preprocess_batch()Giriş grubunu önceden işleme
label_loss_items()Günlüğe kaydetmek için biçim kaybı öğelerini biçimlendirin

API referansının tamamı için bkz. BaseTrainer belgeleme.

Eğiticiyi alt sınıflandırmak yerine geri aramaları kullanabilir miyim?

Evet, daha basit özelleştirmeler için, geri aramalar genellikle yeterlidir. Kullanılabilir geri arama olayları şunlardır: on_train_start, on_train_epoch_start, on_train_epoch_end, on_fit_epoch_endve on_model_saveBunlar, alt sınıf oluşturmadan eğitim döngüsüne bağlanmanıza olanak tanır. Yukarıdaki backbone örneği bu yaklaşımı göstermektedir.

Modeli alt sınıflandırmadan kayıp fonksiyonunu nasıl özelleştirebilirim?

Değişikliğiniz daha basitse (kayıp kazançlarını ayarlamak gibi), hiperparametreleri doğrudan değiştirebilirsiniz:

model.train(data="coco8.yaml", box=10.0, cls=1.5, dfl=2.0)

Kayıpta yapısal değişiklikler yapmak için (sınıf ağırlıkları eklemek gibi), sınıf ağırlıkları bölümünde gösterildiği gibi kayıp ve modeli alt sınıfa ayırmanız gerekir.



📅 6 gün önce oluşturuldu ✏️ 0 gün önce güncellendi
raimbekovmonuralpszr

Yorumlar