
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Ă« 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 ?)
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 :
- 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
- 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ë:

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:

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:

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:
- . Ideja është se konvolucionet me këto vlera të vogla peshojnë pak në vendimin përfundimtar.
- Masa më e vogël L1 me llogaritjen e mesatares dhe devijimit standard. Plotësojmë me vlerësimin e natyrës së shpërndarjes.
- . Një përcaktim më i saktë i konvolutioneve të pakta, por shumë i kushtueshëm në kohë dhe resurse.
- 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:

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

Tani do të ngremë një cikël pune:
- Shkarkojmë aktivizimet
- Përllogarisim se sa të presim
- Presim
- Mësojmë për 10 epoka me LR=1e-4
- 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:

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):
| Hapi | mAp75 | Numri i parametrave, mln | Madhësia e rrjetit, mb | Nga origjinali, % | Koha e kalimit, ms | Kushti i prerjes |
|---|---|---|---|---|---|---|
| 0 | 0.9656 | 60 | 241 | 100 | 180 | â |
| 1 | 0.9622 | 55 | 218 | 91 | 175 | 5% nga e gjithë |
| 2 | 0.9625 | 50 | 197 | 83 | 168 | 5% nga e gjithë |
| 3 | 0.9633 | 39 | 155 | 64 | 155 | 15% për shtresat me 400+ konvolucione |
| 4 | 0.9555 | 31 | 124 | 51 | 146 | 10% 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 .
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":

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:

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

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ë):

Shpejtësia e ekzekutimit është e ekspozuar ndaj fluktuacioneve normale dhe praktikisht nuk ka ndryshuar. Kësaj i ka shpjegim:
- 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.
- 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 )
Shtojca
- Pas hapit të prerjes, mund të vazhdojmë me kuantizimin (për shembull me TensorRT)
- Tensorflow ofron mundësi për . Funksionon.
- dua ta zhvilloj dhe do të isha i lumtur për ndihmë
Burimi: habr.com
