Architektura

Aktualny przeplyw modelu

Obecna sciezka modelu ma postac:

Backbone (ResNet lub HGNet-V2-S) -> HybridEncoder -> QuerySelection -> EasyDecoder -> DetectionPostProcessor

Trening rozszerza to o dodatkowe elementy:

  • contrastive denoising,
  • galezie o2o i o2m,
  • auxiliary dense head w stylu PP-YOLOE.

Backbone

Repo wspiera dwa glowne typy backbone'u:

  • torchvision ResNet:
  • resnet18,
  • resnet34,
  • resnet50,
  • resnet101,
  • HGNet-V2 inspirowany PPHGNetV2 z PaddleClas:
  • hgnetv2_s (~23M params, lokalnie definiowany wariant),
  • hgnetv2_b0 (~5M params, kompatybilny channel-by-channel z PPHGNetV2_B0 z PaddleClas, ma dostepne pretrenowane wagi).

Backbone domyslnie zwraca trzy poziomy cech o stride 8, 16, 32. Jest tez opt-in support dla 4-poziomowego wariantu z P2 (stride 4) - patrz experiments.md sekcja 11 dla rezultatow.

Wsparcie dla P2 (opcjonalne)

Backbone moze zwrocic dodatkowy poziom P2:

  • TorchvisionResNetBackbone i HGNetV2Backbone przyjmuja flag return_p2,
  • build_backbone ustawia go automatycznie gdy w feat_strides jest 4,
  • model.py wykrywa to przez return_p2 = 4 in config.feat_strides,
  • konfiguracja YAML: num_feature_levels: 4, feat_strides: [4, 8, 16, 32], hybrid_encoder_use_idx: [3].

W obecnym setupie wlaczenie P2 na 5 epok dalo silna regresje. Wsparcie zostawione w kodzie do przyszlych dluzszych biegow.

HybridEncoder

Aktualny HybridEncoder jest juz wyraznie blizej referencji niz poczatkowy prosty neck.

Zaimplementowane elementy:

  • projekcja kanalow do wspolnego hidden_dim,
  • transformer encoder na wybranych poziomach cech,
  • 2D sinus-cosinus positional embedding,
  • top-down fusion w stylu FPN,
  • bottom-up fusion w stylu PAN,
  • blokowe laczenie cech typu CSPRep.

To jest istotna zmiana wzgledem pierwszej wersji, ktora miala jedynie:

  • proste dodawanie map cech,
  • zwykle bloki konwolucyjne,
  • brak transformerowego wzbogacenia najwyzszego poziomu.

Query Selection

QuerySelection odpowiada za przygotowanie wejscia do dekodera.

Obecne elementy:

  • anchor-like proposals generowane z encoder memory,
  • valid_mask dla pozycji spoza poprawnego zakresu,
  • wiele grup query,
  • learnt_init_query,
  • rozdzielenie o2o i o2m,
  • training-only denoising queries.

To jest juz sensownie zblizone do referencyjnego _get_decoder_input z ppdet, chociaz nadal nie jest to pelny port bit-po-bicie.

Decoder

Decoder ma:

  • deformable cross-attention,
  • masked self-attention dla grup query,
  • iteracyjny refinement boxow,
  • osobne heady klas i bbox per layer.
  • opcjonalny quality_score_head per decoder layer.

Wczesniej decoder byl bardziej uproszczony. Zostal poprawiony tak, aby:

  • lepiej obslugiwac reference points,
  • sensowniej inicjalizowac attention,
  • dawac bardziej stabilny refinement boxow.

Quality-aware scoring

Dodano lekka, opcjonalna glowe jakosci:

decoder hidden state -> Linear(hidden_dim, 1) -> quality_logit

W treningu quality_logit jest uczony do przewidywania IoU pomiedzy dopasowana predykcja a GT. Dla niedopasowanych query target wynosi 0. Loss ma postac varifocal-like, czyli pozytywne query sa wazone jakoscia IoU, a negatywne query sa tlumione focal-style.

W inferencji finalny score ma postac:

final_score = sigmoid(class_logit) * sigmoid(quality_logit)

Cel tej zmiany jest waski i praktyczny: nie zwiekszac mocno modelu, tylko obnizac ranking boxow, ktore maja wysoki score klasy, ale slaba lokalizacje. Jest to zgodne z kierunkiem VarifocalNet/RT-DETR/D-FINE, gdzie ranking detekcji powinien uwzgledniac jakosc lokalizacji, a nie sama klasyfikacje.

Kompatybilnosc:

  • domyslnie use_quality_score_head=false, zeby stare checkpointy nadal sie ladowaly,
  • nowe eksperymenty vehicles3 wlaczaja use_quality_score_head=true.

Denoising

W modelu zaimplementowano contrastive denoising dla treningu:

  • noisy labels,
  • noisy boxes,
  • metadata dn_meta,
  • splitting outputs na czesc denoising i matching,
  • osobny loss dla denoising bez Hungarian matchingu.

To jest jeden z kluczowych elementow, ktory zblizyl pipeline do RT-DETRv3 i poprawil stabilnosc treningu.

Class reweighting w SetCriterion

Aby zaadresowac collapse rzadkich klas (np. bus to ~3.6% datasetu vehicles3), SetCriterion przyjmuje opcjonalne wagi per-klasa:

  • EasyRTDETRConfig.cls_class_weights: tuple[float, ...] | None,
  • SetCriterion(class_weights=...) rejestruje je jako buffer,
  • _varifocal_loss_with_logits mnozy element-wise weight tensor przez class_weights[None, None, :].

Wynik: positives i negatives dla klas rzadkich dostaja proporcjonalnie wieksza wage. Standardowe ustawienie to inverse-sqrt-frequency znormalizowane do mean = 1.0.

Dla vehicles3 wagi to [0.47 car, 1.93 bus, 0.60 truck]. Po wlaczeniu, bus AP50 wzrosl z 0.294 do 0.662 w 5 epokach (experiments.md sekcja 12).

Auxiliary O2M Head

Obecna treningowa galaz pomocnicza jest wzorowana na PP-YOLOE:

  • osobna galaz cls,
  • osobna galaz reg,
  • assignment typu ATSS -> TaskAligned,
  • Varifocal Loss,
  • GIoU,
  • DFL.

Wazne:

  • auxiliary head jest training-only,
  • inferencja publiczna nadal korzysta z glownej sciezki DETR,
  • to nie jest pelny port calego PPYOLOEHead.post_process().

Poprawka DFL

W tej galezi znaleziono krytyczny blad broadcastingu w DFL:

  • loss_dfl mial ksztalt [num_pos],
  • bbox_weight.unsqueeze(-1) mial ksztalt [num_pos, 1],
  • wynik byl broadcastowany do [num_pos, num_pos].

Poprawka usuwa unsqueeze(-1) i mnozy wektory element-wise. To obnizylo sztucznie zawyzony auxiliary DFL z okolo 293 do okolo 1.42 na probce diagnostycznej. Wyniki treningow sprzed tej poprawki nalezy traktowac ostroznie.

Relacja do D-FINE

Architektura projektu jest RT-DETR-like, ale nie jest pelnym portem D-FINE.

D-FINE wprowadza dodatkowe mechanizmy, m.in. fine-grained distribution refinement dla regresji boxow i self-distillation dla lokalizacji. W Easy-RT-DETR mamy auxiliary DFL i RT-DETR-like decoder, ale nie mamy jeszcze kompletnego odpowiednika FDR/GO-LSD. Dlatego porownanie do D-FINE nalezy opisywac jako inspiracje i kierunek rozwoju, a nie jako rownowazna implementacje.

Postprocess

Postprocess modelu obejmuje:

  • top-k selection,
  • score threshold,
  • NMS.

Po strojeniach praktyczne domyslne wartosci okazaly sie sensowne:

  • score_threshold = 0.18,
  • nms_threshold = 0.25.

To bylo potrzebne, bo we wczesniejszych wersjach model potrafil zwracac zduplikowane boxy.

Co nadal odbiega od referencji

Najwazniejsze braki wzgledem referencji RT-DETRv3:

  • brak pelnego portu wszystkich szczegolow PPYOLOEHead,
  • brak pelnej parity calego ekosystemu PaddleDet,
  • brak pelnego eksportu produkcyjnego, np. dopracowanego ONNX/inference backend,
  • brak kompatybilnosci starych checkpointow po wiekszych zmianach architektury,
  • brak szerokiego benchmarku na wiecej niz jednym lub dwoch datasetach.

Warstwa treningowa i eksperymentalna

Po refaktorze repo architektura modelu jest otoczona nowym wspolnym stackiem:

  • YAML configi eksperymentow,
  • solver,
  • builders danych,
  • optimizer + scheduler + warmup + EMA,
  • nowe CLI.

To nie zmienia samego forward pass modelu, ale istotnie zmienia sposob uruchamiania treningu i eksperymentow.