Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Para ty përsëri është një detyrë për identifikimin e objekteve. Prioriteti është shpejtësia e punës me një saktësi të pranueshme. Merr arhitekturën YOLOv3 dhe e trajnoni atë. Saktësia (mAp75) është më shumë se 0.95. Por shpejtësia e përpunimit gjithmonë mbetet e ulët. Korr.

Sot do ta kalojmë në mënyrë anash kvanitizimin. Nën kapitujm do të shqyrtojmë Pruning i Modelit — prerja e pjesëve të tepërta të rrjetit për të përshpejtuar Inferencën pa humbur saktësinë. Duke e ilustruar — nga e ku, sa dhe si mund të hiqet. Do të diskutojmë se si ta bëjmë këtë manualisht dhe ku mund ta automatizojmë. Në fund — një depo në keras.

Hyrje

Në vendin tim të kaluar të punës, në Macroscopin e Permës, kam fituar një zakon — të monitoroj gjithmonë kohën e ekzekutimit të algoritmeve. Dhe kohën e përpunimit të rrjeteve gjithmonë ta kontrolloj përmes filtrit të adekuatësisë. Zakonisht, state-of-the-art në prodhim nuk kalojnë këtë filtër, që më çoi tek Pruning.

Pruning — një temë e vjetër, për të cilën flitej në lektorat e Stanfordit në vitin 2017. Ideja kryesore — reduktimi i madhësisë së rrjetit të trajnuar pa humbur saktësinë përmes heqjes së nyjave të ndryshme. Dëgjohet mirë, por rrallë dëgjoj për aplikimin e saj. Ndoshta mungojnë implementimet, nuk ka artikuj në gjuhën ruse ose thjesht të gjithë e konsiderojnë pruning si një know-how dhe heshtin.
Por le t'i hedhim një vështrim

Një vështrim në biologji

Më pëlqen kur në Deep Learning hyjnë ide nga biologjia. Ata, ashtu si dhe evolucionin, mund të besohen (a e more vesh se ReLU është shumë e ngjashme me funksionin e aktivizimit të neuroneve në tru?)

Procesi i Pruning të Modelit është gjithashtu i afërt me biologjinë. Reagimi i rrjetit këtu mund të krahasohet me plastizitetin e trurit. Ka disa shembuj interesantë në librin Norman Doidge:

  1. Truri i një gruaje që kishte prej lindjes vetëm një gjysmë, e riprogramoi vetveten për të kryer funksionet e gjysmës së munguar
  2. Një djalë që i ka shkëputur vetes 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 e përsërisim)

Ashtu si nga modeli juaj mund të hiqni disa nga konvolucionet e dobëta. Në rastin më të keq, konvolucionet e mbetura do t'ju ndihmojnë të zëvendësoni të hequrat.

A e do Transfer Learning apo mëson nga fillimi?

Opsioni numër një. Po përdor Transfer Learning në Yolov3, Retina, Mask-RCNN ose U-Net. Por shpesh nuk na nevojitet të njohim 80 klasa objektesh si në COCO. Në përvojën time, gjithçka është e kufizuar në 1-2 klasa. Mund të supozojmë se arkitektura për 80 klasa këtu është e tepërt. Kjo na bën të mendojmë se arkitektura duhet të zvogëlohet. Për më tepër, do të dëshironim ta bënim këtë pa humbur pesha e paratreguara ekzistuese.

Opsioni i dytë. Ndoshta ti ke shumë të dhëna dhe burime kompjuterike, ose thjesht të nevojitet një arkitekturë super-personalizuar. Nuk ka rëndësi. Por ti e mëson rrjetin nga e para. Rregulli i zakonshëm është që shohim strukturën e të dhënave, përzgjedhim një arkitekturë TEPËR të fuqishme dhe shtojmë dropaout për mbipopullimin. Kam parë dropaout 0.6, Karl.

Në të dy rastet, rrjeti mund të zvogëlohet. E kemi motivuar. Tani le të kuptojmë se çfarë është prerja (pruning).

Algoritmi i përgjithshëm

Kemi vendosur se mund të eliminojmë konvolucione. Duke dukur mjaft e thjeshtë:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Eliminimi i çdo konvolucioni është një stres për rrjetin, i cili zakonisht çon në një rritje të caktuar të gabimit. Nga njëra anë, kjo rritje e gabimit është një tregues se sa saktë po eliminojmë konvolucionet (p.sh., një rritje e madhe tregon se po bëjmë diçka gabim). Por një rritje e vogël është mjaft e pranueshme dhe shpesh hiqet me një ritëm të vogël të përshtatjes që vijon. Shtojmë një hap përshtatjeje:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Tani na nevojitet të kuptojmë se kur duam të ndalojmë ciklin tonë të MësimitPruning. Këtu mund të kenë variante ekzotike, kur duhet ta zvogëlojmë rrjetin në një madhësi dhe shpejtësi të caktuar (p.sh., për pajisje mobile). Megjithatë, varianti më i zakonshëm është vazhdimi i ciklit derisa gabimi të shkojë mbi maksimumin e pranueshëm. Shtojmë një kushte:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Pra, algoritmi bëhet i qartë. Ne duhet të përcaktojmë se si të identifikojmë konvolucionet për tu eliminuar.

Kërkimi i konvolucioneve për t'u eliminuar.

Na nevojitet të eliminojmë disa konvolucione. Të sulmojmë dhe "të qëllojmë" çdo konvolucion është një ide e keqe, edhe pse do të funksionojë. Por që ka mendje, mund të mendojmë dhe të përpiqemi të identifikojmë konvolucionet "e dobëta" për t'u eliminuar. Ka disa opsione:

  1. Masa më e vogël L1 ose low_magnitude_pruning.. Ideja është se konvolucionet me këto vlera të vogla peshojnë pak në vendimin përfundimtar.
  2. Masa më e vogël L1 me llogaritjen e mesatares dhe devijimit standard. Plotësojmë me vlerësimin e natyrës së shpërndarjes.
  3. Maskimi i konvolutioneve dhe përjashtimi i atyre me ndikimin më të vogël në saktësinë përfundimtare. Një përcaktim më i saktë i konvolutioneve të pakta, por shumë i kushtueshëm në kohë dhe resurse.
  4. Të tjera

Çdo opsion ka të drejtën e ekzistencës dhe karakteristikat e tij të veçanta. Këtu do të shqyrtojmë opsionin me masën L1 më të vogël

Procesi manual për YOLOv3

Arkitektura origjinale përmban blloqe reziduese. Por, pavarësisht sa të jashtëzakonshëm janë ata për rrjetet e thella, ata na krijojnë disa pengesa. Vështirësia është se nuk mund të fshihen konvolutionet me indekse të ndryshme në këto shtresa:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Prandaj, do të distintim shtresat nga të cilat mund të fshijmë lirisht konvolutionet:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Tani do të ngremë një cikël pune:

  1. Shkarkojmë aktivizimet
  2. Përllogarisim se sa të presim
  3. Presim
  4. Mësojmë për 10 epoka me LR=1e-4
  5. Testojmë

Shkarkimi i konvolutioneve është i dobishëm për të vlerësuar se sa pjesë mund të fshijmë në një hap të caktuar. Shembujt e shkarkimit:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Vëmë re se pothuajse kudo 5% e konvolutioneve kanë normë shumë të ulët L1 dhe mund t'i fshijmë. Në çdo hap, ky shkarkim përsëritej dhe bëhej vlerësimi se nga cilat shtresa dhe sa mund të presim.

I gjithë procesi u zhvillua në 4 hapa (këtu dhe në gjithë numrat për RTX 2060 Super):

HapimAp75Numri i parametrave, mlnMadhësia e rrjetit, mbNga origjinali, %Koha e kalimit, msKushti i prerjes
00.965660241100180
10.962255218911755% nga e gjithë
20.962550197831685% nga e gjithë
30.9633391556415515% për shtresat me 400+ konvolucione
40.9555311245114610% për shtresat me 100+ konvolucione

Në hapin 2 u shtua një efekt pozitiv — që madhësia e grupit të kishte 4, gjë që përshpejtoi ndjeshëm procesin e ripërshtatjes.
Në hapin 4 procesi u ndal, pasi edhe trajnimet e zgjatura nuk çuan mAp75 në vlerat e vjetra.
Në fund, arritëm të shpejtojmë inferencën me 15%, të zvogëlojmë madhësinë me 35% dhe të mos humbim saktësinë.

Automatizimi për arkitekturë më të thjeshtë

Për arkitekturat më të thjeshta të rrjeteve (pa blloqe të mundshme add, concatenate dhe residual), është e mundshme të orientohesh në përpunimin e të gjitha shtresave konvolucionale dhe të automatizosh procesin e prerjes së konvolutioneve.

Ky opsion e implementova këtu.
E gjithë është e thjeshtë: ju keni vetëm funksionin e humbjes, optimizuesin 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 është e nevojshme, 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 train midis hapave të prerjes
    "stop_loss": 0.1, # humbja për të ndaluar procesin
    "pruning_percent_step": 0.05, # pjesa e convs për të fshirë në çdo hap prerjeje
    "pruning_standart_deviation_part": 0.2 # shmangie për të kufizuar pjesën e prerjes
}

Është implementuar gjithashtu një kufizim në bazë të devijimit standard. Qëllimi është të kufizojmë pjesën e fshirë, duke përjashtuar konvolucionet me masa L1 "të mjaftueshme":

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Kështu, ne lejojmë që të fshijmë vetëm konvolucionet e dobëta nga shpërndarjet e ngjashme me ato të djathta dhe nuk ndikojmë në fshirjen nga shpërndarjet e ngjashme me ato të majta:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Kur shpërndarja i afrohet normalit, koeficienti pruning_standart_deviation_part mund të përcaktohet nga:

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning
Unë rekomandoj një tolerancë prej 2 sigma. Ose mund të mos orientoheni nga kjo veçori, duke lënë vlerën < 1.0.

Si rezultat, del një grafik i madhësisë së rrjetit, humbjes dhe kohës së ekzekutimit të rrjetit gjatë gjithë testit, të normalizuar në 1.0. Për shembull, këtu madhësia e rrjetit u zvogëlua gati 2 herë pa humbje në cilësi (një rrjet i vogël konvolucional me 100k peshë):

Teknika Jedi e reduktimit të rrjeteve konvoluese — pruning

Shpejtësia e ekzekutimit është e ekspozuar ndaj fluktuacioneve normale dhe praktikisht nuk ka ndryshuar. Kësaj i ka shpjegim:

  1. Numri i konvolucioneve kalon nga të përshtatshmet (32, 64, 128) në ato që nuk janë aq të përshtatshme për kartat grafike — 27, 51 etj. Këtu mund të gaboj, por besoj se kjo ndikon.
  2. Arkitektura nuk është e gjerë, por e njëpasnjëshme. Duke ulur gjerësinë, ne nuk prekim thellësinë. Kështu zvogëlojmë ngarkesën, por nuk e ndryshojmë shpejtësinë.

Prandaj, përmirësimi u shpreh në zvogëlimin e ngarkesës CUDA gjatë ekzekutimit për 20-30%, por jo në zvogëlimin e kohës së ekzekutimit.

Përfundime

Le të reflektojmë. Kemi shqyrtuar 2 varianta të prerjes — për YOLOv3 (kur duhet të punosh me duar) dhe për rrjetet me arkitektura më të thjeshta. Është e qartë se në të dy rastet mund të arrihet një zvogëlim i madhësisë së rrjetit dhe një shpejtësi më e madhe pa humbje saktësie. Rezultatet:

  • Zvogëlimi i madhësisë
  • Shpejtimi i ekzekutimit
  • Zvogëlimi i ngarkesës CUDA
  • Si pasojë, ekologjiciteti (Ne optimizojmë përdorimin e ardhshëm të burimeve kompjuterike. Diku njëra është e gëzuar Greta Thunberg)

Shtojca

  • Pas hapit të prerjes, mund të vazhdojmë me kuantizimin (për shembull me TensorRT)
  • Tensorflow ofron mundësi për low_magnitude_pruning. Funksionon.
  • Repo dua ta zhvilloj dhe do të isha i lumtur për ndihmë

Burimi: habr.com

Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы 🔥 Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы | ProHoster