Deep Learning Best Practices (1) - Initialisering av vekt

Grunnleggende, fallinitialiseringsgruver og beste praksis

https://pixabay.com/photo-1600668/

Motivasjon

Som nybegynner på dyp læring, var en av tingene jeg innså at det ikke er mye online dokumentasjon som dekker alle dype læring-triks et sted. Det er mange små beste fremgangsmåter, alt fra enkle triks som initialisering av vekter, regularisering til litt komplekse teknikker som syklisk læringsgrad som kan gjøre trening og feilsøking av nevrale nett enklere og effektive. Dette inspirerte meg til å skrive denne serien med blogger hvor jeg vil dekke så mange nyanser jeg kan for å gjøre implementering av dyp læring enklere for deg.

Når du skriver denne bloggen, er forutsetningen at du har en grunnleggende ide om hvordan nevrale nettverk blir opplært. En forståelse av vekter, skjevheter, skjulte lag, aktiveringer og aktiveringsfunksjoner vil gjøre innholdet tydeligere. Jeg vil anbefale dette kurset hvis du ønsker å bygge et grunnleggende fundament for dyp læring.

Merk - Hver gang jeg refererer til lag i et nevralt nettverk, innebærer det lagene i et enkelt nevralt nettverk, dvs. de helt tilkoblede lagene. Noen av metodene jeg snakker om gjelder selvfølgelig også for innviklede og tilbakevendende nevrale nettverk. I denne bloggen skal jeg snakke om problemene knyttet til initialisering av vektmatriser og måter å dempe dem på. Før det, la oss bare dekke noen grunnleggende og notasjoner som vi vil bruke fremover.

Grunnleggende og notasjoner

Vurdere et L-lag nevralt nettverk, som har L-1 skjulte lag og 1 utgangslag. Parametrene (vekter og skjevheter) for laget l er representert som

I tillegg til vekter og skjevheter, beregnes følgende mellomvariabler under treningsprosessen

Å trene et nevralt nettverk består av fire trinn:

  1. Initialiser vekter og skjevheter.
  2. Fremoverutbredelse: Ved bruk av inndata X, vekter W og forspenninger b, for hvert lag vi beregner Z og A. På det endelige laget beregner vi f (A ^ (L-1)) som kan være en sigmoid, softmax eller lineær funksjon av A ^ (L-1), og dette gir prediksjonen y_hat.
  3. Beregn tapsfunksjonen: Dette er en funksjon av den faktiske etiketten y og den forutsagte etiketten y_hat. Den fanger hvor langt unna spådommene våre er fra det faktiske målet. Vårt mål er å minimere denne tapsfunksjonen.
  4. Bakoverutbredelse: I dette trinnet beregner vi gradientene av tapsfunksjonen f (y, y_hat) med hensyn til A, W og b kalt dA, dW og db. Ved å bruke disse gradientene oppdaterer vi verdiene til parametrene fra det siste laget til det første.
  5. Gjenta trinn 2–4 for n iterasjoner / epoker til vi føler at vi har minimert tapsfunksjonen, uten å overpasse togdataene (mer om dette senere!)

Her er en rask titt på trinn 2, 3 og 4 for et nettverk med 2 lag, dvs. ett skjult lag. (Merk at jeg ikke har lagt skjevhetsbetingelsene her for enkelhets skyld):

FremoverformeringBakoverformering

Initialisering av vekter W

Et av utgangspunktene å ta vare på mens du bygger nettverket ditt, er å initialisere vektmatrisen riktig. La oss vurdere to scenarier som kan forårsake problemer mens vi trener modellen:

1. Initialiserer alle vekter til 0

La oss bare legge den der ute - dette gjør modellen din til en lineær modell. Når du setter all vekt til 0, er derivatet med hensyn til tapsfunksjon det samme for hver w i W ^ l, og dermed har alle vektene de samme verdiene i den påfølgende iterasjonen. Dette gjør de skjulte enhetene symmetriske og fortsetter for alle n iterasjoner du kjører. Å sette vekter til null gjør nettverket ditt ikke bedre enn en lineær modell. Det er viktig å merke seg at å sette skjevheter til 0 ikke vil skape noen problemer, da vekter som ikke er null, sørger for å bryte symmetrien, og selv om skjevheten er 0, er verdiene i hvert nevron fremdeles forskjellige.

2. Initialisering av vekter tilfeldig

Å initialisere vekter tilfeldig, ved å følge standard normalfordeling (np.random.randn (størrelse_l, størrelse_l-1) i Python) mens du arbeider med et (dypt) nettverk, kan potensielt føre til to problemer - forsvinningsgradienter eller eksploderende graderinger.

a) Forsvinnende gradienter - Ved dype nettverk vil abs (dW) for enhver aktiveringsfunksjon bli mindre og mindre når vi går bakover med hvert lag under utbredelse av ryggen. De tidligere lagene er de tregeste å trene i et slikt tilfelle.

Vektoppdateringen er liten og gir langsommere konvergens. Dette gjør optimaliseringen av tapsfunksjonen treg. I verste fall kan dette stoppe nevrale nettverket helt fra å trene videre.

Mer spesifikt, i tilfelle sigmoid (z) og tanh (z), hvis vektene dine er store, vil gradienten være forsvinnende liten og effektivt forhindre at vektene endrer verdien. Dette er fordi abs (dW) vil øke veldig litt eller muligens bli mindre og mindre hver iterasjon. Med RELU (z) er forsvinningsgradienter vanligvis ikke et problem, da gradienten er 0 for negative (og null) innganger og 1 for positive innganger.

b) Eksploderende graderinger - Dette er det motsatte av forsvinnende gradienter. Tenk på at du har ikke-negative og store vekter og små aktiveringer A (som kan være tilfelle for sigmoid (z)). Når disse vektene multipliseres langs lagene, forårsaker de en stor endring i kostnadene. Dermed blir gradientene også store. Dette betyr at endringene i W, med W - ⍺ * dW, vil være i store trinn, det nedadgående øyeblikket vil øke.

Dette kan føre til svingende rundt minima eller til og med å overskrive det optimale igjen og igjen, og modellen vil aldri lære!

En annen innvirkning av eksplosive graderinger er at enorme verdier av gradientene kan føre til antalloverløp som kan føre til feilberegninger eller introduksjoner av NaNs. Dette kan også føre til at tapet tar verdien NaN.

Beste praksis

1. Bruke RELU / lekker RELU som aktiveringsfunksjon, da det er relativt robust overfor forsvinnende / eksploderende gradientproblemet (spesielt for nettverk som ikke er for dypt). I tilfelle av utette RELU-er, har de aldri 0 gradient. Dermed dør de aldri og trening fortsetter.

2. For dype nettverk kan vi bruke heuristikk for å initialisere vektene avhengig av den ikke-lineære aktiveringsfunksjonen. Her, i stedet for å tegne fra standard normalfordeling, tegner vi W fra normalfordeling med varians k / n, hvor k avhenger av aktiveringsfunksjonen. Selv om disse heuristikkene ikke løser problemet med eksplosjon / forsvinnende gradient helt, hjelper de å dempe det i stor grad. De vanligste er:

a) For RELU (z) - Vi multipliserer de tilfeldig genererte verdiene av W med:

b) For tanh (z) - Heuristikken kalles Xavier initialisering. Den ligner den forrige, bortsett fra at k er 1 i stedet for 2.

I TensorFlow W = tf.get_variable ('W', [dims], initializer) hvor initialisator = tf.contrib.layers.xavier_initializer ()

c) En annen vanlig heuristikk er:

Disse fungerer som gode utgangspunkt for initialisering og demper sjansene for å eksplodere eller forsvinne gradueringer. De setter vektene verken for mye større enn 1, eller for mye mindre enn 1. Altså, gradientene forsvinner ikke eller eksploderer for raskt. De hjelper til med å unngå langsom konvergens, og sørger også for at vi ikke fortsetter å svinge av minima. Det finnes andre varianter av de ovennevnte, der hovedmålet igjen er å minimere variansen til parametrene.

3. Gradient Clipping - Dette er en annen måte å håndtere det eksplosive gradientproblemet. Vi setter en terskelverdi, og hvis en valgt funksjon av en gradient er større enn denne terskelen, setter vi den til en annen verdi. Normaliser for eksempel gradientene når L2-normen overskrider en viss terskel - W = W * terskel / l2_norm (W) hvis l2_norm (W)> terskel

Et viktig poeng å merke seg er at vi har snakket om forskjellige initialiseringer av W, men ikke skjevhetene b. Dette er fordi gradientene med hensyn til skjevhet bare avhenger av den lineære aktiveringen av det laget, og ikke av gradientene til de dypere lagene. Dermed er det ingen reduksjon eller eksplosjon av gradienter for skjevhetene. Som nevnt tidligere, kan de trygt initialiseres til 0.

Konklusjon

I denne bloggen har vi dekket fallgruver for vektinitialisering og noen begrensningsteknikker. Hvis jeg har gått glipp av annen nyttig innsikt knyttet til dette emnet, vil jeg gjerne lære det fra deg! I neste blogg vil jeg snakke om regulariseringsmetoder for å redusere overmasse og gradientkontroll - et triks for å gjøre feilsøking enklere!

referanser

  1. https://www.coursera.org/learn/deep-neural-network/lecture/RwqYe/weight-initialization-for-deep-networks
  2. Nevrale nettverk: trening med backpropagation - Jeremy Jordan
  3. En mild introduksjon til eksploderende graderinger i nevrale nettverk av Jason Brownlee
  4. Forsvinnende gradientproblem
  5. https://www.quora.com/Why-is-it-a-problem-to-have-exploding-gradients-in-a-neural-net-especially-in-an-RNN

Om meg: Utdannet ved MS Data Science ved USF og undergrad i informatikk, har jeg 2 års erfaring med å bygge prediktive og anbefalingsalgoritmer, og utlede forretningsinnsikt for finans- og detaljhandelskunder. Jeg er spent på muligheter for å bruke maskinlæring og kunnskap om dyp læring på problemer i den virkelige verden.
Sjekk ut de andre bloggene mine her!
LinkedIn: https://www.linkedin.com/in/neerja-doshi/