Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Teie ees on jälle objektide tuvastamise ülesanne. Prioriteet - töö kiirus vastuvõetava täpsusega. Võtate YOLOv3 arhitektuuri ja treenite seda edasi. Täpsus (mAp75) on suurem kui 0.95. Kuid jooksukiirus on endiselt madal. Jama.

Täna läheme kvantiseerimisest mööda. Ja lõike all, kaaluge Mudeli pügamine - võrgu üleliigsete osade katkestamine, et kiirendada järelduste tegemist täpsust kaotamata. Selge – kus, kui palju ja kuidas lõigata. Mõelgem välja, kuidas seda käsitsi teha ja kus saab automatiseerida. Lõpus on hoidla kerasel.

Sissejuhatus

Viimases töökohas Macroscopis Permis omandasin ühe harjumuse – jälgida alati algoritmide täitmise aega. Ja võrgu tööaega tuleks alati kontrollida adekvaatsusfiltri kaudu. Tavaliselt tootmises olev tipptehnoloogia ei läbi seda filtrit, mis viis mind Pügamise juurde.

Pügamine on vana teema, mida arutati Stanfordi loengud aastal 2017. Põhiidee on vähendada koolitatud võrgu suurust täpsust kaotamata, eemaldades erinevaid sõlme. Kõlab lahedalt, aga kuulen selle kasutamisest harva. Tõenäoliselt pole rakendusi piisavalt, pole venekeelseid artikleid või lihtsalt kõik kaaluvad pügamisoskust ja vaikivad.
Aga lahti võtta

Pilk bioloogiasse

Mulle meeldib, kui bioloogiast pärinevad ideed uurivad süvaõpet. Neid, nagu ka evolutsiooni, saab usaldada (kas teadsite, et ReLU on väga sarnane aju neuronite aktiveerimise funktsioon?)

Mudeli pügamise protsess on samuti bioloogiale lähedane. Võrgu reaktsiooni saab siin võrrelda aju plastilisusega. Raamatus on paar huvitavat näidet. Norman Doidge:

  1. Ainult ühe poolega sündinud naise aju programmeeris end ümber, et täita puuduva poole funktsioone
  2. Mees tulistas oma aju nägemise eest vastutava osa maha. Aja jooksul võtsid need funktsioonid üle teised ajuosad. (ärge proovige korrata)

Nii et saate oma mudelist välja lõigata mõned nõrgad konvolutsioonid. Äärmuslikel juhtudel aitavad ülejäänud kimbud lõigatud kimbud asendada.

Kas teile meeldib ülekandeõpe või õpite nullist?

Variant number üks. Kasutate Yolov3-s ülekandeõpet. Retina, Mask-RCNN või U-Net. Kuid enamasti ei pea me tuvastama 80 objektiklassi nagu COCO-s. Minu praktikas piirdub kõik 1-2 klassiga. Võib oletada, et 80 klassi arhitektuur on siin üleliigne. Tekib mõte, et arhitektuuri on vaja vähendada. Pealegi tahaksin seda teha olemasolevaid eeltreenitud raskusi kaotamata.

Variant number kaks. Võib-olla on teil palju andmeid ja arvutusressursse või vajate lihtsalt ülikohandatud arhitektuuri. Vahet pole. Kuid te õpite võrku nullist. Tavaline järjekord - vaatame andmestruktuuri, valime võimsuse poolest ÜLILIIGSE arhitektuuri ja lükkame ümberõppest väljalangejaid. Ma nägin 0.6 väljalangejat, Carl.

Mõlemal juhul saab võrku vähendada. Edutati. Nüüd mõtleme välja, millist ümberlõikamist pügatakse

Üldine algoritm

Otsustasime, et saame konvolutsioonid eemaldada. See näeb välja väga lihtne:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Mis tahes keerdude eemaldamine on võrgu jaoks stressirohke, mis põhjustab tavaliselt vigade suurenemist. Ühest küljest näitab see vea suurenemine, kui õigesti me konvolutsioone eemaldame (näiteks näitab suur kasv, et teeme midagi valesti). Kuid väike tõus on üsna vastuvõetav ja sageli välistatakse selle hilisema kerge ümberõppega väikese LR-iga. Ümberõppeetapi lisamine:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Nüüd peame välja mõtlema, millal tahame oma õppimise<-> pügamistsükli peatada. Siin võib olla eksootilisi võimalusi, kui peame vähendama võrku teatud suuruse ja töökiiruseni (näiteks mobiilseadmete jaoks). Kõige tavalisem variant on aga tsükli jätkamine seni, kuni viga muutub vastuvõetavast suuremaks. Tingimuse lisamine:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Nii saab algoritm selgeks. Jääb veel välja mõelda, kuidas määrata eemaldatavad keerdud.

Eemaldatud kimpude leidmine

Peame eemaldama mõned keerdud. Ette tormamine ja ükskõik millise "tulistamine" on halb mõte, kuigi see toimib. Kuid kuna pea on olemas, võite mõelda ja proovida kustutamiseks valida "nõrgad" konvolutsioonid. Valikuid on mitu:

  1. Madalaim L1-mõõt või madal_suuruse_pügamine. Mõte, et väikese kaaluga keerdud aitavad lõplikule otsusele vähe kaasa
  2. Väikseim L1 mõõt, arvestades keskmist ja standardhälvet. Täiendame hinnanguga jaotuse olemuse kohta.
  3. Konvolutsioonide maskeerimine ja nende välistamine, millel on lõpptäpsusele kõige vähem mõju. Ebaoluliste keerdude täpsem definitsioon, kuid väga aja- ja ressursimahukas.
  4. Teised

Igal valikul on õigus elule ja selle rakendusfunktsioonid. Siin käsitleme väikseima L1-mõõduga varianti

Käsitsi protsess YOLOv3 jaoks

Algne arhitektuur sisaldab jääkplokke. Kuid hoolimata sellest, kui lahedad need sügavate võrkude jaoks on, segavad nad meid pisut. Raskus seisneb selles, et nendes kihtides ei saa kustutada erinevate indeksitega kooskõlastusi:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Seetõttu valime kihid, millest saame kooskõlastusi vabalt eemaldada:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Nüüd koostame töötsükli:

  1. Aktiveeringute üleslaadimine
  2. Arutab, kui palju lõigata
  3. Lõika välja
  4. 10 epohhi õppimine LR=1e-4
  5. Testimine

Kogumite mahalaadimine on kasulik selleks, et hinnata, kui palju saame konkreetse etapi käigus eemaldada. Näitete üleslaadimine:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Näeme, et peaaegu kõikjal on 5% konvolutsioonidest väga madal L1-norm ja me saame need eemaldada. Igal etapil korrati sellist mahalaadimist ja hinnati, milliseid kihte ja kui palju saab lõigata.

Kogu protsess mahub 4 sammu (siin ja kõikjal RTX 2060 Super numbrid):

Samm kaart75 Parameetrite arv, miljon Võrgu suurus, mb Originaalist, % Tööaeg, ms Lõikeseisund
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% kõigist
2 0.9625 50 197 83 168 5% kõigist
3 0.9633 39 155 64 155 15% kihtide puhul, millel on üle 400 kimbu
4 0.9555 31 124 51 146 10% kihtide puhul, millel on üle 100 kimbu

2. sammule lisati üks positiivne efekt - partii suurus 4 sai mällu, mis kiirendas oluliselt lisatreeningu protsessi.
4. etapil protsess peatati, kuna isegi pikaajaline lisatreening ei tõstnud mAp75 vanadele väärtustele.
Selle tulemusel oli võimalik järeldamist kiirendada 15%, vähendage suurust 35% ja ei kaota täpsust.

Automatiseerimine lihtsamate arhitektuuride jaoks

Lihtsamate võrguarhitektuuride puhul (ilma tingimusliku lisamise, konkaternatsiooni ja jääkplokkideta) on täiesti võimalik keskenduda kõigi konvolutsioonikihtide töötlemisele ja automatiseerida konvolutsioonide lõikamise protsessi.

Rakendasin selle võimaluse siin.
See on lihtne: teil on ainult kadufunktsioon, optimeerija ja partiigeneraatorid:

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)

Vajadusel saate muuta konfiguratsiooni parameetreid:

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

Lisaks rakendatakse standardhälbel põhinev piirang. Eesmärk on piirata eemaldatud osa, jättes välja keerdud juba "piisavate" L1-meetmetega:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Seega lubame parempoolsetest jaotustest eemaldada ainult nõrgad konvolutsioonid ja mitte mõjutada vasakpoolsete jaotuste eemaldamist:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Kui jaotus läheneb normaalsele, saab pruning_standart_deviation_part koefitsiendi valida järgmiste hulgast:

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine
Soovitan 2 sigma oletust. Või võite seda funktsiooni ignoreerida, jättes väärtuseks < 1.0.

Väljund on graafik võrgu suuruse, kaotuse ja võrgu tööaja kohta kogu testi jooksul, normaliseeritud väärtusele 1.0. Näiteks siin on võrgu suurust vähendatud peaaegu 2 korda ilma kvaliteeti kaotamata (väike konvolutsioonivõrk 100 XNUMX kaalu jaoks):

Jedi tehnika konvolutsiooniliste võrkude vähendamiseks – pügamine

Jooksukiirus on tavapäraste kõikumiste all ja pole palju muutunud. Sellele on seletus:

  1. Konvolutsioonide arv muutub mugavast (32, 64, 128) videokaartide jaoks mitte kõige mugavamaks - 27, 51 jne. Ma võin siin eksida, kuid ilmselt see nii on.
  2. Arhitektuur ei ole lai, kuid ühtlane. Laiust vähendades me sügavust ei puuduta. Seega vähendame koormust, kuid ei muuda kiirust.

Seetõttu väljendus paranemine CUDA koormuse vähenemises jooksu ajal 20-30%, kuid mitte jooksuaja vähenemises

Tulemused

Mõtiskleme. Kaalusime 2 kärpimisvõimalust - YOLOv3 jaoks (kui peate oma kätega töötama) ja lihtsama arhitektuuriga võrkude jaoks. On näha, et mõlemal juhul on võimalik saavutada võrgu suuruse vähendamine ja kiirendus ilma täpsust kaotamata. Tulemused:

  • Suuruse vähendamine
  • Jooksu kiirendus
  • CUDA koormuse vähendamine
  • Selle tulemusena keskkonnasõbralikkus (Optimeerime arvutusressursside edaspidist kasutamist. Kuskil rõõmustatakse Greta Thunberg)

Lisa

  • Pärast pügamisetappi saate ka kvantiseerimist muuta (näiteks TensorRT-ga)
  • Tensorflow pakub võimalusi madala_suuruse_pügamine. Töötab.
  • hoidla Tahan areneda ja aitan hea meelega

Allikas: www.habr.com

Lisa kommentaar