Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Pred vama je ponovno zadatak otkrivanja objekata. Prioritet je brzina rada uz prihvatljivu točnost. Uzimate YOLOv3 arhitekturu i dalje je trenirate. Točnost (mAp75) je veća od 0.95. Ali stopa trčanja je još uvijek niska. Sranje.

Danas ćemo zaobići kvantizaciju. I ispod reza ćemo pogledati Model Obrezivanje — skraćivanje suvišnih dijelova mreže kako bi se ubrzalo zaključivanje bez gubitka točnosti. Jasno je gdje, koliko i kako rezati. Hajde da shvatimo kako to učiniti ručno i gdje to možete automatizirati. Na kraju je spremište na kerasu.

Uvod

Na prethodnom radnom mjestu, Macroscopu u Permu, stekao sam jednu naviku - uvijek pratiti vrijeme izvršavanja algoritama. I uvijek provjerite mrežno vrijeme rada kroz filtar adekvatnosti. Obično najsuvremenije u proizvodnji ne prolaze ovaj filter, što me dovelo do rezidbe.

Orezivanje je stara tema o kojoj se raspravljalo u Predavanja na Stanfordu u 2017. godini. Glavna ideja je smanjiti veličinu uvježbane mreže bez gubitka točnosti uklanjanjem različitih čvorova. Zvuči cool, ali rijetko čujem o njegovoj upotrebi. Vjerojatno nema dovoljno implementacija, nema članaka na ruskom jeziku ili jednostavno svi to smatraju znanjem rezidbe i šute.
Ali rastavimo ga

Pogled u biologiju

Volim kad Deep Learning razmatra ideje koje dolaze iz biologije. Njima se, kao i evoluciji, može vjerovati (jeste li znali da je ReLU vrlo sličan funkcija aktivacije neurona u mozgu?)

Model rezidbe također je blizak biologiji. Odgovor mreže ovdje se može usporediti s plastičnošću mozga. U knjizi ima par zanimljivih primjera. Norman Doidge:

  1. Mozak žene koja je rođena samo s jednom polovicom reprogramirao se da obavlja funkcije polovice koja nedostaje.
  2. Tip mu je pucao u dio mozga odgovoran za vid. S vremenom su drugi dijelovi mozga preuzeli te funkcije. (ne pokušavamo ponavljati)

Isto tako, možete izrezati neke od slabih zavoja iz svog modela. U krajnjem slučaju, preostali snopovi pomoći će zamijeniti odrezane.

Volite li Transfer Learning ili učite od nule?

Opcija broj jedan. Koristite Transfer Learning na Yolov3. Retina, Mask-RCNN ili U-Net. Ali većinu vremena ne trebamo prepoznati 80 klasa objekata kao u COCO. U mojoj praksi sve je ograničeno na razrede 1-2. Moglo bi se pretpostaviti da je arhitektura za 80 razreda ovdje suvišna. To sugerira da arhitekturu treba smanjiti. Štoviše, želio bih to učiniti bez gubitka postojećih prethodno treniranih utega.

Opcija broj dva. Možda imate puno podataka i računalnih resursa ili vam je samo potrebna super-prilagođena arhitektura. Nije važno. Ali učite mrežu od nule. Uobičajeni postupak je pogledati strukturu podataka, odabrati arhitekturu koja ima PREVIŠE snage i pogurati osobe koje su napustile školovanje. Vidio sam 0.6 odustajanja, Karl.

U oba slučaja, mreža se može smanjiti. Motivirano. Sada idemo shvatiti kakva je vrsta obrezivanja obrezivanja

Opći algoritam

Odlučili smo da možemo ukloniti svežnjeve. Izgleda prilično jednostavno:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Uklanjanje bilo kakve konvolucije stresno je za mrežu, što obično dovodi do određenog povećanja pogreške. S jedne strane, ovo povećanje pogreške pokazatelj je koliko ispravno uklanjamo vijuge (na primjer, veliko povećanje ukazuje na to da radimo nešto pogrešno). Ali malo povećanje je sasvim prihvatljivo i često se eliminira naknadnim laganim dodatnim treningom s malim LR. Dodajte dodatni korak obuke:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Sada moramo shvatiti kada želimo zaustaviti našu petlju učenja<->obrezivanja. Ovdje mogu postojati egzotične opcije kada trebamo smanjiti mrežu na određenu veličinu i brzinu (na primjer, za mobilne uređaje). Međutim, najčešća opcija je nastavak ciklusa dok pogreška ne postane veća od prihvatljive. Dodajte uvjet:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Dakle, algoritam postaje jasan. Ostaje shvatiti kako odrediti izbrisane vijuge.

Potražite izbrisane pakete

Moramo ukloniti neke zavoje. Žuriti naprijed i "upucavati" bilo koga je loša ideja, iako će uspjeti. Ali budući da imate glavu, možete razmisliti i pokušati odabrati "slabe" vijuge za uklanjanje. Postoji nekoliko opcija:

  1. Najmanja L1-mjera ili obrezivanje niske_veličine. Ideja da konvolucije s malim težinama malo doprinose konačnoj odluci
  2. Najmanja L1-mjera uzimajući u obzir srednju vrijednost i standardnu ​​devijaciju. Dopunjavamo ocjenom prirode distribucije.
  3. Maskiranje zavoja i isključivanje onih koji najmanje utječu na konačnu točnost. Točnije određivanje beznačajnih zavoja, ali vrlo dugotrajno i resursno.
  4. Drugi

Svaka od opcija ima pravo na život i svoje značajke implementacije. Ovdje razmatramo opciju s najmanjom L1-mjerom

Ručni postupak za YOLOv3

Izvorna arhitektura sadrži zaostale blokove. Ali koliko god bili cool za duboke mreže, donekle će nas ometati. Poteškoća je u tome što ne možete izbrisati usklađivanja s različitim indeksima u ovim slojevima:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Stoga, odaberimo slojeve iz kojih možemo slobodno brisati usklađivanja:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Sada napravimo radni ciklus:

  1. Prijenos aktivacija
  2. Smišljanje koliko smanjiti
  3. Izrezati
  4. Učenje 10 epoha s LR=1e-4
  5. Testiranje

Istovar vijuga je koristan za procjenu koliko dijelova možemo ukloniti u određenom koraku. Primjeri istovara:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Vidimo da gotovo posvuda 5% vijuga ima vrlo nisku L1-normu i možemo ih ukloniti. U svakom koraku ponavljalo se ovo istovaranje i procjenjivalo se koji se slojevi i koliko mogu izrezati.

Cijeli proces je dovršen u 4 koraka (brojevi ovdje i posvuda za RTX 2060 Super):

Korak mAp75 Broj parametara, milijun Veličina mreže, mb Od početka, % Vrijeme izvođenja, ms Stanje obrezivanja
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% od svih
2 0.9625 50 197 83 168 5% od svih
3 0.9633 39 155 64 155 15% za slojeve s 400+ zavoja
4 0.9555 31 124 51 146 10% za slojeve s 100+ zavoja

Koraku 2 dodan je jedan pozitivan učinak - veličina serije 4 stala je u memoriju, što je znatno ubrzalo proces dodatne obuke.
U koraku 4 proces je zaustavljen jer čak ni dugotrajna dodatna obuka nije podigla mAp75 na stare vrijednosti.
Kao rezultat toga, uspjeli smo ubrzati zaključivanje za 15%, smanjite veličinu za 35% a ne izgubiti točno.

Automatizacija za jednostavnije arhitekture

Za jednostavnije mrežne arhitekture (bez uvjetnog dodavanja, spajanja i rezidualnih blokova), sasvim je moguće usredotočiti se na obradu svih zavojnih slojeva i automatizirati proces izrezivanja zavoja.

Implementirao sam ovu opciju здесь.
Jednostavno je: potrebna vam je samo funkcija gubitka, optimizator i batch generatori:

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)

Ako je potrebno, možete promijeniti konfiguracijske parametre:

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

Osim toga, provodi se ograničenje temeljeno na standardnoj devijaciji. Cilj je ograničiti dio koji se uklanja, isključujući zavoje s već "dovoljnim" mjerama L1:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Stoga vam dopuštamo uklanjanje samo slabih zavoja iz distribucija sličnih desnoj i ne utječemo na uklanjanje iz distribucija sličnih lijevoj:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Kada se distribucija približi normalnoj, koeficijent pruning_standart_deviation_part može se odabrati između:

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning
Preporučujem pretpostavku od 2 sigme. Ili možete zanemariti ovu značajku, ostavljajući vrijednost < 1.0.

Izlaz je grafikon veličine mreže, gubitaka i vremena rada mreže za cijeli test, normaliziran na 1.0. Na primjer, ovdje je veličina mreže smanjena gotovo 2 puta bez gubitka kvalitete (mala konvolucijska mreža s težinama od 100k):

Jedi tehnika za smanjivanje konvolucijskih mreža – pruning

Brzina vožnje je podložna normalnim fluktuacijama i ostaje gotovo nepromijenjena. Za to postoji objašnjenje:

  1. Broj zavoja mijenja se od prikladnog (32, 64, 128) do ne najprikladnijeg za video kartice - 27, 51 itd. Možda griješim, ali najvjerojatnije ima učinka.
  2. Arhitektura nije široka, ali dosljedna. Smanjenjem širine ne utječemo na dubinu. Dakle, smanjujemo opterećenje, ali ne mijenjamo brzinu.

Stoga je poboljšanje izraženo u smanjenju CUDA opterećenja tijekom rada za 20-30%, ali ne iu smanjenju vremena rada.

Rezultati

Razmislimo. Razmotrili smo 2 mogućnosti rezanja - za YOLOv3 (kada morate raditi rukama) i za mreže s jednostavnijom arhitekturom. Može se vidjeti da je u oba slučaja moguće postići smanjenje veličine mreže i ubrzanje bez gubitka točnosti. Rezultati:

  • Smanjenje veličine
  • Trčanje za ubrzanje
  • Smanjenje CUDA opterećenja
  • Kao rezultat, prihvatljivost okoliša (Optimiziramo buduću upotrebu računalnih resursa. Negdje je netko sretan Greta Thunberg)

Dodatak

  • Nakon koraka rezanja, možete dodati kvantizaciju (na primjer, s TensorRT)
  • Tensorflow pruža mogućnosti za obrezivanje male_veličine. Djela.
  • spremište Želim se razvijati i rado ću pomoći

Izvor: www.habr.com

Dodajte komentar