Technika Jedi pro redukci konvolučních sítí – prořezávání

Technika Jedi pro redukci konvolučních sítí – prořezávání

Před vámi je opět úkol detekce objektů. Priorita - rychlost práce s přijatelnou přesností. Vezmete architekturu YOLOv3 a trénujete ji dále. Přesnost (mAp75) je větší než 0.95. Ale rychlost běhu je stále nízká. Blbost.

Dnes kvantování obejdeme. A pod řezem, zvažte Modelové prořezávání - odříznutí nadbytečných částí sítě pro urychlení Inference bez ztráty přesnosti. Jasně – kde, kolik a jak řezat. Pojďme zjistit, jak to udělat ručně a kde můžete automatizovat. Na konci je úložiště na keras.

úvod

Na svém posledním působišti, Macroscop v Permu, jsem si osvojil jeden zvyk – vždy sledovat dobu provádění algoritmů. A doba provozu sítě by měla být vždy kontrolována pomocí filtru přiměřenosti. Obvykle nejmodernější ve výrobě tímto filtrem neprojde, což mě přivedlo k Pruningu.

Prořezávání je staré téma, o kterém se diskutovalo v Stanfordské přednášky v roce 2017. Hlavní myšlenkou je zmenšit velikost trénované sítě bez ztráty přesnosti odstraněním různých uzlů. Zní to dobře, ale málokdy slyším o jeho použití. Pravděpodobně není dostatek implementací, neexistují žádné články v ruštině, nebo prostě každý zvažuje know-how o prořezávání a mlčí.
Ale rozebrat

Pohled do biologie

Líbí se mi, když myšlenky pocházející z biologie nahlédnou do Deep Learning. Stejně jako evoluci jim lze věřit (věděli jste, že ReLU je velmi podobný aktivační funkce neuronů v mozku?)

Proces Model Pruning má také blízko k biologii. Reakci sítě zde lze přirovnat k plasticitě mozku. V knize je pár zajímavých příkladů. Norman Doidge:

  1. Mozek ženy, která se narodila pouze s jednou polovinou, se přeprogramoval tak, aby vykonával funkce chybějící poloviny
  2. Ten chlap mu ustřelil část mozku zodpovědnou za vidění. Postupem času tyto funkce převzaly jiné části mozku. (nesnažte se opakovat)

Takže z vašeho modelu můžete vystřihnout některé slabé konvoluce. V extrémních případech zbývající svazky pomohou nahradit řezané.

Milujete Transfer Learning nebo se učíte od nuly?

Možnost číslo jedna. Používáte Transfer Learning na Yolov3. Retina, Mask-RCNN nebo U-Net. Ale častěji než ne, nepotřebujeme rozpoznávat 80 tříd objektů jako v COCO. V mé praxi je vše omezeno na 1-2 lekce. Dá se předpokládat, že architektura pro 80 tříd je zde nadbytečná. Vzniká myšlenka, že architekturu je třeba zredukovat. Navíc bych to chtěl udělat, aniž bych ztratil stávající předtrénované váhy.

Možnost číslo dvě. Možná máte spoustu dat a výpočetních zdrojů, nebo jen potřebujete super zakázkovou architekturu. Na tom nezáleží. Ale vy se učíte síť od nuly. Obvyklé pořadí – podíváme se na datovou strukturu, vybereme NADMĚRNOU architekturu z hlediska výkonu a vytlačíme výpadky z rekvalifikací. Viděl jsem 0.6 výpadků, Carle.

V obou případech lze síť zredukovat. Povýšeno. Nyní pojďme zjistit, jaký druh obřízky prořezávání

Obecný algoritmus

Rozhodli jsme se, že můžeme odstranit konvoluce. Vypadá to velmi jednoduše:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Odstranění jakékoli konvoluce je pro síť stresující, což obvykle vede k určitému nárůstu chyb. Na jedné straně je tento nárůst chyb indikátorem toho, jak správně odstraňujeme konvoluce (např. velký nárůst naznačuje, že něco děláme špatně). Ale malé navýšení je celkem přijatelné a často se eliminuje následným lehkým přeškolením s malým LR. Přidání kroku rekvalifikace:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Nyní musíme zjistit, kdy chceme zastavit naši smyčku učení<->prořezávání. Zde mohou být exotické možnosti, když potřebujeme zmenšit síť na určitou velikost a rychlost běhu (například pro mobilní zařízení). Nejběžnější možností je však pokračovat ve smyčce, dokud nebude chyba vyšší, než je přijatelné. Přidání podmínky:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Algoritmus je tedy jasný. Zbývá vymyslet, jak určit konvoluce, které mají být odstraněny.

Hledání odstraněných svazků

Musíme odstranit některé konvoluce. Uhánět vpřed a „střílet“ na jakékoli je špatný nápad, i když to bude fungovat. Ale protože existuje hlava, můžete přemýšlet a pokusit se vybrat „slabé“ konvoluce pro smazání. Existuje několik možností:

  1. Nejnižší L1-measure nebo low_magnitude_pruning. Myšlenka, že konvoluce s malými hmotnostmi přispívají ke konečnému rozhodnutí jen málo
  2. Nejmenší míra L1 daná průměrem a standardní odchylkou. Doplňujeme odhadem charakteru distribuce.
  3. Maskování konvoluce a vyloučení těch, které mají nejmenší vliv na výslednou přesnost. Přesnější definice nevýznamných konvolucí, ale velmi náročná na čas a zdroje.
  4. Ostatní

Každá z možností má právo na život a jeho implementační prvky. Zde uvažujeme variantu s nejmenší mírou L1

Manuální proces pro YOLOv3

Původní architektura obsahuje zbytkové bloky. Ale bez ohledu na to, jak cool jsou pro hluboké sítě, trochu nám překážejí. Potíž je v tom, že v těchto vrstvách nemůžete odstranit odsouhlasení s různými indexy:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Proto vybíráme vrstvy, ze kterých můžeme libovolně odebírat odsouhlasení:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Nyní vytvoříme pracovní cyklus:

  1. Nahrávání aktivací
  2. Zjistit, kolik řezat
  3. Vystřihněte
  4. Učení 10 epoch s LR=1e-4
  5. Testování

Uvolnění souhrnů je užitečné k vyhodnocení toho, kolik můžeme v konkrétním kroku odstranit. Příklady nahrání:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Vidíme, že téměř všude má 5 % konvolucí velmi nízkou normu L1 a můžeme je odstranit. Na každém kroku se takové vykládání opakovalo a vyhodnocovalo se, které vrstvy a kolik lze řezat.

Celý proces se vešel do 4 kroků (zde a všude čísla pro RTX 2060 Super):

Krok mapa75 Počet parametrů, milion Velikost sítě, mb Z originálu, % Doba běhu, slečno Mezní stav
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5 % ze všech
2 0.9625 50 197 83 168 5 % ze všech
3 0.9633 39 155 64 155 15 % pro vrstvy s více než 400 svazky
4 0.9555 31 124 51 146 10 % pro vrstvy s více než 100 svazky

Ke kroku 2 byl přidán jeden pozitivní efekt - dávka velikosti 4 se dostala do paměti, což značně urychlilo proces dodatečného tréninku.
Ve 4. kroku byl proces zastaven, protože ani prodloužené dodatečné školení nezvedlo mAp75 na staré hodnoty.
V důsledku toho bylo možné urychlit inferenci na 15%, zmenšit velikost o 35% a neztratit přesnost.

Automatizace pro jednodušší architektury

Pro jednodušší síťové architektury (bez podmíněného přidávání, zřetězení a zbytkových bloků) je docela možné zaměřit se na zpracování všech konvolučních vrstev a automatizovat proces řezání konvolucí.

Tuto možnost jsem implementoval zde.
Je to jednoduché: máte pouze ztrátovou funkci, optimalizátor a dávkové generátory:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

V případě potřeby můžete změnit konfigurační parametry:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

Navíc je implementováno omezení založené na směrodatné odchylce. Cílem je omezit část odstraněných, s vyloučením konvolucí s již „dostatečnými“ mírami L1:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Umožňujeme tedy odstranit pouze slabé konvoluce z pravoúhlých distribucí a neovlivnit odstranění z levých distribucí:

Technika Jedi pro redukci konvolučních sítí – prořezávání

Když se distribuce blíží normálu, koeficient pruning_standart_deviation_part lze vybrat z:

Technika Jedi pro redukci konvolučních sítí – prořezávání
Doporučuji předpoklad 2 sigma. Nebo můžete tuto funkci ignorovat a ponechat hodnotu < 1.0.

Výstupem je graf velikosti sítě, ztráty a doby běhu sítě během celého testu, normalizovaný na 1.0. Například zde se velikost sítě zmenšila téměř 2krát bez ztráty kvality (malá konvoluční síť pro 100k závaží):

Technika Jedi pro redukci konvolučních sítí – prořezávání

Rychlost běhu podléhá běžným výkyvům a příliš se nezměnila. Existuje pro to vysvětlení:

  1. Počet závitů se mění z vhodných (32, 64, 128) na ne nejvhodnější pro grafické karty - 27, 51 atd. Tady se mohu mýlit, ale pravděpodobně ano.
  2. Architektura není široká, ale konzistentní. Zmenšením šířky se nedotýkáme hloubky. Tím snížíme zátěž, ale neměníme rychlost.

Zlepšení se tedy projevilo snížením zátěže CUDA během běhu o 20-30%, ale ne snížením doby běhu

Výsledky

Pojďme se zamyslet. Zvažovali jsme 2 možnosti prořezávání – pro YOLOv3 (když musíte pracovat rukama) a pro sítě s jednodušší architekturou. Je vidět, že v obou případech je možné dosáhnout zmenšení velikosti sítě a zrychlení bez ztráty přesnosti. Výsledek:

  • Zmenšení velikosti
  • Zrychlení běhu
  • Snížení zatížení CUDA
  • Výsledkem je šetrnost k životnímu prostředí (Optimalizujeme budoucí využití výpočetních zdrojů. Někde se člověk raduje Greta Thunbergová)

Příloha

  • Po kroku prořezávání můžete také vyladit kvantizaci (například pomocí TensorRT)
  • Tensorflow poskytuje zařízení pro low_magnitude_pruning. funguje.
  • úložiště Chci se rozvíjet a rád pomůžu

Zdroj: www.habr.com

Přidat komentář