Thursday 2 November 2017

Flytte Gjennomsnittet Neural Nettverk


John Bullinarias Step by Step Guide til å implementere et neuralt nettverk i C Av John A. Bullinaria fra School of Computer Science ved University of Birmingham, Storbritannia. Dette dokumentet inneholder en trinnvis veiledning for å implementere et enkelt neuralt nettverk i C. Det er hovedsakelig rettet mot studenter som ønsker å (eller har blitt fortalt) å inkorporere en læringskomponent i et større system de bygger. Det er åpenbart at det er mange typer nevrale nettverk man kan vurdere å bruke - her skal jeg konsentrere seg om en spesielt vanlig og nyttig type, nemlig et enkelt trelags feed-forward back-propagationsnettverk (multi layer perceptron). Denne typen nettverk vil være nyttig når vi har et sett med inngangvektorer og et tilsvarende sett med utgangsvektorer, og vårt system må produsere en passende utgang for hver inngang den er gitt. Selvfølgelig, hvis vi allerede har et komplett støyfritt sett med inngangs - og utgangsvektorer, vil det være tilstrekkelig med et enkelt oppslagstabell. Men hvis vi vil at systemet skal generaliseres. d. v.s. produsere passende utganger for innganger det aldri har sett før, da vil et nevralt nettverk som har lært å kartlegge mellom de kjente innganger og utganger (dvs. treningssettet) ofte gjøre en ganske god jobb for nye innganger også. Jeg skal anta at leseren allerede er kjent med C, og for mer informasjon om nevrale nettverk generelt, referer leseren til nyhetsgruppens comp. ai. neural-nett og de tilhørende spørsmålene om nevrale nettverk. Så, la oss begynne. En enkelt nevron (dvs. behandlingsenhet) tar den totale inngangen i og produserer en utgangsaktivering ut. Jeg skal ta dette for å være sigmoid-funksjonen, men andre aktiveringsfunksjoner brukes ofte (for eksempel lineær eller hyperbolisk tangent). Dette har den effekten av å knuse det uendelige utvalg av In inn i området 0 til 1. Det har også den praktiske egenskapen at dets derivat tar den spesielt enkle formen SigmoidDerivative Sigmoid (1.0 - Sigmoid) Vanligvis vil inngangen inn i et gitt nevron bli den vektede summen av utgangsaktiveringer som fôrer inn fra en rekke andre nevroner. Det er praktisk å tenke på aktiveringene som strømmer gjennom lag av nevroner. Så, hvis det er NumUnits1-neuroner i lag 1, er den totale aktiveringen som strømmer inn i vårt lag 2-neuron, bare summen over Layer1OutiWeighti. hvor Weighti er styrken av forbindelsen mellom enhet i i lag 1 og vår enhet i lag 2. Hver neuron vil også ha en bias eller hvilestatus som legges til summen av innganger, og det er praktisk å kalle denne vekten 0 . Vi kan da skriveLayer2In Weight0 start med bias for (i 1 I lt NumUnits1 i) Layer2In Layer1Outi Weighti legg i vektede bidrag fra lag 1 Layer2Out 1.0 (1.0 exp (-Layer2In)) beregne sigmoid for å gi aktivering Normalt vil lag 2 ha mange enheter også, så det er hensiktsmessig å skrive vektene mellom enhet i i lag 1 og enhet j i lag 2 som en array Weightij. For å få utdataene fra enhet j i lag 2 har vi Layer2Inj Weight0j for (i 1 i NumUnits1 i) Layer2Inj Layer1Outi Weightij Layer2Outj 1.0 (1.0 exp (-Layer2Inj)) Husk at i C starter indeksene fra null, ikke en , så vi vil erklære våre variabler asdouble Layer1OutNumUnits11 double Layer2InNumUnits21 double Layer2OutNumUnits21 double WeightNumUnits11NumUnits21 (eller, mer sannsynlig, erklære pekere og bruk calloc eller malloc til å tildele minnet). Selvfølgelig trenger vi en annen sløyfe for å få alle lag 2-utgangene for (j 1 j lt NumUnits2 j) Layer2Inj Weight0j for (1 1 lt NumUnits1 i) Layer2Inj Layer1Outi Weightij Layer2Outj 1.0 (1.0 exp (-Layer2Inj)) Tre lags nettverk er nødvendige og tilstrekkelig for de fleste formål, slik at lag 2-utgangene våre strømmer inn i et tredje lag på samme måte som ovenfor. Koden kan begynne å bli forvirrende på dette punktet. Jeg finner at det å holde en egen indeks, jeg, j, k for hvert lag hjelper, som gjør en intuitiv notasjon for å skille mellom de forskjellige lagtykkene Weight12 og Weight23. Av åpenbare grunner, for tre lags nettverk, er det tradisjonelt å ringe til lag 1 Inndata laget, lag 2 det skjulte lag og lag 3 utgangslaget. Vårt nettverk tar dermed den kjente form som vi skal bruke for resten av dette dokumentet. For å lagre å få alle In s og Out s forvirret, kan vi skrive LayerNIn som SumN. Vår kode kan dermed skrives. Generelt vil vi ha et helt sett med NumPattern treningsmønstre, dvs. par av inngangs - og målutgangsvektorer, merket av indeksen p. Nettverket lærer ved å minimere noe mål på feilen i nettverketes faktiske utdata sammenlignet med målutgangene. For eksempel vil sumkvadratfeilen over alle utgangsenheter k og alle treningsmønstre p bli gitt ved Feil 0,0 for (p 1 p lt NumPattern p) for (k 1 k lt NumOutput k) Feil 0,5 (Targetpk - Outputpk) (Targetpk - Outputpk) (Faktoren på 0,5 er vanligvis inkludert for å forenkle algebraen ved å utlede læringsalgoritmen.) Hvis vi legger inn koden ovenfor for å beregne nettverksutgangene i p-løkken av dette, slutter vi med Ill, la leseren slippe ut med noen indekser som de ikke trenger med hensyn til deres eget system (f. eks. indeksene på SumH og SumO). Det neste trinnet er å iterativt justere vekter for å minimere nettverksfeilen. En standard måte å gjøre dette på er ved gradient nedstigning på feilfunksjonen. Vi kan beregne hvor mye feilen endres med en liten endring i hver vekt (dvs. beregne de partielle derivatene d Feil d Vekt) og skift vektene med en liten mengde i retningen som reduserer feilen. Litteraturen er full av variasjoner i denne generelle tilnærmingen - jeg skal begynne med standard on-line back-propagation med momentum algoritme. Dette er ikke stedet å gå gjennom all matematikk, men for den ovennevnte summekvadratfeil kan vi beregne og bruke en iterasjon (eller epoke) av de nødvendige vektendringene DeltaWeightIH og DeltaWeightHO ved å bruke Feil 0,0 for (p 1 p lt NumPattern p) for (j 1 j lt NumHidden j) SumHpj WeightIH0j for (I 1 I NumInput i) SumHpj Inputpi WeightIHij Hiddenpj 1.0 (1.0 exp (-SumHpj)) for (k 1 k lt NumOutput k) SumOpk WeightHO0k for (j 1 j lt NumHidden j) SumOpk Hiddenpj WeightHOjk Outputpk 1.0 (1.0 exp (-SumOpk)) Feil 0.5 (Targetpk - Outputpk) (Targetpk - Outputpk) DeltaOk (Targetpk - Outputpk) Outputpk (1.0 - Outputpk) for (j 1 j lt NumHidden j) SumDOWj 0,0 for (k 1 k lt NumOutput k) SumDOWj WeightHOjk DeltaOk DeltaHj SumDOWj Hiddenpj (1.0 - Hiddenpj) for (j 1 j lt NumHidden j) DeltaWeightIH0j eta DeltaHj alpha DeltaWeightIH0j WeightIH0j DeltaWeightIH0j for (i 1 iIndIngang) DeltaWeightIHij eta Inputpi DeltaHj alfa DeltaWeightIHij WeightIHij DeltaWeightIHij for (k 1 k lt NumOutput k) DeltaWeightHO0k eta DeltaOk alpha DeltaWeightHO0k WeightHO0k DeltaWeightHO0k for (j 1 j lt NumHidden j) DeltaWeightHOjk eta Hiddenpj DeltaOk alpha DeltaWeightHOjk WeightHOjk DeltaWeightHOjk (Det er klart rikelig med muligheter for ombestilling, kombinere og forenkle løkkene her - jeg vil forlate det for leseren å gjøre når de har forstått hva de separate kodeseksjonene gjør.) Vektendringene DeltaWeightIH og DeltaWeightHO er hver bestå av to komponenter. Først, eta-komponenten som er graden av nedstigningsbidrag. For det andre er alfakomponenten som er et momentum-term som effektivt holder et bevegelig gjennomsnittsgrad av graden av nedgangsvektsendring, og dermed utjevner de totale vektendringene. Fastsetting av gode verdier av læringsparametrene eta og alpha er vanligvis et spørsmål om prøving og feiling. Absolutt alfa må være i området 0 til 1, og en ikke-null-verdi fører vanligvis til læring. Å finne en god verdi for eta vil avhenge av problemet, og også på verdien som er valgt for alfa. Hvis den er satt for lav, vil treningen være unødvendig sakte. Å ha det for stort vil føre til at vekten endres til å svinge vilt, og kan redusere eller til og med forhindre læring helt. (Jeg starter vanligvis med å prøve eta 0.1 og utforske effektene av gjentatte ganger doble eller halvere den.) Den komplette treningsprosessen består av å gjenta ovennevnte vektoppdateringer for en rekke epoker (ved hjelp av en annen for sløyfe) til noen feilberegninger er oppfylt, for eksempel faller feilen under noe valgt lite nummer. (Merk at med sigmoider på utgangene, kan feilen bare nå nøyaktig null hvis vikene kommer til uendelig. Merk også at treningen kan bli sittende fast i et lokalt minimum av feilfunksjonen og aldri komme overalt det faktiske minimumet.) Så, vi må pakke inn den siste koden med noe som helst for (epoke 1 epok lt LARGENUMBER epoke) OVER KODE FOR EN ITERATION hvis (Feil lt SMALLNUMBER) pause Hvis treningsmønstrene presenteres i samme systematiske rekkefølge i hver epoke, er det mulig for vektoscillasjoner å forekomme. Det er derfor generelt en god ide å bruke en ny tilfeldig rekkefølge for treningsmønstrene for hver epoke. Hvis vi setter NumPatterns treningsmønsterindekser p i tilfeldig rekkefølge inn i en array ranpat. så er det bare et spørsmål om å erstatte vår treningsmønstersløype. Generering av tilfeldig array ranpat er ikke helt så enkelt, men følgende kode vil gjøre jobben. Naturligvis må man sette noen innledende nettvekter for å starte læringsprosessen. Å starte alle vektene ved null er vanligvis ikke en god ide, da det ofte er et lokalt minimum av feilfunksjonen. Det er normalt å initialisere alle vekter med små tilfeldige verdier. Hvis rando () er din favoritt tilfeldig talegeneratorfunksjon som returnerer en flat fordeling av tilfeldige tall i området 0 til 1, og smallwt er den maksimale absolutt størrelsen på innledningsvektene, vil en passende del av vektinitieringskoden være Merk, at det er en god ide å sette alle de første DeltaWeightene til null samtidig. Vi har nå nok kode for å sette sammen et fungerende nevralnettprogram. Jeg har kuttet og limt inn koden ovenfor i filen nn. c (som din nettleser lar deg lagre i din egen filplass). Jeg har lagt til standard inkluderer, erklært alle variablene, hardkodede standard XOR treningsdata og verdier for eta. alfa og smallwt. definert en over enkel rando (). lagt til noen utskriftserklæringer for å vise hva nettverket gjør, og pakket mye i en main (). Filen skal kompilere og kjøre på vanlig måte (for eksempel ved å bruke UNIX-kommandoene cc nn. c - O - lm - o nn og nn). Ive forlot mye for leseren å gjøre for å konvertere dette til et nyttig program, for eksempel: Les treningsdataene fra filen Tillat at parametrene (aa. Smallwt. NumHidden etc.) varieres i løpet av kjøretiden. og allokere dem minne under kjøretid. Lagre vekter til fil, og les dem igjen. Plotting av feil, utgangsaktiveringer, etc. under trening. Det finnes også mange nettverksvarianter som kan implementeres, for eksempel: Batch læring, i stedet for on - lineær læring Alternativ aktiveringsfunksjoner (lineær, tanh, etc.). Ekte (i stedet for binær) verdierte utganger krever lineære utgangsfunksjoner. Outputpk SumOpk DeltaOk Targetpk - Outputpk Kryss-Entropi-kostnadsfunksjon i stedet for Sum Squared Error Error - (Targetpk Log (Outputpk) 1.0 - Targetpk) logg (1.0 - Outputpk)) DeltaOk Targetpk - Outputpk Separat trening, validering og testsett Vektnedgang Regulering Men herfra er du selv. Jeg håper du fant denne siden nyttig. Denne siden vedlikeholdes av John Bullinaria. Sist oppdatert 18. november 2002. Forskeren og ingeniørerveiledningen til digital signalbehandling av Steven W. Smith, Ph. D. Kapittel 26: Neural Networks (og mer) Neural Network Architecture Mennesker og andre dyr behandler informasjon med nevrale nettverk. Disse er dannet fra trillioner av nevroner (nerveceller) som utveksler korte elektriske pulser som kalles actionpotensialer. Datamaskinalgoritmer som etterligner disse biologiske strukturer kalles formelt kunstige nevrale nettverk for å skille dem fra de dårlige tingene inne i dyrene. Imidlertid er de fleste forskere og ingeniører ikke dette formelle og bruker begrepet neuralt nettverk for å inkludere både biologiske og ikke-biologiske systemer. Neural network research er motivert av to ønsker: å oppnå bedre forståelse for menneskets hjerne, og å utvikle datamaskiner som kan håndtere abstrakte og dårlig definerte problemer. For eksempel har konvensjonelle datamaskiner problemer med å forstå tale og gjenkjenne folks ansikter. Til sammenligning gjør mennesker det svært godt med disse oppgavene. Mange forskjellige neurale nettverksstrukturer har blitt prøvd, noen basert på å etterligne hva en biolog ser under mikroskopet, noen basert på en mer matematisk analyse av problemet. Den mest brukte strukturen er vist i figur 26-5. Dette nevrale nettverket er dannet i tre lag, kalt inngangslaget, skjult lag og utgangslag. Hvert lag består av en eller flere noder. representert i dette diagrammet av de små sirkler. Linjene mellom nodene indikerer strømmen av informasjon fra en node til den neste. I denne spesielle typen av neuralt nettverk strømmer kun informasjonen fra inngangen til utgangen (det vil si fra venstre til høyre). Andre typer nevrale nettverk har mer intrikate forbindelser, for eksempel tilbakemeldingsbaner. Nodene til inngangslaget er passive. noe som betyr at de ikke endrer dataene. De mottar en enkelt verdi på deres inngang, og dupliserer verdien til sine flere utganger. Til sammenligning er nodene til skjult og utgangslaget aktive. Dette betyr at de modifiserer dataene som vist i figur 26-6. Variablene: X1 1, X1 2 8230 X1 15 holder dataene som skal evalueres (se figur 26-5). For eksempel kan de være pikselverdier fra et bilde, prøver fra et lydsignal, aksjekurspriser på påfølgende dager, osv. De kan også være utdataene fra en annen algoritme, slik som klassifiseringene i vårt eksempel på kreftoppdagelse: diameter, lysstyrke, kantskarphet, etc. Hver verdi fra inngangslaget dupliseres og sendes til alle de skjulte nodene. Dette kalles en fullt sammenkoblet struktur. Som vist i figur 26-6, blir verdiene som kommer inn i en skjult knute multiplisert med vekt. et sett med forutbestemte tall lagret i programmet. De vektede inngangene blir deretter lagt til for å produsere et enkelt nummer. Dette er vist i diagrammet ved symbolet, summen. Før du forlater noden, går dette nummeret gjennom en ikke-lineær matematisk funksjon kalt en sigmoid. Dette er en s-formet kurve som begrenser nodenes utgang. Dvs. inngangen til sigmoid er en verdi mellom - infin og infin, mens utgangen kun kan være mellom 0 og 1. Utgangene fra skjult lag er representert i flytdiagrammet (Fig 26-5) av variablene: X2 1, X2 2, X2 3 og X2 4. Like før, blir hver av disse verdiene duplisert og brukt til neste lag. De aktive nodene til utgangslaget kombinerer og modifiserer dataene for å produsere de to utgangsværdiene til dette nettverket, X3 1 og X3 2. Nevrale nettverk kan ha et hvilket som helst antall lag, og et hvilket som helst antall noder per lag. De fleste applikasjoner bruker trelagsstrukturen med maksimalt noen få hundre innmatingsnoder. Det skjulte laget er vanligvis omtrent 10 størrelsen på inngangslaget. I tilfelle måldeteksjon trenger utgangslaget bare en enkelt knutepunkt. Utgangen av denne noden er tersklet for å gi en positiv eller negativ indikasjon på målets tilstedeværelse eller fravær i inngangsdataene. Tabell 26-1 er et program for å utføre flytdiagrammet i figur 26-5. Hovedpunktet er at denne arkitekturen er veldig enkel og veldig generalisert. Det samme flytskjemaet kan brukes til mange problemer, uavhengig av deres spesielle egenskaper. Det neurale nettverks evne til å gi nyttig datapanulasjon ligger i riktig utvalg av vekter. Dette er en dramatisk avvik fra konvensjonell informasjonsbehandling der løsninger beskrives i trinnvise prosedyrer. For eksempel, tenk på et neuralt nettverk for å gjenkjenne objekter i et sonarsignal. Anta at 1000 prøver fra signalet er lagret i en datamaskin. Hvordan bestemmer datamaskinen om disse dataene representerer en ubåt, hval, undersjøisk fjell eller ingenting i det hele tatt. Konvensjonell DSP ville nærme seg dette problemet med matematikk og algoritmer, som korrelasjon og frekvensspektrumanalyse. Med et neuralt nettverk blir de 1000 prøvene enkelt innmatedt i inngangslaget, noe som resulterer i verdier som popper fra utgangslaget. Ved å velge riktige vekter kan utgangen konfigureres til å rapportere et bredt spekter av informasjon. For eksempel kan det være utganger for ubåt (yesno), hval (yesno), undersjøisk fjell (yesno) osv. Med andre vekter kan utgangene klassifisere gjenstandene som: metall eller ikke-metall, biologisk eller ikke-biologisk, fiende eller alliert, etc. Ingen algoritmer, ingen regler, ingen prosedyrer bare et forhold mellom inngang og utgang diktert av verdiene av de valgte vektene. Figur 26-7a viser nærmere på sigmoid-funksjonen, matematisk beskrevet av ligningen: Den nøyaktige formen på sigmoiden er ikke viktig, bare at den er en jevn grense. Til sammenligning gir en enkel terskel en verdi av en når x gt 0 og en verdi på null når x lt 0. Sigmoid utfører samme grunnleggende tersklingsfunksjon, men er også differensierbar. som vist i figur 26-7b. Mens derivatet ikke brukes i flytdiagrammet (figur 25-5), er det en kritisk del av å finne de riktige vektene som skal brukes. Mer om dette snart. En fordel ved sigmoiden er at det er en snarvei for å beregne verdien av derivatet: For eksempel, hvis x 0, så s (x) 0,5 (ved ekv. 26-1), og det første derivatet beregnes: s ( x) 0,5 (1-0,5) 0,25. Dette er ikke et kritisk konsept, bare et triks for å gjøre algebra kortere. Ville ikke det nevrale nettverket være mer fleksibelt hvis sigmoidet kunne justeres til venstre eller høyre, noe som gjør det sentrert på en annen verdi enn x 0 Svaret er ja, og de fleste nevrale nettverk tillater dette. Det er veldig enkelt å implementere en ekstra node er lagt til inngangslaget, med inngang som alltid har en verdi på en. Når dette multipliseres med det skjulte lagets vekter, gir det en bias (DC-offset) til hver sigmoid. Dette tillegget kalles en bias node. Det behandles det samme som de andre noder, bortsett fra den konstante inngangen. Kan nevrale nettverk bli laget uten sigmoid eller lignende ikke-linearitet For å svare på dette, se på trelagsnettverket i figur 26-5. Hvis sigmoider ikke var tilstede, ville de tre lagene kollapse til bare to lag. Med andre ord, summasjonene og vektene til de skjulte og utgående lagene kan kombineres til et enkelt lag, noe som resulterer i bare et tolags nettverk. Scientist and Engineers Guide til digital signalbehandling av Steven W. Smith, Ph. D. Kapittel 26: Neural Networks (og mer) Trening av Neural Network Neural Network Design kan best forklares med et eksempel. Figur 26-8 viser problemet vi vil angripe, identifisere individuelle bokstaver i et bilde av tekst. Denne mønstergenkjenningsoppgaven har fått mye oppmerksomhet. Det er lett nok at mange tilnærminger oppnår delvis suksess, men vanskelig nok at det ikke finnes noen perfekte løsninger. Mange vellykkede kommersielle produkter har vært basert på dette problemet, for eksempel: lesing av adressene på brev for postrute, dokumentoppføring i tekstbehandlere, etc. Det første trinnet i å utvikle et neuralt nettverk er å lage en database med eksempler. For tekstgjenkjenningsproblemet oppnås dette ved å skrive ut de store bokstaver: A, B, C, D 8230 Y, Z, 50 ganger på et ark. Deretter konverteres disse 1300 bokstavene til et digitalt bilde ved å bruke en av de mange skanneenheter som er tilgjengelige for personlige datamaskiner. Dette store digitale bildet deles da i små bilder på 10 x 10 piksler, som hver inneholder et enkelt brev. Denne informasjonen lagres som en 1,3 megabyte database: 1300 bilder 100 piksler per bilde 8 bits per piksel. Vi vil bruke de første 260 bildene i denne databasen for å trene det neurale nettverket (dvs. bestemme vektene), og resten for å teste ytelsen. Databasen må også inneholde en måte å identifisere brevet på i hvert bilde. For eksempel kan en ekstra byte legges til hvert 10times10 bilde, som inneholder bokstavene ASCII-kode. I en annen ordning kan plasseringen av hvert 10times10 bilde i databasen indikere hva brevet er. For eksempel kan bildene 0 til 49 alle være A, bilder 50-99 kan alle være en B osv. For denne demonstrasjonen vil det nevrale nettverket bli designet for en vilkårlig oppgave: avgjøre hvilken av de 10times10 bildene som inneholder en vokal. dvs. A, E, I, O eller U. Dette kan ikke ha noen praktisk anvendelse, men det illustrerer det neurale nettverks evne til å lære svært abstrakte mønstergenkjenningsproblemer. Ved å inkludere ti eksempler på hvert brev i treningssettet, vil nettverket (forhåpentligvis) lære de viktigste funksjonene som skiller målet fra ikke-målrettede bilder. Det nevrale nettverket som brukes i dette eksempel er den tradisjonelle trelags, fullt sammenkoblede arkitektur, som vist i fig. 26-5 og 26-6. Det er 101 noder i inngangslaget (100 pikselverdier pluss en forspenningskode), 10 noder i det skjulte laget og 1 node i utgangslaget. Når et 100 pikslerbilde blir brukt på inngangen til nettverket, vil vi at utdataverdien skal være nær en hvis en vokal er tilstede, og nær null hvis en vokal ikke er tilstede. Ikke vær bekymret for at inngangssignalet ble kjøpt som et todimensjonalt array (10times10), mens inngangen til det nevrale nettverket er et endimensjonalt array. Dette er din forståelse av hvordan pikselverdiene er sammenhengende. Det neurale nettverket vil finne egne forhold. Tabell 26-2 viser hovedprogrammet for beregning av nevrale nettvekt, med tabell 26-3 som inneholder tre delrutiner som kalles fra hovedprogrammet. Arteringselementene: X11 til X1100, hold innstillingsverdiene. I tillegg har X1101 alltid en verdi på 1, som gir inngangen til biasnoden. Utdataverdiene fra de skjulte knutepunktene finnes i arrayelementene: X21 til X210. Variabelen, X3, inneholder nettverksutgangsverdien. Vektene til det skjulte laget er inneholdt i gruppen WH. , der den første indeksen identifiserer den skjulte noden (1 til 10), og den andre indeksen er inngangslagsnoden (1 til 101). Vektene til utgangslaget holdes i WO1 til WO10. Dette gir totalt 1020 vektverdier som definerer hvordan nettverket skal fungere. Programmets første handling er å sette hver vekt til en vilkårlig startverdi ved å bruke en tilfeldig talegenerator. Som vist i linjene 190-240, blir de skjulte lagvektene tilordnet innledende verdier mellom -0.0005 og 0.0005, mens utgangslagsvektene er mellom -0,5 og 0,5. Disse områdene er valgt for å være av samme størrelsesorden som de endelige vekter må være. Dette er basert på: (1) rekkevidden av verdier i inngangssignalet, (2) antall innganger summet på hver knute, og (3) rekkevidden av verdier over hvilke sigmoidet er aktivt, en inngang på ca. -5 lt x lt 5 og en utgang på 0 til 1. For eksempel når 101 innganger med en typisk verdi på 100 multipliseres med den typiske vektverdien på 0,0002, er summen av produktene ca. 2, som er i det aktive området av sigmoidsinngangen. Hvis vi vurderte ytelsen til det neurale nettverket ved hjelp av disse tilfeldige vektene, ville vi forvente at det skulle være det samme som tilfeldig gjetning. Læringsalgoritmen forbedrer ytelsen til nettverket ved gradvis å endre hver vekt i riktig retning. Dette kalles en iterativ prosedyre, og styres i programmet ved FOR-NEXT-sløyfen i linjene 270-400. Hver iterasjon gjør vikene litt mer effektive til å skille målet fra ikke-målgruppen. Itereringssløyfen utføres vanligvis til det ikke gjøres ytterligere forbedringer. I typiske nevrale nettverk kan dette være alt fra ti til ti tusen iterasjoner, men noen få hundre er vanlige. Dette eksemplet utfører 800 iterasjoner. For at denne iterative strategien skal fungere, må det være en enkelt parameter som beskriver hvor godt systemet er i bruk. Den variable ESUM (for feil sum) tjener denne funksjonen i programmet. Den første handlingen i itereringssløyfen er å stille ESUM til null (linje 290) slik at den kan brukes som en akkumulator. På slutten av hver iterasjon skrives verdien av ESUM ut på skjermen (linje 380), slik at operatøren kan forsikre seg om at fremdriften blir gjort. Verdien av ESUM vil starte høyt og gradvis reduseres ettersom det neurale nettverket er opplært for å gjenkjenne målene. Figur 26-9 viser eksempler på hvordan ESUM avtar når iterasjonene fortsetter. Alle 260 bilder i treningssettet evalueres under hver iterasjon, som styrt av FOR-NEXT-sløyfen i linjene 310-360. Subroutine 1000 brukes til å hente bilder fra databasen med eksempler. Siden dette ikke er noe av særlig interesse her, vil vi kun beskrive parametrene som er overført til og fra denne underrutinen. Subrutinen 1000 er oppgitt med parameteren LETTER, som er mellom 1 og 260. Ved retur, inneholder inngangsnodeverdiene, X11 til X1100, pikselverdiene for bildet i databasen som svarer til LETTER. Forspenningsverdien, X1101, returneres alltid med en konstant verdi av en. Subrutinen 1000 returnerer også en annen parameter, KORREKT. Dette inneholder ønsket utdataverdi for nettverket for dette bokstaven. Det vil si at hvis brevet i bildet er vokal, vil KORREKT returneres med en verdi på en. Hvis brevet i bildet ikke er vokal, vil KORREKT returneres med en verdi på null. Etter at bildet som ble bearbeidet er lastet inn i X11 til X1100, passerer subrutinen 2000 dataene gjennom det nåværende nevrale nettverket for å produsere utgangsnodeverdien, X3. Med andre ord er subrutine 2000 det samme som programmet i tabell 26-1, med unntak av et annet antall noder i hvert lag. Denne subrutinen beregner også hvor godt det nåværende nettverket identifiserer brevet som et mål eller et ikke-mål. I linje 2210 beregnes variabelen ELET (for feilbrev) som forskjellen mellom utgangsverdien som faktisk er generert, X3 og ønsket verdi, KORREKT. Dette gjør ELET til en verdi mellom -1 og 1. Alle 260-verdiene for ELET er kombinert (linje 340) for å danne ESUM, den totale kvadratfeilen til nettverket for hele treningssettet. Linje 2220 viser et alternativ som ofte inkluderes ved beregning av feilen: Tilordne en annen betydning for feilene for mål og mål. For eksempel, husk det krefteksempel som ble presentert tidligere i dette kapitlet, og konsekvensene av å lage en falsk positiv feil i motsetning til en falsk-negativ feil. I det nåværende eksemplet erklærer vi vilkårlig at feilen i å oppdage et mål er fem ganger så ille som feilen i å oppdage en nontarget. I virkeligheten forteller dette nettverket å gjøre en bedre jobb med målene, selv om det gjør vondt i nontargets ytelse. Subroutine 3000 er hjertet av den nevrale nettverksstrategien, algoritmen for å endre vektene på hver iterasjon. Vi vil bruke en analogi for å forklare den underliggende matematikken. Tenk på situasjonen for en militær soldatskytter som droppet bak fiendens linjer. Han faller til bakken i ukjent territorium, bare for å finne det er så mørkt, kan han ikke se mer enn noen få meter unna. Hans ordrer er å gå videre til bunnen av nærmeste dal for å starte resten av sitt oppdrag. Problemet er uten å være i stand til å se mer enn noen få meter, hvordan gjør han veien til dalen. På en annen måte trenger han en algoritme til å justere sin x - og y-posisjon på jordoverflaten for å minimere sin høyde . Dette er analog med problemet med å justere de nevrale nettvektene, slik at nettverksfeilen, ESUM, minimeres. Vi vil se på to algoritmer for å løse dette problemet: evolusjon og brattest nedstigning. I evolusjonen tar paratrooper et flygende hopp i noen tilfeldig retning. Hvis den nye høyden er høyere enn den forrige, forbanner han og går tilbake til startstedet der han prøver igjen. Hvis den nye høyden er lavere. han føler seg et mål for suksess, og gjentar prosessen fra det nye stedet. Til slutt kommer han til bunnen av dalen, men i en svært ineffektiv og tilfeldig sti. Denne metoden kalles evolusjon fordi den er den samme typen algoritme som brukes av naturen i biologisk evolusjon. Hver ny generasjon av en art har tilfeldige variasjoner fra det forrige. Hvis disse forskjellene er til nytte for arten, er de mer sannsynlig å bli beholdt og videreført til neste generasjon. Dette er et resultat av forbedringen som gjør at dyret kan motta mer mat, unnslippe sine fiender, produsere flere avkom, etc. Hvis det nye trekket er skadelig, blir det ugunstige dyret lunsj for noen rovdyr, og variasjonen blir kassert. I denne forstand er hver ny generasjon en iterasjon av den evolusjonære optimaliseringsprosedyren. Når evolusjon brukes som treningsalgoritme, blir hver vekt i det nevrale nettverket litt endret ved å legge til verdien fra en tilfeldig talgenerator. Hvis de modifiserte vekter gir et bedre nettverk (dvs. en lavere verdi for ESUM), blir endringene beholdt, ellers blir de kassert. Mens dette virker, er det veldig sakte i konvergering. Dette er sjargongen som brukes til å beskrive at kontinuerlig forbedring gjøres mot en optimal løsning (bunnen av dalen). I enklere termer skal programmet trenge dager for å nå en løsning, i stedet for minutter eller timer. Heldigvis er den bratteste nedstigningsalgoritmen mye raskere. Dette er hvordan paratroperen naturlig ville reagere: vurdere hvilken vei som er nedoverbakke. og beveg deg i den retningen. Tenk på situasjonen på denne måten. Paratroperen kan bevege seg ett skritt mot nord og registrere endringen i høyde. Etter å ha kommet tilbake til sin opprinnelige posisjon, kan han ta ett skritt mot øst og registrere den hevningsendringen. Ved å bruke disse to verdiene kan han bestemme hvilken retning som er nedoverbakke. Anta at fallskjermen faller 10 cm når han beveger seg ett skritt i nordretningen og faller 20 cm når han beveger seg ett skritt i østretningen. For å reise direkte nedoverbakke, må han bevege seg langs hver akse et forhold som er proporsjonalt med skråningen langs den aksen. I dette tilfellet kan han bevege seg nordover med 10 trinn og øst ved 20 trinn. Dette beveger ham nedover den bratteste delen av bakken en avstand av radikale 10 2 20 2 trinn. Alternativt kunne han bevege seg i en rett linje til den nye plasseringen, 22,4 trinn langs diagonalen. Hovedpunktet er: Den bratteste nedstigningen oppnås ved å bevege seg langs hver akse en avstand som er proporsjonal med hellingen langs den aksen. Subroutine 3000 implementerer den samme bratteste anstendig algoritmen for nettverksvektene. Before entering subroutine 3000, one of the example images has been applied to the input layer, and the information propagated to the output. This means that the values for: X1 , X2 and X3 are all specified, as well as the current weight values: WH. and WO . In addition, we know the error the network produces for this particular image, ELET. The hidden layer weights are updated in lines 3050 to 3120, while the output layer weights are modified in lines 3150 to 3190. This is done by calculating the slope for each weight, and then changing each weight by an amount proportional to that slope . In the paratrooper case, the slope along an axis is found by moving a small distance along the axis (say, Delta x ), measuring the change in elevation (say, Delta E ), and then dividing the two (Delta E Delta x ). The slope of a neural network weight can be found in this same way: add a small increment to the weight value (Delta w ), find the resulting change in the output signal (Delta X3 ), and divide the two (Delta X3 Delta w ). Later in this chapter we will look at an example that calculates the slope this way. However, in the present example we will use a more efficient method. Earlier we said that the nonlinearity (the sigmoid) needs to be differentiable . Here is where we will use this property. If we know the slope at each point on the nonlinearity, we can directly write an equation for the slope of each weight (Delta X3 Delta w) without actually having to perturb it. Consider a specific weight, for example, WO1, corresponding to the first input of the output node. Look at the structure in Figs. 26-5 and 26-6, and ask: how will the output ( X3 ) be affected if this particular weight ( w ) is changed slightly, but everything else is kept the same The answer is: where SLOPE O is the first derivative of the output layer sigmoid, evaluated where we are operating on its curve. In other words, SLOPE O describes how much the output of the sigmoid changes in response to a change in the input to the sigmoid. From Eq. 26-2, SLOPE O can be calculated from the current output value of the sigmoid, X3. This calculation is shown in line 3160. In line 3170, the slope for this weight is calculated via Eq. 26-3, and stored in the variable DX3DW (i. e. Delta X3 Delta w). Using a similar analysis, the slope for a weight on the hidden layer, such as WH1,1, can be found by: SLOPE H1 is the first derivative of the hidden layer sigmoid, evaluated where we are operating on its curve. The other values, X11 and WO1, are simply constants that the weight change sees as it makes its way to the output. In lines 3070 and 3080, the slopes of the sigmoids are calculated using Eq. 26-2. The slope of the hidden layer weight, DX3DW is calculated in line 3090 via Eq. 26-4. Now that we know the slope of each of the weights, we can look at how each weight is changed for the next iteration. The new value for each weight is found by taking the current weight, and adding an amount that is proportional to the slope: This calculation is carried out in line 3100 for the hidden layer, and line 3180 for the output layer. The proportionality constant consists of two factors, ELET, the error of the network for this particular input, and MU, a constant set at the beginning of the program. To understand the need for ELET in this calculation, imagine that an image placed on the input produces a small error in the output signal. Next, imagine that another image applied to the input produces a large output error. When adjusting the weights, we want to nudge the network more for the second image than the first. If something is working poorly, we want to change it if it is working well, we want to leave it alone. This is accomplished by changing each weight in proportion to the current error, ELET. To understand how MU affects the system, recall the example of the paratrooper. Once he determines the downhill direction, he must decide how far to proceed before reevaluating the slope of the terrain. By making this distance short, one meter for example, he will be able to precisely follow the contours of the terrain and always be moving in an optimal direction. The problem is that he spends most of his time evaluating the slope, rather than actually moving down the hill. In comparison, he could choose the distance to be large, say 1000 meters. While this would allow the paratrooper to move rapidly along the terrain, he might overshoot the downhill path. Too large of a distance makes him jump all over the country-side without making the desired progress. In the neural network, MU controls how much the weights are changed on each iteration. The value to use depends on the particular problem, being as low as 10 -6. or as high as 0.1. From the analogy of the paratrooper, it can be expected that too small of a value will cause the network to converge too slowly. In comparison, too large of a value will cause the convergence to be erratic, and will exhibit chaotic oscillation around the final solution. Unfortunately, the way neural networks react to various values of MU can be difficult to understand or predict. This makes it critical that the network error (i. e. ESUM) be monitored during the training, such as printing it to the video screen at the end of each iteration. If the system isnt converging properly, stop the program and try another value for MU.

No comments:

Post a Comment