Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Pred vama je ponovo zadatak otkrivanja objekata. Prioritet je brzina rada uz prihvatljivu preciznost. Uzimate YOLOv3 arhitekturu i dalje je obučavate. Preciznost (mAp75) je veća od 0.95. Ali stopa rada je još uvijek niska. Sranje.

Danas ćemo zaobići kvantizaciju. A ispod reza ćemo pogledati Model Obrezivanje — odsecanje suvišnih delova mreže radi ubrzanja zaključivanja bez gubitka tač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 se nalazi spremište na kerasu.

Uvod

Na prethodnom radnom mestu, Macroscop u Permu, stekao sam jednu naviku - da uvek pratim vreme izvršavanja algoritama. I uvijek provjerite vrijeme rada mreže kroz filter adekvatnosti. Obično najsavremenije u proizvodnji ne prođu ovaj filter, što me je dovelo do Obrezivanja.

Orezivanje je stara tema o kojoj se raspravljalo Stanford predavanja u 2017. Glavna ideja je smanjiti veličinu obučene mreže bez gubitka preciznosti uklanjanjem različitih čvorova. Zvuči super, ali rijetko čujem za njegovu upotrebu. Vjerovatno nema dovoljno implementacija, nema članaka na ruskom jeziku, ili jednostavno svi smatraju da to skraćuje znanje i šuti.
Ali hajde da ga rastavite

Pogled u biologiju

Sviđa mi se kada duboko učenje razmatra ideje koje dolaze iz biologije. Njima se, kao i evoluciji, može vjerovati (da li ste znali da je ReLU vrlo sličan funkcija aktivacije neurona u mozgu?)

Proces modelne rezidbe je također blizak biologiji. Odgovor mreže ovdje se može uporediti sa plastičnošću mozga. U knjizi ima nekoliko zanimljivih primjera. Norman Doidge:

  1. Mozak žene koja je rođena sa samo jednom polovinom reprogramirao se da obavlja funkcije polovice koja nedostaje.
  2. Tip mu je odbio dio mozga odgovoran za vid. Vremenom su te funkcije preuzeli drugi dijelovi mozga. (ne pokušavamo da ponovimo)

Isto tako, možete izrezati neke od slabih konvolucija iz vašeg modela. U krajnjem slučaju, preostali snopovi pomoći će zamijeniti izrezane.

Volite li transfer učenja ili učite od nule?

Opcija broj jedan. Koristite Transfer Learning na Yolov3. Retina, Mask-RCNN ili U-Net. Ali većinu vremena ne moramo 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 klasa ovdje suvišna. Ovo sugerira da arhitekturu treba smanjiti. Štaviše, želio bih to učiniti bez gubljenja postojećih prethodno uvježbanih tegova.

Opcija broj dva. Možda imate puno podataka i računarskih resursa, ili vam je samo potrebna super prilagođena arhitektura. Nije bitno. Ali učite mrežu od nule. Uobičajena procedura je da se pogleda struktura podataka, odabere arhitektura koja je PREKRASNA u snazi ​​i potisne odustajanje od preobuke. Video sam 0.6 odustajanja, Karl.

U oba slučaja, mreža se može smanjiti. Motivisan. Hajde sada da shvatimo kakva je vrsta obrezivanja

Opći algoritam

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

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Uklanjanje bilo koje konvolucije je stresno za mrežu, što obično dovodi do određenog povećanja greške. S jedne strane, ovo povećanje greške je pokazatelj koliko ispravno uklanjamo konvolucije (na primjer, veliko povećanje ukazuje 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 smanjenje konvolucionih mreža - orezivanje

Sada moramo shvatiti kada želimo zaustaviti našu petlju Learning<->Obrezivanje. 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 sve dok greška ne postane veća od prihvatljive. Dodajte uslov:

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

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

Potražite izbrisane pakete

Moramo ukloniti neke zavoje. Juriti naprijed i "pucati" u bilo koga je loša ideja, iako će uspjeti. Ali budući da imate glavu, možete razmišljati i pokušati odabrati "slabe" konvolucije za uklanjanje. Postoji nekoliko opcija:

  1. Najmanja L1-mera ili obrezivanje niske_magnitude. Ideja da konvolucije sa malim težinama malo doprinose konačnoj odluci
  2. Najmanja L1-mjera koja uzima u obzir srednju vrijednost i standardnu ​​devijaciju. Dopunjavamo procjenom prirode distribucije.
  3. Maskiranje konvolucija i isključivanje onih koji najmanje utiču na konačnu tačnost. Točnije određivanje beznačajnih konvolucija, ali vrlo dugotrajno i resursno.
  4. Ostalo

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

Ručni proces za YOLOv3

Originalna arhitektura sadrži preostale blokove. Ali koliko god da su cool za duboke mreže, donekle će nas ometati. Poteškoća je u tome što ne možete izbrisati usaglašavanja s različitim indeksima u ovim slojevima:

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Stoga, izaberimo slojeve iz kojih možemo slobodno brisati usaglašavanja:

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Sada napravimo ciklus rada:

  1. Učitavanje aktivacija
  2. Smišljanje koliko treba smanjiti
  3. Sečenje
  4. Učenje 10 epoha sa LR=1e-4
  5. Testiranje

Rasterećenje konvolucija je korisno za procjenu koliko dijela možemo ukloniti u određenom koraku. Primjeri istovara:

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Vidimo da skoro svuda 5% konvolucija ima vrlo nisku L1-normu i možemo ih ukloniti. U svakom koraku, ovo rasterećenje se ponavljalo i procjenjivalo se koji slojevi i koliko ih je moguće izrezati.

Ceo proces je završen u 4 koraka (brojevi ovde i svuda za RTX 2060 Super):

Korak mAp75 Broj parametara, milion Veličina mreže, mb Od početnog, % Vrijeme rada, 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 sa 400+ konvolucija
4 0.9555 31 124 51 146 10% za slojeve sa 100+ konvolucija

Korak 2 dodan je jedan pozitivan efekat - veličina serije 4 se uklapa 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 15%, smanjite veličinu za 35% i ne izgubiti tačno.

Automatizacija za jednostavnije arhitekture

Za jednostavnije mrežne arhitekture (bez uvjetnog dodavanja, spajanja i rezidualnih blokova) sasvim je moguće fokusirati se na obradu svih konvolucijskih slojeva i automatizirati proces izrezivanja konvolucija.

Ja sam implementirao ovu opciju ovdje.
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
}

Dodatno, implementirano je ograničenje zasnovano na standardnoj devijaciji. Cilj je ograničiti dio koji se uklanja, isključujući konvolucije s već "dovoljnim" L1 mjerama:

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Stoga vam omogućavamo da uklonite samo slabe konvolucije iz distribucija sličnih desnoj i ne utičete na uklanjanje iz distribucija sličnih lijevoj:

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

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

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje
Preporučujem pretpostavku od 2 sigma. Ili možete zanemariti ovu funkciju, ostavljajući vrijednost < 1.0.

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

Jedi tehnika za smanjenje konvolucionih mreža - orezivanje

Brzina trčanja je podložna normalnim fluktuacijama i ostaje gotovo nepromijenjena. Za ovo postoji objašnjenje:

  1. Broj konvolucija se mijenja od pogodnih (32, 64, 128) do ne najprikladnijih za video kartice - 27, 51, itd. Možda grešim, ali najverovatnije ima efekta.
  2. Arhitektura nije široka, ali konzistentna. Smanjenjem širine ne utičemo na dubinu. Tako smanjujemo opterećenje, ali ne mijenjamo brzinu.

Dakle, poboljšanje je izraženo u smanjenju opterećenja CUDA tokom trčanja za 20-30%, ali ne i u smanjenju vremena rada

Ishodi

Hajde da razmislimo. Razmotrili smo 2 opcije za smanjenje - za YOLOv3 (kada morate raditi rukama) i za mreže sa 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
  • Ubrzanje
  • Smanjenje CUDA opterećenja
  • Kao rezultat, ekološka prihvatljivost (Optimiziramo buduću upotrebu računarskih resursa. Negdje je neko zadovoljan Greta Thunberg)

dodatak

  • Nakon koraka rezanja, možete dodati kvantizaciju (na primjer, sa TensorRT)
  • Tensorflow pruža mogućnosti za low_magnitude_obrezivanje. Radi.
  • spremište Želim da se razvijam i rado ću pomoći

izvor: www.habr.com

Dodajte komentar