
Para ty sërish një detyrë për detektimin e objekteve. Prioriteti është shpejtësia e operimit me saktësi të pranueshme. Merr arkitekturën YOLOv3 dhe vazhdoje trajnimin. Saktësia (mAp75) është më shumë se 0.95. Por shpejtësia e ekzekutimit ende mbetet e ulët. Damn.
Sot do ta kalojmĂ« kualifikimin. NĂ«n titullin do tĂ« shqyrtojmĂ« Model Pruning â prerja e pjesĂ«ve tĂ« tepĂ«rta tĂ« rrjetit pĂ«r tĂ« pĂ«rshpejtuar InferencĂ«n pa humbur saktĂ«sinĂ«. PĂ«rshtatshĂ«m â nga ku, sa dhe si mund tĂ« priten. Do tĂ« shqyrtojmĂ« si ta bĂ«jmĂ« kĂ«tĂ« manualisht dhe ku mund tĂ« automatizohet. NĂ« fund â njĂ« depozitĂ« nĂ« keras.
Hyrje
NĂ« punĂ«n time tĂ« kaluar, nĂ« Macroscopin e Permit, kam fituar njĂ« zakon â gjithmonĂ« tĂ« monitoroj kohĂ«n e ekzekutimit tĂ« algoritmeve. Dhe koha e ekzekutimit tĂ« rrjeteve gjithmonĂ« duhet tĂ« kontrollohet pĂ«rmes filtrit tĂ« pĂ«rshtatshmĂ«risĂ«. Zakonisht, state-of-the-art nĂ« prodhim nuk kalojnĂ« kĂ«tĂ« filter, qĂ« mĂ« ka çuar te Pruning.
Pruning Ă«shtĂ« njĂ« temĂ« e vjetĂ«r, e cila u diskutua nĂ« nĂ« vitin 2017. Ideja kryesore â reduktimi i madhĂ«sisĂ« sĂ« rrjetit tĂ« trajnuar pa humbur saktĂ«sinĂ« pĂ«rmes heqjes sĂ« nodeve tĂ« ndryshme. DĂ«gjohet bukur, por rrallĂ« dĂ«gjoj pĂ«r aplikimin e tij. Ndoshta mungojnĂ« implementimet, nuk ka artikuj nĂ« gjuhĂ«n ruse ose thjesht tĂ« gjithĂ« mendojnĂ« se pruning Ă«shtĂ« njĂ« know-how dhe heshtin.
Por le të fillojmë.
Një shikim në biologji
Më pëlqen kur në Deep Learning hyjnë ide nga biologia. Ato, si dhe evolucioni, janë të besueshme (dhe a e dinte se ReLU është shumë e ngjashme me ?)
Procesi i Model Pruning është gjithashtu i ngjashëm me biolgjinë. Reagimi i rrjetit këtu mund të krahasohet me plastikën e trurit. Disa shembuj interesantë janë në librin :
- Tru i një gruaje që ka pasur vetëm një gjysmë që nga lindja, e ka rikrijuar veten për të kryer funksionet e gjysmës së munguar.
- Një djalë përjashtoi pjesën e trurit që përgjigjej për shikimin. Me kalimin e kohës, pjesë të tjera të trurit morën përsipër këto funksione. (nuk po përpiqemi ta përsërisim)
Ashtu si nga modeli juaj mund të priten disa konvolucione të dobëta. Në rastin më të keq, konvolucionet e mbetura do të ndihmojnë për të zëvendësuar ato të prera.
Doni Transfer Learning apo po mësoni nga fillimi?
Opsioni numër një. Po përdorni Transfer Learning në Yolov3. Retina, Mask-RCNN ose U-Net. Por shpesh na nevojitet të njohim 80 klasa objektesh, si në COCO. Në praktikën time, gjithçka është e kufizuar në 1-2 klasa. Mund të supozohet se arkitektura për 80 klasa është e tepërt këtu. E mendoj se arkitektura duhet të zvogëlohet. Për më tepër, dëshirojmë ta bëjmë këtë pa humbur pesha të paratanuara që kemi.
Opsioni numĂ«r dy. Ndoshta keni shumĂ« tĂ« dhĂ«na dhe burime llogaritĂ«se ose thjesht keni nevojĂ« pĂ«r njĂ« arkitekturĂ« super tĂ« personalizuar. Nuk ka rĂ«ndĂ«si. Por po e mĂ«soni rrjetin nga fillimi. Renditja e zakonshme â shikojmĂ« strukturĂ«n e tĂ« dhĂ«nave, pĂ«rzgjedhim njĂ« arkitekturĂ« TEPĂR KOHA dhe shtojmĂ« dropaout pĂ«r tĂ« parandaluar mbipĂ«rgatitjen. Kam parĂ« dropaout 0.6, Karl.
Në të dyja rastet, rrjeti mund të zvogëlohet. Të stimuluar. Tani shkojmë të mësojmë se çfarë është pruning.
Algoritmi i përgjithshëm
Ne vendosëm se mund të hiqnim konvolucionet. Kjo duket shumë e thjeshtë:

Heqja e çdo konvolucioni është një stres për rrjetin, që zakonisht çon në rritjen e ndonjë gabimi. Nga njëra anë, kjo rritje gabimi është një tregues se sa saktësisht po heqim konvolucionet (për shembull, një rritje e madhe tregon se po bëjmë diçka të gabuar). Por një rritje e vogël është plotësisht e pranueshme dhe shpesh eliminohet nga provimi më i lehtë i mëvonshëm me një LR të vogël. Shtojmë hapin e mësimit:

Tani duhet tĂ« kuptojmĂ« se kur duam tĂ« ndalim ciklin tonĂ« LearningPruning. KĂ«tu mund tĂ« ketĂ« variante ekzotike, kur na nevojitet tĂ« zvogĂ«lojmĂ« rrjetin nĂ« njĂ« madhĂ«si dhe shpejtĂ«si tĂ« caktuar (pĂ«r shembull, pĂ«r pajisje mobile). MegjithatĂ«, varianti mĂ« i zakonshĂ«m â Ă«shtĂ« vazhdimi i ciklit derisa gabimi tĂ« bĂ«het mĂ« i lartĂ« se e lejuara. ShtojmĂ« kushtin:

Pra, algoritmi bëhet i qartë. Mbetej të shqyrtonim se si të përcaktojmë konvolucionet që do të hiqen.
Kërkimi i konvolucionëve për t'u hequr
Na nevojitet të heqim disa konvolucione. Të veprosh në mënyrë të drejtpërdrejtë dhe të "goditësh" çdo konvolucion është një ide e keqe, edhe pse do të funksionojë. Por përqendrohuni dhe përpiquni të identifikoni konvolucionet "e dobëta" për t'u hequr. Ka disa opcione:
- . Ideja është se konvolucionet me vlera të vogla peshe, kontribuojnë pak në vendimmarrjen përfundimtare.
- Masa më e vogël L1 duke marrë parasysh mesataren dhe devijimin standard. Plotësojmë me vlerësimin e natyrës së shpërndarjes.
- . Përcaktim më të saktë të konvolucionve të dobëta, por shumë kërkon kohë dhe burime.
- TĂ« tjera
Ădo variant ka tĂ« drejtĂ« pĂ«r jetĂ«n dhe karakteristikat e tij tĂ« zbatimit. KĂ«tu do tĂ« shqyrtojmĂ« variantin me masĂ«n mĂ« tĂ« vogĂ«l L1.
Procesi manual për YOLOv3
Arkitektura origjinale përmban blloqe të mbetura. Por sa madhështore ishin ato për rrjetet e thella, ato do na pengonin disi. Problemi është se nuk mund të fshihen verifikimet me indekse të ndryshme në këto nivele:

Prandaj, do të ndajmë nivelet nga të cilat mund të fshijmë lirshëm verifikimet:

Tani do të ndërtojmë një cikël pune:
- Shkarkojmë aktivizimet
- Vlerësojmë sa mund të presim
- Presim
- Mësojmë për 10 epoka me LR=1e-4
- Testojmë
Shkarkimi i konvolucioneve është i dobishëm për të vlerësuar se sa mund të fshihet në një hap të caktuar. Shembujt e shkarkimit:

Vërejmë se pothuajse kudo 5% e konvolucioneve kanë një normë të ulët L1 dhe ne mund t'i fshijmë ato. Në çdo hap, një shkarkim i tillë është përsëritur dhe është bërë vlerësimi se nga cilat nivele dhe sa mund të presim.
I gjithë procesi është realizuar në 4 hapa (numrat këtu dhe kudo janë për RTX 2060 Super):
| Hapi | mAp75 | Numri i parametrave, mln | Madhësia e rrjetit, mb | Nga origjinali, % | Koha e ekzekutimit, ms | Kushti i prerjes |
|---|---|---|---|---|---|---|
| 0 | 0.9656 | 60 | 241 | 100 | 180 | â |
| 1 | 0.9622 | 55 | 218 | 91 | 175 | 5% e të gjithave |
| 2 | 0.9625 | 50 | 197 | 83 | 168 | 5% e të gjithave |
| 3 | 0.9633 | 39 | 155 | 64 | 155 | 15% për nivelet me 400+ konvolucione |
| 4 | 0.9555 | 31 | 124 | 51 | 146 | 10% për nivelet me 100+ konvolucione |
Në hapin 2 u shtua një efekt pozitiv - u ndikua nga madhësia e grupit 4, që e përshpejtoi procesin e rinovimit.
Në hapin 4, procesi u ndal, pasi madje edhe stërvitja e gjatë nuk e çoi mAp75 deri në vlerat e mëparshme.
Rezultati ishte përshpejtimi i inferencës me 15%, zvogëlimi i madhësisë me 35% dhe pa humbur saktësinë.
Automatizimi për arkitekturat më të thjeshta
Për arkitekturat më të thjeshta të rrjeteve (pa blloqe kushtore add, concatenate dhe residual), është plotësisht e mundur të orientoheni nga përpunimi i të gjitha konvolucioneve dhe të automatizoni procesin e prerjes së konvolucioneve.
Një variant të tillë e kam realizuar .
E gjithë kjo është e thjeshtë: ju nevojitet vetëm funksioni i humbjes, optimizatori dhe gjeneratorët e grupit:
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)Nëse nevojitet, mund të ndryshoni parametrat e konfigurimeve:
{
"input_model_path": "model.h5",
"output_model_path": "model_pruned.h5",
"finetuning_epochs": 10, # numri i epokave për stërvitje midis hapave të prerjes
"stop_loss": 0.1, # humbja për të ndalur procesin
"pruning_percent_step": 0.05, # pjesa e konvolucioneve për t'u fshirë në çdo hap prerjeje
"pruning_standart_deviation_part": 0.2 # shkelje për kufizimin e pjesës së prerë
}PĂ«r mĂ« tepĂ«r, Ă«shtĂ« realizuar njĂ« kufizim mbi bazĂ«n e devijimit standard. QĂ«llimi â tĂ« kufizojmĂ« pjesĂ«n e fshirĂ«, duke pĂ«rjashtuar konvolucionet me masa L1 "tĂ« mjaftueshme":

Me këtë, lejojmë që të fshijmë vetëm konvolucionet e dobëta nga shpërndarjet si ato të djathta dhe të mos ndikojmë në fshirjen nga shpërndarjet si ato të majta:

Te afrohesh shpërndarja me normën, koeficienti pruning_standart_deviation_part mund të përcaktohet nga:

Unë rekomandoj një tolerancë prej 2 sigma. Ose mund të mos orientoheni nga kjo karakteristikë, duke lënë vlerën < 1.0.
Në fund, rezulton një grafik i madhësisë së rrjetit, humbjeve dhe kohës së ekzekutimit të rrjetit gjatë gjithë testit, të normalizuar në 1.0. Për shembull, këtu madhësia e rrjetit është zvogëluar pothuajse dy herë pa humbur në cilësi (një rrjet konvolucioni i vogël me 100k peshë):

Shpejtësia e ekzekutimit është nën ndikimin e fluktuacioneve normale dhe praktikisht nuk ka ndryshuar. Kështu është e arsyeshme:
- Numri i konvolucioneve ndryshon nga të përshtatshmet (32, 64, 128) në ato jo shumë përshtatshëm për kartat grafike - 27, 51 etj. Këtu mund të gaboj, por me siguri kjo ndikon.
- Arkitektura nuk është e gjerë, por e vazhdueshme. Duke zvogëluar gjerësinë, ne nuk prekim thellësinë. Kështu, zvogëlojmë ngarkesën, por nuk ndryshojmë shpejtësinë.
Prandaj, përmirësimi u shpreh në zvogëlimin e ngarkesës CUDA gjatë ekzekutimit me 20-30%, por jo në zvogëlimin e kohës së ekzekutimit.
Përfundimet
Le të reflektojmë. Ne shqyrtuam 2 variante të prerjes - për YOLOv3 (kur duhet të punojmë manualisht) dhe për rrjetet me arkitektura më të thjeshta. Ndjehet se në të dy rastet, është e mundur të arrihet zvogëlimi i madhësisë së rrjetit dhe përshpejtimi pa humbur saktësinë. Rezultatet:
- Zvogëlim i madhësisë
- Përshpejtimi i ekzekutimit
- Zvogëlimi i ngarkesës CUDA
- Si pasojë, ekologjia (Ne optimizojmë përdorimin e ardhshëm të burimeve kompjuterike. Diku gëzon një )
Shtojca
- Pas hapit të prerjes, mund të rregullohet edhe kuantizimi (p.sh. me TensorRT)
- Tensorflow ofron mundësi për . Funksionon.
- doja të zhvilloja dhe do të isha i lumtur për ndihmë
Burimi: habr.com
