7.12. Post-procesory

Detekční síť nevypouští rámečky. Vypouští jeden nebo více tenzorů, jejichž rozložení závisí na architektuře, na které byl model trénován – 2D tenzor kandidátních predikcí pro detektor z rodiny YOLO, dvojici tenzorů (boxes, scores) pro detektor MediaPipe, plochý seznam souřadnic klíčových bodů pro síť odhadu pózy. Aplikace nedokáže žádný z nich číst přímo; to, co chce – seznam rámečků, seznam klíčových bodů, rozpis podle tříd – musí být z hrubého tenzoru dekódováno.

Tímto dekodérem je post-procesor. Modul ml.postprocessing je seskupuje podle zdrojového ekosystému.

7.12.1. Darknet

ml.postprocessing.darknet dekóduje modely z původní éry YOLO. YOLO v2 zavedl myšlenky mřížky a kotvy, které většina pozdějších detektorů v nějaké podobě zdědila, takže rozložení v2 je nejčistším výchozím bodem.

YOLO v2 začíná rozdělením vstupního obrazu na hrubou mřížku – rozložení 13 × 13 pro kanonický 416pixelový vstup, menší pro menší modely – a trénuje síť tak, aby každá buňka mřížky byla zodpovědná za detekci jakéhokoli objektu, jehož střed do ní spadá. Prostorové rozložení výstupního tenzoru zrcadlí rozložení vstupu: jedna pozice ve výstupu na každou buňku v obraze.

V každé buňce mřížky síť nepredikuje rámeček z ničeho. Vybírá z několika předem zvolených referenčních tvarů zvaných kotvy – pevných dvojic (width, height) odvozených offline shlukováním velikostí rámečků v trénovací sadě tak, aby pokrývaly typické objekty, které má model očekávat. Úkolem sítě v každé buňce je predikovat pro každou kotvu malý posun středu rámečku v rámci buňky, měřítko šířky a výšky kotvy, skóre objektnosti (pravděpodobnost, že tam vůbec něco je) a vektor pravděpodobností podle tříd. Mřížka 13 × 13 s výchozími 5 kotvami a 20 třídami tedy vypouští na jednu inferenci 13 * 13 * 5 * (4 + 1 + 20) = 21,125 čísel.

YoloV2 toto rozložení dekóduje: prochází buňky, aplikuje posuny a měřítka každé kotvy k získání absolutních souřadnic rámečku, kombinuje objektnost s pravděpodobností třídy do skóre podle tříd, prahuje a posílá přeživší do NMS. Třída přijímá argument konstruktoru anchors=, byl-li model trénován vůči vlastní tabulce kotev, jinak se vrací k vestavěné výchozí hodnotě. Varianty vyladěné pro konkrétní sady tříd jsou dodávány ve stejném submodulu.

7.12.2. Ultralytics

ml.postprocessing.ultralytics dekóduje novější generace YOLO. YoloV8 čte výstup uspořádaný po sloupcích, kde každý sloupec je jedna predikce kotvy obsahující souřadnice rámečku a vektor skóre podle tříd – kanál objektnosti, který nesly dřívější výstupy YOLO, byl ve v8 vypuštěn a skóre tříd stojí samostatně. Průchod YOLOv8 provádí dekódováním tenzor po tenzoru. Starší verze z éry Ultralytics jsou dodávány ve stejném submodulu pro modely trénované vůči jejich rozložením.

7.12.3. MediaPipe

ml.postprocessing.mediapipe dekóduje lehkou rodinu modelů Google pro běh přímo na zařízení. BlazeFace je detektor tváří popsaný v hello-blazeface: rychlý detektor založený na kotvách, který vypouští rámečky a šest souřadnic význačných bodů na tvář, vracené jako n-tice (box, score, keypoints) s význačnými body připojenými ke každému rámečku, nikoli jako samostatný výstupní seznam. Modely pro detekci rukou, význačných bodů a pózy ze stejné rodiny jsou dodávány spolu s ním a řídí se stejným návratovým tvarem s připojenými klíčovými body.

7.12.4. Výběr jednoho

Správný post-procesor je dán architekturou, na které byl model trénován, nikoli tím, co chce aplikace. .tflite typu YOLOv8 se správně dekóduje pouze přes YoloV8; .tflite typu BlazeFace pouze přes BlazeFace. Výběr post-procesoru je součástí výběru modelu. Pokud architektura modelu není zastoupena dodávaným post-procesorem, napsat vlastní je přímočaré.

Výjimkou jsou klasifikační sítě. Jejich jediný výstupní tenzor je už tím, co aplikace chce – seznamem skóre podle tříd – a žádný post-procesor není potřeba. Načtení modelu bez postprocess= a čtení výsledku predikce jako plochého ndarray je správná cesta, jak pokryl tenzorový vstup/výstup.