Jedi technika a konvolúciós hálózatok csökkentésére - metszés
Ön előtt ismét a tárgyak észlelésének feladata. A prioritás az elfogadható pontosságú működés sebessége. Előveszi a YOLOv3 architektúrát, és továbbképzi. A pontosság (mAp75) nagyobb, mint 0.95. De a futási sebesség még mindig alacsony. Szar.
Ma megkerüljük a kvantálást. És a vágás alatt megnézzük Modellmetszés — a hálózat redundáns részeinek levágása a következtetések felgyorsítása érdekében a pontosság elvesztése nélkül. Egyértelmű, hogy hol, mennyit és hogyan kell vágni. Nézzük meg, hogyan kell ezt manuálisan megtenni, és hol automatizálhatja. A végén van egy adattár a kerason.
Bevezetés
Előző munkahelyemen, a permi Macroscopnál egy szokásra tettem szert: mindig figyelni kell az algoritmusok végrehajtási idejét. És mindig ellenőrizze a hálózati futásidőt egy megfelelőségi szűrőn keresztül. Általában a legmodernebb gyártás nem megy át ezen a szűrőn, ami a Metszéshez vezetett.
A metszés egy régi téma, amiről szó volt Stanfordi előadások 2017-ben. A fő ötlet a betanított hálózat méretének csökkentése a pontosság elvesztése nélkül a különböző csomópontok eltávolításával. Jól hangzik, de ritkán hallok a használatáról. Valószínűleg nincs elég megvalósítás, nincsenek orosz nyelvű cikkek, vagy egyszerűen mindenki a know-how-t metssze, és hallgat.
De szedjük szét
Bepillantás a biológiába
Imádom, amikor a Deep Learning a biológiából származó ötleteket vizsgálja. Az evolúcióhoz hasonlóan bennük is meg lehet bízni (tudtad, hogy a ReLU nagyon hasonlít a neuronaktiválás funkciója az agyban?)
A Modellmetszés folyamata szintén közel áll a biológiához. A hálózat válasza itt az agy plaszticitásához hasonlítható. Van egy-két érdekes példa a könyvben. Norman Doidge:
Egy olyan nő agya, aki csak az egyik felével született, átprogramozta magát a hiányzó fél funkcióinak ellátására.
A srác lelőtte agyának a látásért felelős részét. Idővel az agy más részei átvették ezeket a funkciókat. (nem próbáljuk megismételni)
Hasonlóképpen, kivághat néhány gyenge konvolúciót a modellből. Végső megoldásként a megmaradt kötegek segítenek pótolni a vágottakat.
Szereted a transzfertanulást, vagy a semmiből tanulsz?
Első számú lehetőség. Ön a Transfer Learning szolgáltatást használja a Yolov3-on. Retina, Mask-RCNN vagy U-Net. De legtöbbször nem kell 80 objektumosztályt felismernünk, mint a COCO-ban. Az én gyakorlatomban minden 1-2 évfolyamra korlátozódik. Feltételezhető, hogy a 80 osztály architektúrája itt redundáns. Ez arra utal, hogy az architektúrát kisebbre kell tenni. Sőt, szeretném ezt megtenni anélkül, hogy elveszíteném a meglévő előre edzett súlyokat.
Második lehetőség. Lehet, hogy sok adattal és számítási erőforrással rendelkezik, vagy egyszerűen csak szuper-egyéni architektúrára van szüksége. Nem számít. De te a nulláról tanulod a hálózatot. A szokásos eljárás az adatstruktúra megvizsgálása, egy TÚLÓZOTT teljesítményű architektúra kiválasztása, és az átképzésből kiesők kiszorítása. 0.6 kiesőt láttam, Karl.
Mindkét esetben csökkenthető a hálózat. Motivált. Most pedig nézzük meg, milyen a körülmetélési metszés
Általános algoritmus
Úgy döntöttünk, hogy eltávolíthatjuk a kötegeket. Elég egyszerűnek tűnik:
Bármilyen konvolúció eltávolítása megterhelő a hálózat számára, ami általában a hibák növekedéséhez vezet. Ez a hibanövekedés egyrészt azt jelzi, hogy mennyire helyesen távolítjuk el a konvolúciókat (például a nagy növekedés azt jelzi, hogy valamit rosszul csinálunk). De egy kis növekedés teljesen elfogadható, és gyakran kiküszöbölhető egy kis LR-vel végzett könnyű kiegészítő edzéssel. Adjon hozzá egy további képzési lépést:
Most ki kell találnunk, mikor akarjuk leállítani a Tanulási<->metszés hurkot. Egzotikus lehetőségek adódhatnak itt, amikor egy bizonyos méretre és sebességre kell csökkentenünk a hálózatot (például mobileszközök esetén). A legáltalánosabb lehetőség azonban az, hogy a ciklust addig folytatjuk, amíg a hiba az elfogadhatónál magasabb lesz. Feltétel hozzáadása:
Így az algoritmus világossá válik. Továbbra is ki kell találni, hogyan határozható meg a törölt konvolúciók.
Törölt csomagok keresése
El kell távolítanunk néhány konvolúciót. Előresietni és bárkit „lelőni” rossz ötlet, bár működni fog. De mivel van feje, gondolkodhat, és megpróbálhatja kiválasztani a „gyenge” fordulatokat az eltávolításhoz. Több lehetőség is van:
Mindegyik lehetőségnek megvan az élethez való joga és saját megvalósítási jellemzői. Itt a legkisebb L1-mértékkel rendelkező lehetőséget vesszük figyelembe
Kézi folyamat a YOLOv3-hoz
Az eredeti architektúra maradék blokkokat tartalmaz. De bármennyire is jók a mély hálózatokhoz, valamennyire akadályoznak bennünket. A nehézség az, hogy ezekben a rétegekben nem törölheti a különböző indexekkel rendelkező egyeztetéseket:
Ezért válasszunk olyan rétegeket, amelyekből szabadon törölhetjük az egyeztetéseket:
Most építsünk fel egy munkaciklust:
Aktiválások feltöltése
Kitalálni, mennyit kell vágni
Elég már
10 korszak tanulása LR=1e-4 mellett
Tesztelés
A konvolúciók kirakodása hasznos annak becslésére, hogy egy bizonyos lépésnél mekkora részt tudunk eltávolítani. Példák a kirakodásra:
Azt látjuk, hogy szinte mindenhol a konvolúciók 5%-ának nagyon alacsony az L1-normája, és ezeket el tudjuk távolítani. Minden lépésnél megismételték ezt a kirakodást, és felmérték, hogy melyik réteget és hányat lehet kivágni.
Az egész folyamat 4 lépésben zajlott (a számok itt és mindenhol az RTX 2060 Super esetében):
Lépés
mAp75
Paraméterek száma, millió
Hálózat mérete, mb
Kezdettől, %
Futási idő, ms
Körülmetélés állapota
0
0.9656
60
241
100
180
-
1
0.9622
55
218
91
175
az összes 5%-a
2
0.9625
50
197
83
168
az összes 5%-a
3
0.9633
39
155
64
155
15% a 400+ konvolúciójú rétegeknél
4
0.9555
31
124
51
146
10% a 100+ konvolúciójú rétegeknél
Egy pozitív hatást adtunk a 2. lépéshez - a 4-es kötegméret beilleszkedett a memóriába, ami nagymértékben felgyorsította a további képzés folyamatát.
A 4. lépésnél a folyamat leállt, mert még a hosszú távú kiegészítő edzés sem emelte az mAp75-öt a régi értékekre.
Ennek eredményeként sikerült felgyorsítani a következtetést azáltal 15%, csökkentse a méretet 35% és nem veszít pontosan.
Automatizálás az egyszerűbb architektúrákhoz
Egyszerűbb hálózati architektúrák esetén (feltételes összeadás, összefűzés és maradék blokkok nélkül) teljesen lehetséges az összes konvolúciós réteg feldolgozására összpontosítani, és automatizálni a konvolúciók kivágásának folyamatát.
Ezt a lehetőséget megvalósítottam itt.
Egyszerű: csak veszteségfüggvényre, optimalizálóra és köteggenerátorokra van szüksége:
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)
Ha szükséges, módosíthatja a konfigurációs paramétereket:
{
"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
}
Ezenkívül a standard eltérésen alapuló korlátozást alkalmaznak. A cél az eltávolított rész korlátozása, kizárva a már „elegendő” L1 mértékkel rendelkező konvolúciókat:
Így lehetővé tesszük, hogy a jobb oldalihoz hasonló disztribúciókból csak gyenge konvolúciókat távolítson el, és nem befolyásolja a bal oldalihoz hasonló eloszlások eltávolítását:
Amikor az eloszlás megközelíti a normált, a pruning_standart_deviation_part együttható a következők közül választható ki:
2 szigma feltételezését javaslom. Vagy figyelmen kívül hagyhatja ezt a funkciót, és az értéket <1.0-nál hagyja.
A kimenet a hálózat méretét, veszteségét és hálózati futási idejét ábrázoló grafikon a teljes tesztre vonatkozóan, 1.0-ra normalizálva. Például itt a hálózat mérete majdnem kétszeresére csökkent minőségromlás nélkül (kis konvolúciós hálózat 2 ezer súllyal):
A futási sebesség normál ingadozásoknak van kitéve, és gyakorlatilag változatlan marad. Ennek van magyarázata:
A konvolúciók száma kényelmesről (32, 64, 128) a videokártyák számára nem legkényelmesebbre változik - 27, 51 stb. Lehet, hogy tévedek, de valószínűleg van hatása.
Az architektúra nem széles, de következetes. A szélesség csökkentésével a mélységet nem befolyásoljuk. Így csökkentjük a terhelést, de nem változtatunk a sebességen.
Ezért a javulás a futás közbeni CUDA terhelés 20-30%-os csökkenésében nyilvánult meg, de nem a futási idő csökkenésében
Eredményei
Gondolkodjunk el. A metszés két lehetőségét mérlegeltük - a YOLOv2-hoz (amikor kézzel kell dolgoznia) és az egyszerűbb architektúrájú hálózatokhoz. Látható, hogy mindkét esetben lehetséges a hálózat méretének csökkentése és gyorsítása a pontosság elvesztése nélkül. Eredmények:
Méretének csökkentése
Gyorsulási futás
A CUDA terhelés csökkentése
Ennek eredményeként a környezetbarátság (Optimalizáljuk a számítási erőforrások jövőbeni felhasználását. Valahol az ember boldog Greta Thunberg)
Függelék
A metszés lépése után kvantálást adhat hozzá (például a TensorRT-vel)