Jedi-teknik för att minska konvolutionella nätverk - beskärning

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Innan du igen är uppgiften att upptäcka föremål. Prioriteten är drifthastighet med acceptabel noggrannhet. Du tar YOLOv3-arkitekturen och vidareutbildar den. Noggrannheten (mAp75) är större än 0.95. Men körhastigheten är fortfarande låg. Skit.

Idag kommer vi att kringgå kvantisering. Och under snittet ska vi titta Modell beskärning — trimma redundanta delar av nätverket för att påskynda inferens utan förlust av noggrannhet. Det är tydligt var, hur mycket och hur man skär. Låt oss ta reda på hur du gör detta manuellt och var du kan automatisera det. I slutet finns ett förråd på keras.

Inledning

På min tidigare arbetsplats, Macroscop i Perm, fick jag en vana - att alltid övervaka exekveringstiden för algoritmer. Och kontrollera alltid nätverkets körtid genom ett lämplighetsfilter. Vanligtvis klarar inte den senaste produktionen detta filter, vilket ledde mig till beskärning.

Beskärning är ett gammalt ämne som diskuterades i Stanford föreläsningar under 2017. Huvudtanken är att minska storleken på det tränade nätverket utan att tappa exaktheten genom att ta bort olika noder. Det låter coolt, men jag hör sällan om användningen. Förmodligen finns det inte tillräckligt med implementeringar, det finns inga ryskspråkiga artiklar, eller helt enkelt anser alla att det beskär kunskap och förblir tysta.
Men låt oss ta isär det

En inblick i biologin

Jag älskar när Deep Learning tittar på idéer som kommer från biologin. De, precis som evolution, kan lita på (visste du att ReLU är väldigt lik funktion av neuronaktivering i hjärnan?)

Modellbeskärningsprocessen ligger också nära biologi. Nätverkets svar här kan jämföras med hjärnans plasticitet. Det finns ett par intressanta exempel i boken. Norman Doidge:

  1. Hjärnan hos en kvinna som föddes med bara en halva har programmerat om sig själv för att utföra funktionerna hos den saknade halvan.
  2. Killen sköt av den del av hans hjärna som ansvarar för synen. Med tiden tog andra delar av hjärnan över dessa funktioner. (vi försöker inte upprepa)

På samma sätt kan du klippa bort några av de svaga vecken från din modell. Som en sista utväg kommer de återstående buntarna att hjälpa till att ersätta de skurna.

Älskar du Transfer Learning eller lär du dig från grunden?

Alternativ nummer ett. Du använder Transfer Learning på Yolov3. Retina, Mask-RCNN eller U-Net. Men för det mesta behöver vi inte känna igen 80 objektklasser som i COCO. I min praktik är allt begränsat till årskurs 1-2. Man kan anta att arkitekturen för 80 klasser är överflödig här. Detta talar för att arkitekturen behöver göras mindre. Dessutom skulle jag vilja göra detta utan att förlora de befintliga förtränade vikterna.

Alternativ nummer två. Kanske har du mycket data och datorresurser, eller bara behöver en superanpassad arkitektur. spelar ingen roll. Men du lär dig nätverket från grunden. Det vanliga förfarandet är att titta på datastrukturen, välja en arkitektur som är EXCESSIG i kraft och skjuta upp avhopp från omskolning. Jag såg 0.6 avhopp, Karl.

I båda fallen kan nätverket minskas. Motiverad. Nu ska vi ta reda på vilken typ av beskärning av omskärelse

Allmän algoritm

Vi bestämde att vi kunde ta bort buntarna. Det ser ganska enkelt ut:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Att ta bort eventuell faltning är stressande för nätverket, vilket vanligtvis leder till en viss ökning av antalet fel. Å ena sidan är denna ökning av fel en indikator på hur korrekt vi tar bort faltningar (till exempel en stor ökning indikerar att vi gör något fel). Men en liten ökning är helt acceptabelt och elimineras ofta av efterföljande lätt tilläggsträning med en liten LR. Lägg till ytterligare ett träningssteg:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Nu måste vi ta reda på när vi vill stoppa vår Learning<->Pruning loop. Det kan finnas exotiska alternativ här när vi behöver minska nätet till en viss storlek och hastighet (till exempel för mobila enheter). Det vanligaste alternativet är dock att fortsätta cykeln tills felet blir högre än acceptabelt. Lägg till ett villkor:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Så algoritmen blir tydlig. Det återstår att ta reda på hur man bestämmer de raderade veckningarna.

Sök efter borttagna paket

Vi måste ta bort några veck. Att rusa framåt och "skjuta" vem som helst är en dålig idé, även om det kommer att fungera. Men eftersom du har ett huvud kan du tänka och försöka välja "svaga" veck för borttagning. Det finns flera alternativ:

  1. Minsta L1-mått eller low_magnitude_beskärning. Tanken att veck med små vikter inte bidrar till det slutliga beslutet
  2. Minsta L1-mått med hänsyn till medelvärde och standardavvikelse. Vi kompletterar med en bedömning av fördelningens karaktär.
  3. Maskera veck och exkludera de som minst påverkar den slutliga noggrannheten. Mer exakt bestämning av obetydliga veck, men mycket tidskrävande och resurskrävande.
  4. Andra

Vart och ett av alternativen har rätt till liv och sina egna implementeringsfunktioner. Här överväger vi alternativet med det minsta L1-måttet

Manuell process för YOLOv3

Den ursprungliga arkitekturen innehåller restblock. Men oavsett hur coola de är för djupa nätverk, kommer de att hindra oss något. Svårigheten är att du inte kan ta bort avstämningar med olika index i dessa lager:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Låt oss därför välja lager från vilka vi fritt kan ta bort avstämningar:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Låt oss nu bygga en arbetscykel:

  1. Laddar upp aktiveringar
  2. Funderar på hur mycket man ska skära
  3. Sluta
  4. Lärande 10 epoker med LR=1e-4
  5. Testning

Att lossa veck är användbart för att uppskatta hur mycket del vi kan ta bort vid ett visst steg. Exempel på lossning:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Vi ser att nästan överallt 5% av vecken har en mycket låg L1-norm och vi kan ta bort dem. Vid varje steg upprepades denna lossning och en bedömning gjordes av vilka lager och hur många som kunde skäras ut.

Hela processen slutfördes i fyra steg (nummer här och överallt för RTX 4 Super):

Steg mAp75 Antal parametrar, miljoner Nätverksstorlek, mb Från initial, % Körtid, fröken Omskärelsetillstånd
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% av alla
2 0.9625 50 197 83 168 5% av alla
3 0.9633 39 155 64 155 15 % för lager med 400+ veck
4 0.9555 31 124 51 146 10 % för lager med 100+ veck

En positiv effekt lades till i steg 2 - batchstorlek 4 passade in i minnet, vilket avsevärt påskyndade processen med ytterligare träning.
Vid steg 4 stoppades processen pga inte ens långvarig tilläggsutbildning höjde mAp75 till gamla värden.
Som ett resultat lyckades vi påskynda slutsatsen med 15%, minska storleken med 35% och inte förlora exakt.

Automation för enklare arkitekturer

För enklare nätverksarkitekturer (utan villkorlig addering, konkaternerade och resterande block) är det fullt möjligt att fokusera på att bearbeta alla faltningslager och automatisera processen att klippa ut faltningar.

Jag implementerade det här alternativet här.
Det är enkelt: du behöver bara en förlustfunktion, en optimerare och batchgeneratorer:

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)

Om det behövs kan du ändra konfigurationsparametrarna:

{
    "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
}

Dessutom implementeras en begränsning baserad på standardavvikelsen. Målet är att begränsa den del som tas bort, exklusive veck med redan "tillräckliga" L1-mått:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Således tillåter vi dig att ta bort endast svaga faltningar från distributioner som liknar den högra och inte påverka borttagningen från distributioner som liknar den vänstra:

Jedi-teknik för att minska konvolutionella nätverk - beskärning

När fördelningen närmar sig normal kan pruning_standart_deviation_part-koefficienten väljas från:

Jedi-teknik för att minska konvolutionella nätverk - beskärning
Jag rekommenderar ett antagande om 2 sigma. Eller så kan du ignorera den här funktionen och lämna värdet < 1.0.

Utdata är ett diagram över nätverksstorlek, förlust och nätverkskörtid för hela testet, normaliserat till 1.0. Till exempel, här reducerades nätverksstorleken med nästan 2 gånger utan kvalitetsförlust (litet konvolutionellt nätverk med 100 XNUMX vikter):

Jedi-teknik för att minska konvolutionella nätverk - beskärning

Körhastigheten är föremål för normala fluktuationer och förblir praktiskt taget oförändrad. Det finns en förklaring till detta:

  1. Antalet faltningar ändras från bekvämt (32, 64, 128) till inte det mest bekväma för grafikkort - 27, 51, etc. Jag kan ha fel här, men troligen har det en effekt.
  2. Arkitekturen är inte bred, men konsekvent. Genom att minska bredden påverkar vi inte djupet. Således minskar vi belastningen, men ändrar inte hastigheten.

Därför uttrycktes förbättringen i en minskning av CUDA-belastningen under körningen med 20-30 %, men inte i en minskning av körtiden

Resultat av

Låt oss reflektera. Vi övervägde 2 alternativ för beskärning - för YOLOv3 (när du måste arbeta med händerna) och för nätverk med enklare arkitekturer. Det kan ses att i båda fallen är det möjligt att uppnå minskning av nätverksstorlek och snabbhet utan förlust av noggrannhet. Resultat:

  • Minska storleken
  • Accelerationskörning
  • Minska CUDA-belastningen
  • Som ett resultat, miljövänlighet (Vi optimerar den framtida användningen av datorresurser. Någonstans är man nöjd Greta Thunberg)

Appendix

  • Efter beskärningssteget kan du lägga till kvantisering (till exempel med TensorRT)
  • Tensorflow ger möjligheter för låg_magnitude_beskärning. Arbetar.
  • förvaret Jag vill utvecklas och hjälper gärna till

Källa: will.com

Lägg en kommentar