Neurale netwerken in de praktijk Deel 1: Een inleiding in neurale netwerken Inleiding Neurale netwerken zijn een bekende vorm van kunstmatige intelligentie (Artificial Intelligence, AI). De werking berust op dezelfde principes als die van de menselijke hersenen en daarom denken veel onderzoekers in de Al dat neurale netwerken de beste kansen bieden om ooit intelligente machines te kunnen bouwen. Star-Trek-fans weten natuurlijk dat ook het brein van de menselijke robot Data een neuraal netwerk is. Hetzelfde geldt voor de robot in de Terminator-films. Neurale netwerken worden gebruikt in het meest geavanceerde onderzoek naar kunstmatige intelligentie. Het leuke is dat ze tamelijk eenvoudig te maken zijn en daardoor ook heel geschikt voor experimenten. Het doel van deze serie artikelen is om de lezer op een praktische manier te introduceren in deze fascinerende wereld. We beperken ons niet tot de theorie. We gaan aan de slag met ons eigen neurale netwerk! Wat is een neuraal netwerk? Een neuraal netwerk is een netwerk van onderling verbonden processors. De processors waaruit het netwerk is opgebouwd, zijn heel simpel. Ze voeren een eenvoudige mathematische bewerking uit. De kracht van het netwerk ligt in de samenwerking van een groot aantal van deze processors. Daardoor wordt zeer complex gedrag mogelijk. In figuur 1 is de opbouw van een eenvoudig neuraal netwerk weergegeven. Onze hersenen De wetenschappelijke naam van hersencellen is neuronen. Dit zijn de levende cellen waaruit onze hersenen en ons zenuwstelsel zijn opgebouwd. Het menselijk lichaam bevat zo'n 100 miljard neuronen. Elk neuron is een kleine elektrische processor. In figuur 2 is te zien hoe een neuron er uit ziet onder de microscoop. De dendrieten ontvangen signalen van andere neuronen of uit de buitenwereld. Dat is de 'input-kant' van het neuron. Als de dendrieten voldoende gestimuleerd worden, genereert het cellichaam een elektrische impuls die via het axon wordt doorgegeven aan andere neuronen of aan spieren, die daardoor gestimuleerd worden. Het axon is dus de 'output-kant' van het neuron. Hoe sterker het neuron wordt gestimuleerd via de dendrieten, hoe meer elektrische impulsen het per seconde zal produceren (zie figuur 3). We zeggen dat de informatie in ons zenuwstelsel wordt overgedragen via frequentiemodulatie. Sommige neuronen zijn gespecialiseerd in het ontvangen van informatie uit de omgeving. Een voorbeeld daarvan zijn de kegeltjes en staafjes in het menselijke netvlies. Via hun axonen sturen deze cellen de informatie verder naar onze hersenen. In de hersenen wordt de informatie verwerkt door neuronen die alleen met andere neuronen verbonden zijn, de zogenaamde interneuronen. Uiteindelijk komt de informatie terecht bij neuronen die onze spieren besturen, de zogenaamde motorische neuronen. Het axon van de motorische neuronen is verbonden met onze spieren en klieren. Zo ontvangen we informatie uit de buitenwereld, verwerken die en reageren er op. Alle informatieverwerking in ons lichaam werkt op deze zelfde manier, van de reflexen tot en met ons bewustzijn. De uitvinding van het kunstmatige neurale netwerk In 1943 publiceerden Warren McCulloch en Walter Pitts een artikel dat het begin vormde van het hele onderzoek naar kunstmatige neurale netwerken. In dat artikel beschreven ze een simpel model van een neuron en de opbouw van een netwerk van neuronen, waarop zelfs de modernste kunstmatige neurale netwerken gebaseerd zijn. In de loop der tijd zijn wel enkele verbeteringen aangebracht, maar het basisprincipe is hetzelfde gebleven. Dit is weergegeven in figuur 4. In figuur 4 zien we een neuron met vier ingangen i1 ... i4. Deze ingangen spelen dezelfde rol als de dendrieten in het biologische neuron. Ze vormen de verbinding met de buitenwereld en/of met andere neuronen. Bij elke input hoort een 'weegfactor', hier aangeduid met Wj tot en met w4. De weegfactoren geven aan hoe sterk de input gekoppeld is met het cellichaam. In werkelijkheid hoeven er niet precies vier ingangen te zijn: Elk aantal is mogelijk. De werking is als volgt. Alle ingangssignalen worden vermenigvuldigd met hun eigen weegfactor en daarna bij elkaar opgeteld: Sum =(i1 x w1) + (i2 x w2) + (13 x w3) + (i4 x w4) Als we het kunstmatige neuron vergelijken met een biologisch neuron, dan stelt deze som de mate voor waarin het neuron gestimuleerd wordt. Komt de som boven een bepaalde drempelwaarde, dan wordt de output '1', anders '0'. Als de drempelwaarde bijvoorbeeld 0,5 is, dan ziet dit er in een programma als volgt uit: If Sum > 0.5 then Output = 1 Else Output = 0 Endif Dit lijkt op een biologisch neuron dat een puls uitzendt als het sterk genoeg gestimuleerd wordt. Laten we eens een praktisch voorbeeld bekijken. Stel dat we een neuron hebben zoals afgebeeld in figuur 5. Met de gegeven waarden voor de weegfactoren kunnen we uitrekenen wat de output zou moeten zijn als we uitgaan van een drempelwaarde van 0,5: Sum = (0,1 x 0,5) + (0,5 x 0,2) + (0,3 x 0,1) = 0,18 Omdat 0,18 minder is dan de drempelwaarde van 0,5, zal de output '0' zijn. Wat is het nut? We hebben nu dus een model gemaakt van een neuron, Maar wat kunnen we daar mee doen? In figuur 6a zien we een patroon van vierkantjes. Stel nu dat we dit patroon willen herkennen. We coderen de donkere vlakken als '1' en de lichte als '0'. Als we nu een neuron aansluiten zoals in figuur 6b, dan zal dat een T aan de uitgang produceren bij dit patroon. Dat blijft werken als de donkere vlakken niet precies '1' zijn en de lichte vlakken niet precies '0'. Het neuron tolereert enige storing aan de ingang. Maar als we een heel ander patroon aanbieden, zoals in figuur 6c, dan produceert het neuron een 0 aan de uitgang. Dat patroon wordt niet herkend. Het herkennen van patronen, ook als ze niet 100 % perfect zijn, is één van de basiskenmerken van intelligentie. Dieren moeten in staat zijn om voedsel, partners en roofdieren te herkennen om te kunnen overleven in de natuur. Als we intelligentie willen nabootsen, dan is het herkennen van patronen dus essentieel. En dat is precies waar neurale netwerken in uitblinken. In het bovenstaande voorbeeld ging het om een patroon in de ruimte, maar ook patronen in de tijd kunnen herkend worden, als ze op de juiste manier aan het netwerk worden aangeboden. Leren! Uit het voorbeeld bleek ook dat de juiste weegfactoren nodig zijn om tot goede resultaten te komen. Het zijn de weegfactoren, die bepalen wat het netwerk zal herkennen. De vraag is natuurlijk, hoe we de juiste weegfactoren moeten bepalen. In het voorbeeld waren de weegfactoren met de hand ingesteld door logisch denken. Voor het herkennen toren van dit simpele patroon was dat wel te doen Maar als we een netwerk willen maken, dat honderden verschillende patronen kan herkennen, dan komen we er op deze manier niet uit. Eigenlijk willen we, dat de weegfactoren automatisch ingesteld worden, zonder hulp van buitenaf. Zo gebeurt het ook in de natuur. Dat noemen we leren. Mensen en dieren leren door ervaring, zonder dat er iemand anders aan hun weegfactoren sleutelt. Om dat in een kunstmatig neuraal netwerk voor elkaar te krijgen, is een leeralgoritme nodig. Een eenvoudig leeralgoritme voor het herkennen van het patroon in figuur 6a kan er als volgt uit zien: If output is correct then doe niets If output is ten onrechte hoog then verlaag de weegfactoren van de inputs die hoog zijn If output is ten onrechte laag then verhoog de weegfactoren van de inputs die hoog zijn Meestal wordt begonnen met de weegfactoren te initialiseren op willekeurige waarden. De volgende artikelen in deze serie zullen vooral gaan over verschillende methoden om het netwerk te trainen. Een paar dingen zijn belangrijk om hier op te merken. Ten eerste kunnen we door de juiste weegfactoren in te stellen vrijwel elke logische schakeling opbouwen, die we willen. Het netwerk is dus niet alleen maar een hulpmiddel om dingen te herkennen. De mogelijkheden zijn veel groter. In feite kan zo'n netwerk gezien worden als een trainbare combinatorische schakeling. Ten tweede hoeven we ons niet te beperken tot simpele binaire uitgangssignalen (nul of één), zoals we tot nu toe gebruikt hebben. Tegenwoordig wordt meestal gebruik gemaakt van de 'Sigmoid'-functie voor de outputs van de neuronen. De Sigmoid-functie is als volgt gedefinieerd: output= 1 1 e− Som In het voorbeeld van figuur 5 zou de output dus gelijk zijn aan: output= 1 1 e− 0,18 Deze functie geeft altijd een output tussen 0 en 1 (plot de functie met een grafische rekenmachine of een functieplotter). Dat lijkt dus sterk op een simpel binair signaal. Maar wat is dan het nut van die functie? Dat wordt duidelijk als we denken aan het herkennen van patronen die sterk op elkaar lijken. Doordat de output elke waarde tussen 0 en 1 kan aannemen, is het neuron in staat om twijfel of onzekerheid uit te drukken. De output wordt niet ondubbelzinnig '0'of '1', maar zweeft daar ergens tussen in. Dit is weergegeven in figuur 7. Neuronen in netwerken Nadat McCulloch en Pitts voor het eerst hadden gepubliceerd over neurale netwerken, werden ze door veel onderzoekers met groot succes toegepast. Totdat er in 1969 een boek uitkwam, waarin neurale netwerken bekritiseerd werden. Dit boek heette 'Perceptrons' en was geschreven door Marvin Minsky en Seymour Papert. Het boek wees op een tekortkoming van neuronen. Zoals al eerder vermeld, kan een neuron bijna elke logisch functie vervullen door de juiste weegfactoren in te stellen. Maar één functie kunnen neuronen niet nabootsen: De Exclusive Or (XOR), zie figuur 8. Dit bezwaar tegen neuronen hield, in combinatie met andere tegenwerpingen in het boek, de vooruitgang in neurale netwerken jarenlang tegen. Veel wetenschappers verlegden hun onderzoek naar andere gebieden, omdat neuronen blijkbaar niet krachtig genoeg waren, als ze zo'n simpele functie niet konden uitvoeren. Toch was er een oplossing voor dit probleem. Hoewel één neuron geen XOR-functie kan uitvoeren, lukt dat heel goed als meerdere neuronen samenwerken in een netwerk. De Russische wiskundige Kolmogorov kwam zelfs met het bewijs dat een neuraal netwerk met drie lagen (zoals weergegeven in figuur 9) voldoende is om elke denkbare logische functie uit te voeren. Ondanks dat duurde het nog tot 1982/83 voordat het onderzoek naar neurale netwerken weer goed op gang kwam. In die tijd werd het 'Back Propagation Algorithm' (dat in deel 2 aan de orde zal komen) gepubliceerd. Bovendien kwamen er krachtige computers op de markt tegen betaalbare prijzen. En John Hopfield publiceerde zijn beroemde artikel dat in deel 3 aan de orde zal komen. De neuronen in een netwerk werken precies hetzelfde als de individuele neuronen die we al bekeken hebben. Laten we het netwerk in figuur 10 eens doorrekenen. De neuronen zijn in dit geval Sigmoid-neuronen. Neuron 1: (0,2 x 0,5) + (0,4 x 0,8) = 0,42 Output =1/(1+ e^-0,42) = 0,603 Neuron 2: (0,2x0,1) + (0,4x0,9) = 0,38 Output = 1 / (1 + e^-0,38) = 0,594 Laatste neuron: (0,594 x 0,7) + (0,603 x 0,5) = 0,717 Output = 1 / (1 + e^0.717) = 0,672 Doorrekenen van een netwerk Met een simpel algoritme kunnen we de computer dit netwerk laten doorrekenen: 1. 2. 3. 4. Initialiseer alle weegfactoren en uitgangen op 0. Vul de ingangssignalen met de gewenste waarden. In dit geval zijn dat dus 0(1,1) en 0(1,2). Vul array W met de gewenste weegfactoren. Bereken de output van het netwerk. Zie listing 1. De hier beschreven oplossing is maar één van de vele manieren waarop een neuraal netwerk kan worden weergegeven in het geheugen van de computer. Een andere, misschien iets flexibelere manier om de weegfactoren op te slaan, is gebruik te maken van een tweedimensionaal array: Weights[bron_neuron, doel_neuron] De neuronen kunnen we dan voorstellen door een simpel eendimensionaal array: Output[neuron_nummer] Het netwerk dat zo opgebouwd wordt, zou er dan uitzien zoals in figuur 13. In dit geval zijn O(1) en O(2) de inputs en 0(5) is de output. Het algoritme zal er dan als volgt uitzien: 1. Initialiseer alle weegfactoren en uitgangen op 0. 2. Vul de ingangssignalen in. In dit geval dus O(1) en O(2). 3. Vul array W met de gewenste weegfactoren. 4. Bereken de output van het netwerk. Zie listing 2. De berekening kan in vrijwel elke programmeertaal geïmplementeerd worden. En elke taal biedt zijn eigen voordelen: Sommige talen (zoals Delphi en C + + ) maken het mogelijk om de grootte van de arrays dynamisch te bepalen. Dat kan handig zijn bij het werken met ingewikkelde netwerken die van grootte veranderen. Andere talen, zoals Fortran en Matlab, bieden ondersteuning voor matrixvermenigvuldigingen. Dat kan het programmeren een stuk gemakkelijker maken, omdat het hele programma dan kan worden geschreven in de vorm van matrix-vergelijkingen. Object-georiënteerde talen maken het mogelijk om neuronen en netwerken te definiëren als objecten en de kenmerken van de neuronen kunnen dan automatisch worden overgedragen aan het hele netwerk (overerven). In assembler-talen is het mogelijk om de weegfactoren en uitgangssignalen rechtstreeks aan geheugenlocaties toe te wijzen. Het doorrekenen van het netwerk zoals hierboven beschreven, is maar een deel van het werk. We noemen dit de voorwaartse berekening ('Forward Pass'). De volgende stap is het bepalen van nieuwe weegfactoren, zodat het netwerk kan leren en bij de volgende Forward Pass betere resultaten kan opleveren. Dat is de achterwaartse berekening ('Reverse Pass'). In het volgende deel van deze serie zullen we aandacht besteden aan deze Reverse Pass. Om te beginnen komt dan de meest bekende methode aan bod om de weegfactoren te bepalen, het zogenaamde 'Back Propagation Algoiithm'. Neurale Netwerken in de praktijk Deel 2: Netwerken met 'Back Propagation' De neurale netwerken die in de praktijk gebruikt worden, werken bijna altijd met 'Back Propagation'. We spreken dan van Back Propagation (BP) netwerken, maar in feite wordt de Back Propagation alleen gebruikt bij het leren. Deze naam zegt dus niets over de structuur van het netwerk zelf. Het netwerk zelf werkt precies zoals dat in deel 1 beschreven werd: Er worden stimuli aangebracht op de ingangen, waarna het netwerk wordt doorgerekend om het resultaat aan de uitgangen te bepalen. Back Propagation wordt gebruikt voor het wijzigen van de weegfactoren in het netwerk. Daardoor kan het netwerk leren en zal het na voldoende training de uitgangssignalen produceren die we willen. Als beginwaarde stellen we alle weegfactoren in op kleine, willekeurige getallen, bijvoorbeeld tussen -1 en +1. Het nut van BP Back Propagation is heel geschikt voor simpele patroonherkenning en classificatie. Bij gebruik van BP leert het netwerk aan de hand van voorbeelden. Een veelgebruikte toepassing is bijvoorbeeld het herkennen van tekst. We hoeven het systeem alleen maar te voorzien van voorbeelden van de te herkennen lettertekens en de uitvoer die we daarbij willen zien. Het netwerk leert dan, zoals weergegeven in figuur 1. Het BP-algoritme werkt door een fout te berekenen. De fout is het verschil tussen de bedoelde output (die we dus zelf kunnen kiezen) en de werkelijke output. Telkens als het BP-algoritme wordt toegepast, worden de weegfactoren zo aangepast dat deze fout verkleind wordt. Als het netwerk eenmaal getraind is, zal het de juiste uitvoer produceren wanneer een letterteken wordt aangeboden, zelfs als dat ingevoerde letterteken niet precies gelijk is aan de letters die bij het leren zijn gebruikt. Het netwerk heeft geen last van kleine vervormingen, ruis of andere vormen van storing in het ingangssignaal. Structuur van het netwerk In figuur 2 zien we een voorbeeld van een netwerk voor patroonherkenning. Het aantal ingangen wordt in dit geval bepaald door het aantal pixels in het te herkennen patroon. Omdat dit netwerk een output van twee bits moet genereren, hebben we twee uitgangsneuronen nodig. Als we willen dat een netwerk acht verschillende patronen herkent, dan kunnen we er voor kiezen om voor elk patroon één uitgangsneuron te gebruiken. Voor elk patroon is het dan de bedoeling dat één uitgangsneuron een '1' produceert en de rest een '0'. Elk uitgangsneuron correspondeert met één van de te herkennen patronen. We kunnen ook kiezen voor een binaire codering aan de uitgang en dan kunnen we met drie uitgangsneuronen volstaan. Het aantal ingangen en uitgangen van het netwerk wordt dus bepaald door de toepassing. Maar het is niet zo eenvoudig om het aantal neuronen in de verborgen laag te kiezen. Gelukkig komt dat niet zo nauw. Het blijkt dat neurale netwerken goed werken als er maar 'voldoende' neuronen in de verborgen laag zitten. Een netwerk dat veel verschillende patronen moet herkennen, heeft meer neuronen in de verborgen laag nodig dan een netwerk dat weinig patronen hoeft te herkennen. Als we alle 26 letters van het alfabet willen herkennen in symbolen die worden weergegeven in een matrix van 5x7 beeldpunten (dus 35 ingangen), dan lukt dat met tenminste 6 en ten hoogste 22 neuronen in de verborgen laag. Als er te weinig neuronen in de verborgen laag zitten, dan heeft het netwerk niet genoeg weegfactoren om de informatie op te slaan. Maar ook een teveel aan neuronen in deze laag is niet goed. Het spreekt vanzelf dat het niet efficiënt is om meer neuronen te gebruiken dan noodzakelijk, maar het leidt er ook toe dat het netwerk minder goed gaat werken. In een te groot netwerk is de kans op het optreden van lokale minima groter. Op dat probleem gaan we verderop in dit artikel nog in. Het BP-algoritme Het BP-algoritme dient dus voor het bepalen van de juiste weegfactoren in het netwerk. Om te begrijpen hoe dat in zijn werk gaat, bekijken we de drie neuronen A, B en C in figuur 3. De weegfactor tussen neuron A en B is in de figuur weergegeven als WAB. Het BP-algoritme werkt voor deze weegfactor als volgt: stap 1 Eerst worden de ingangssignalen aangeboden en wordt het netwerk doorgerekend zoals in deel 1 is besproken. Dat is de forward pass. Stap 2 Dan wordt de fout van neuron B berekend. Dat is het verschil tussen de gewenste output en de werkelijke output. Met andere woorden: Wat je wilt -Wat je krijgt. In formulevorm: FoutB = OutputB x (1 - OutputB) x (TargetB - OutputB) Hierin is OutputB de berekende waarde van neuron B en TargetB de gewenste waarde voor neuron B. De factor OutputB x (1 - OutputB) heeft te maken met de toegepaste Sigmoid-functie in het neuron. Bij een neuron dat niet werkt met de Sigmoid-functie, maar met een drempelwaarde, wordt deze factor niet gebruikt. stap 3 Bepaal de nieuwe weegfactor WAB. Deze wordt berekend uit de huidige weegfactor WAB, de berekende fout FoutB en het uitgangssignaal van neuron A (OutputA) volgens de formule: W+AB = WAB + ( FoutB OutputA We gebruiken dus de fout van het tweede neuron (B), en het uitgangssignaal van het eerste neuron (A), omdat de weegfactor WAB het verband tussen neuronen A en B voorstelt. De factor in de formule is de 'leersnelheid' van het netwerk. We kunnen die gewoon gelijk aan 1 kiezen, maar desgewenst kan het leerproces versneld worden door een waarde groter dan 1 te gebruiken. Met een waarde voor die kleiner is dan 1 kan het leerproces vertraagd worden. stap 4 Bepaal op dezelfde manier nieuwe weegfactoren voor alle neuronen in de uitgangslaag. Stap 5 Om nieuwe weegfactoren voor de neuronen in de verborgen laag te berekenen, moet eerst een foutwaarde voor deze neuronen bepaald worden. De moeilijkheid daarbij is dat we niet weten wat de gewenste output van deze neuronen is. Dit wordt opgelost door de foutwaarden van de uitgangsneuronen terug te rekenen naar foutwaarden voor de neuronen in de verborgen laag. Aan deze truc, het zogenaamde 'achterwaarts propageren', dankt het BP-algoritme zijn naam. De berekening (voor neuron A) gaat als volgt: FoutA = OutputA x (1 - OutputA) x (FoutB xWAB + FoutC xWAC) De factor OutputA x (1 - OutputA) heeft weer te maken met het gebruik van de Sigmoid-functie, net als bij stap 2. Stap 6 Nu de foutwaarden voor de verborgen laag berekend zijn, kunnen de nieuwe weegfactoren worden bepaald op dezelfde manier als besproken bij stap 3. Al met al is dit een behoorlijk ingewikkelde procedure. Daarom zullen we nu eerst een voorbeeld helemaal doorrekenen aan de hand van het netwerk dat is weergegeven in figuur 4. Toepassen van het BP-algoritme Nu we de theorie van het BP-algoritme kennen, kunnen we het gaan toepassen. Bij het trainen van een neuraal netwerk is een veelgemaakte fout dat het 'lesmateriaal' in de verkeerde volgorde aan het systeem wordt aangeboden. Als we bijvoorbeeld de eerste vier letters van het alfabet willen herkennen in bitpatronen in een 5x7-matrix, dan moeten de vier te herkennen letters om beurten worden aangeboden. Begin dus met het bitpatroon voor de letter A en voer het algoritme één keer uit. Doe daarna hetzelfde voor de letters B, C en D. Daarna begint het trainen opnieuw met de letter A. Dit is weergegeven in figuur 5. De training gaat door totdat de totale fout klein genoeg is. De totale fout is de som van de fouten van alle neuronen bij alle patronen. Bij het optellen moet er rekening mee gehouden worden dat de fout van de individuele neuronen zowel positief als negatief kan zijn. We streven naar een fout dicht bij 0. Een grote negatieve fout is even erg als een grote positieve fout. We tellen dus niet de foutwaarden zelf op, maar hun absolute waarde, of beter nog, hun kwadraat. Het kwadrateren is een simpele manier om er voor te zorgen dat alle fouten een positieve bijdrage leveren aan de uitkomst. Maar het zorgt er ook voor dat één grote fout zwaarder bestraft wordt dan vele kleintjes. Hoeveel 'klein genoeg' is, wordt door de gebruiker bepaald. Meestal wordt om te beginnen een klein getal gekozen, bijvoorbeeld 0,1. Een bruikbare waarde wordt door wat experimenteren bepaald. In het bovenstaande voorbeeld is de totale fout dus: (Foutbijdrage van alle neuronen bij het herkennen van de letter A) + (Foutbijdragen bij het herkennen van de letter B) + (Foutbijdragen bij de C) + (Bijdragen voor D). Het leerproces verloopt als volgt: 1. Bied het eerste patroon aan, doe de forward pass, doe de backward pass, sla de foutbijdragen op. 2. Bied het tweede patroon aan, doe de forward pass, doe de backward pass, sla de foutbijdragen op. 3. Bied het derde patroon aan, doe de forward pass, doe de backward pass, sla de foutbijdragen op. 4. Bied het vierde patroon aan, doe de forward pass, doe de backward pass, sla de foutbijdragen op. 5. Controleer het resultaat. Is de totale fout klein genoeg? Zo ja, ga dan naar stap 7. 6. Ga naar stap 1. 7. Stop: Het leerproces is voltooid. Een veelgemaakte fout is om eerst het eerste patroon steeds opnieuw aan te bieden, totdat de fout klein is, daarna het tweede, derde, enzovoort. Op die manier leert het netwerk alleen het laatst aangeboden patroon en het 'vergeet' daarbij de eerder aangeboden patronen. Na het leren kan het netwerk in gebruik genomen worden: Bied een patroon aan, doe alleen de forward pass met de bepaalde weegfactoren en gebruik het resultaat. Dat is de manier waarop het getrainde netwerk in de praktijk wordt gebruikt. Een nog betere manier om de totale fout te bepalen maakt gebruik van een zorgvuldig opgebouwde verzameling van testpatronen (een zogenaamde 'validation set'). Bij gebruik van een validation set wordt het netwerk getraind met behulp van de zuivere testpatronen, zoals hierboven beschreven. Maar de totale fout wordt bepaald door na het trainen de totale fout over de validation set te bepalen in plaats van de fout over de zuivere patronen. Als het leren voltooid is, zullen zowel de zuivere patronen als de validation set een kleine totale fout opleveren. Op een gegeven moment zal de totale fout een minimum bereiken. Het heeft geen zin om daarna door te gaan met leren. Het resultaat zal alleen maar slechter worden (zie figuur 6). Implementatie Zoals in deel 1 besproken, zijn er verschillende manieren om de parameters van een neuraal netwerk op te slaan. Eén manier was om de weegfactoren op te slaan in een driedimensionaal array met indices voor laag-, neuron- en verbindingsnummer. Bij gebruik van die opslagmethode zou het programma als volgt opgebouwd kunnen worden: 1. Initialiseer alle weegfactoren, targets, foutwaarden en outputs. 2. Bied een patroon aan op de ingangen en bereken het uitgangssignaal, zoals weergegeven in listing 1 bij deel 1 (dit is de forward pass). 3. Bereken de foutwaarden en de nieuwe weegfactoren, zoals weergegeven in listing 1 bij deel 2 (dat is de backward pass). Naast een array met weegfactoren zijn er ook arrays nodig voor het opslaan van de foutwaarden en de targets. In listing 1 zijn dat respectievelijk E(L,n) en T(L,n). Index L geeft daarin het laagnummer weer en index n het neuronnummer. Programma voor het trainen van een netwerk bevat naast de hierboven omschreven implementatie ook voorzieningen voor het aanbieden van trainingsdata en het bewaren van de resultaten. Zo'n programma kan als volgt opgebouwd worden: 1. Bepaal de aan te bieden patronen en de bijbehorende targets en sla die op in een file of in arrays. 2. Initialiseer alle weegfactoren met kleine willekeurige getallen. 3. Bied het eerste patroon aan. bereken het resultaat (forward pass), bereken de foutwaarden en de nieuwe weegfactoren (backward pass). Bewaar de totale fout-waarde. 4. Doe hetzelfde voor het tweede patroon. Tel de gevonden totale foutwaarde op bij die uit stap 3 en bewaar het nieuwe totaal. 5. Herhaal dit voor alle andere ingangspatronen, waarbij steeds de totale foutwaarde wordt opgeteld bij het gevonden totaal en bewaard. 6. Als na het aanbieden van alle ingangspatronen de gevonden totale foutwaarde nog te groot is, zet de gevonden totale foutwaarde dan terug op nul en ga naar stap 3. 7. De totale foutwaarde is klein genoeg en het trainen is afgelopen. Bewaar de gevonden weegfactoren in een bestand voor gebruik in de praktijk. Tekortkomingen en uitbreidingen Het BP-algoritme is heel bruikbaar en gemakkelijk te implementeren, maar er kleven toch wel wat problemen aan. Het algoritme werkt goed voor eenvoudige patroonherkenning, maar om het te kunnen gebruiken moet de input wel aan een aantal voorwaarden voldoen. We zijn er tot nu toe steeds van uit gegaan dat het patroon een bepaalde grootte heeft en dat het netjes in het midden van onze ingangen wordt afgebeeld, maar in de praktijk is dat vaak niet het geval. Als we bijvoorbeeld een gezicht willen herkennen in een grote groep mensen, dan zullen we eerst moeten bepalen waar de gezichten in de afbeelding te vinden zijn en we moeten er voor zorgen dat ze worden geschaald tot een grootte waar het netwerk mee uit de voeten kan. Er is dus blijkbaar een heleboel voorbewerking nodig, voordat we met ons neurale netwerk aan de slag kunnen gaan. Zonder voorbewerking zijn de mogelijkheden beperkt en moeten we veel eisen stellen aan de omgeving waarin het netwerk wordt ingezet om tot bruikbare resultaten te komen. We zien dat bijvoorbeeld bij toepassingen zoals tekstherkenning: De invoer bestaat uit een zwart-wit patroon van pixels, dat alleen de te herkennen tekst bevat. Om in de drukke, verwarrende werkelijkheid om ons heen gebruikt te kunnen worden, is heel wat meer intelligentie nodig. Onze hersenen lossen dit op door het beeld dat we zien eerst te ontleden in herkenbare 'brokken' en zo structuur aan te brengen in verschillende abstractieniveaus. Wij herkennen dan een letter T bijvoorbeeld als een horizontale lijn met in het midden een verticale lijn naar beneden. Op die manier maakt het niet uit hoe groot de letter wordt afgebeeld, want we maken alleen gebruik van de onderlinge verbanden in het beeld en niet van de absolute grootte van de weergave of van de plaats van de letter in het beeld. Bij het trainen van het netwerk kunnen problemen ontstaan door het optreden van 'lokale minima- in de gevonden foutwaarden. Deze problemen ontstaan doordat het algoritme altijd probeert om een neergaande lijn te volgen in de gevonden foutwaarden. Dat leidt niet altijd tot de optimale oplossing. Zoals weergegeven in figuur 7 kan de foutwaarde vastlopen bij een lokaal minimum. Om het echte minimum te bereiken, zou de foutwaarde eerst moeten toenemen voordat de dalende trend weer kan worden vervolgd. Dat kan ons algoritme niet. Hoe groter het netwerk is, hoe groter de kans dat dit soort problemen zich voordoet. Een mogelijke oplossing voor dit probleem is om een soort 'traagheid' in te bouwen in het leeralgoritme. Die methode houdt in dat de weegfactoren als ze eenmaal 'in beweging' zijn, de neiging moeten krijgen om door te gaan in dezelfde richting, ook als de foutwaarde daarbij tijdelijk toeneemt. Dat kunnen we doen door bij elke iteratie de verandering in de weegfactor te onthouden en die te gebruiken bij de volgende iteratie op de volgende manier: Bereken de verandering in de weegfactor voor deze iteratie. Bepaal de nieuwe weegfactor als: W+ = W + berekendeverandering + bewaarde_verandering_uit_vorige_ iteratie Maar een andere manier om dit probleem op te lossen is de voortgang van het leerproces in de gaten te houden. Als we dan zien dat het leerproces blijft steken, kunnen we het gewoon opnieuw starten met andere, willekeurige waarden voor de weegfactoren. In het volgende deel van deze serie zullen we ingaan op netwerken waarin de koppeling tussen de neuronen niet altijd in dezelfde richting (van ingang naar uitgang) ligt, maar waarin ook verbindingen in de andere richting voorkomen. Onder andere het beroemde Hopfield-net-werk zal dan aan de orde komen. Neurale netwerken in de praktijk Deel 3: Netwerken met terugkoppeling en competitieve netwerken Nu bekijken we twee wat ingewikkelder structuren voor een neuraal netwerk. Om te beginnen het Hopfield netwerk, dat gebruik maakt van terugkoppeling. Daarna gaan we in op 'competitive' netwerken, die in staat zijn om patronen in de invoerdata te ontdekken, waarvan de programmeur zelf het bestaan niet kent. In 1983 publiceerde de natuurkundige John Hopfield een beroemd artikel over neurale netwerken. Door de publicatie van dit artikel werd het onderzoek naar neurale netwerken, dat een tijd lang had stilgelegen, weer nieuw leven ingeblazen. Het neurale netwerk dat naar Hopfield vernoemd is, heeft maar een beperkt praktisch nut, maar het geeft wel een dieper inzicht in het gedrag van deze netwerken. Het bijzondere van het Hopfieldnetwerk is dat het gebruik maakt van terugkoppeling ('feedback'). Dit betekent dat de uitgangssignalen van het netwerk teruggevoerd worden naar de ingang. Zo'n netwerk is afgebeeld in figuur 1. Een Hopfield-netwerk bestaat altijd uit één laag en het heeft evenveel neuronen als ingangen. Werking van het Hopfield-netwerk De neuronen in dit netwerk werken net zoals de binaire neuronen uit deel 1, met dit verschil dat ze aan de output +1 of -1 leveren in plaats van 0 of 1. Als het netwerk is doorgerekend, worden de uitgangssignalen teruggevoerd naar de ingangen. De teruggevoerde signalen gaan opnieuw door het netwerk en leveren dus weer nieuwe uitgangssignalen op. Dit gaat door totdat het netwerk tot rust is gekomen. (Die eindtoestand van het netwerk noemt men dan ook 'relaxed'.) Op dat moment zijn de uitgangssignalen geschikt om verder verwerkt te worden. In figuur 2 is deze gang van zaken weergegeven in een programmastroomschema. Toepassing van het Hopfield-netwerk Wat is nu het nut van zo'n Hopfield-netwerk en wat is het voordeel ten opzichte van een back propagation netwerk? Het antwoord daarop is dat het Hopfield-netwerk niet alleen in staat is patronen te herkennen, maar het kan ook patronen opslaan en terughalen: Het heeft een geheugen. Als we het netwerk een vervormd en verstoord ingangspatroon aanbieden, dan haalt het het perfecte patroon, zoals het is opgeslagen, terug op de uitgangen. Dit is te zien in figuur 3. Als we het netwerk eenmaal getraind hebben, dan kunnen we een verstoord ingangspatroon aanbieden, wachten tot het netwerk tot rust is gekomen en het gereconstrueerde patroon gebruiken, dat dan op de uitgangen aanwezig is (zie figuur 4). Het originele Hopfield-netwerk maakte alleen gebruik van twee vaste waarden voor de ingangen en uitgangen. De waarde -1 stelt bijvoorbeeld een wit pixel voor en de waarde +1 een zwart pixel. Bij moderne netwerken wordt meestal gewerkt met continue signalen die elke waarde tussen -1 en +1 kunnen aannemen, maar hier beperken we ons tot het eenvoudige geval waarbij we dus met twee discrete waarden werken. Trainen Laten we nu eens kijken hoe we een Hopfield-netwerk kunnen trainen. Vergeleken met het back propagation netwerk is het trainen van het Hopfield-netwerk gemakkelijk. Alle weegfactoren worden berekend met de volgende formule: Wmn = Som( OmOn ) over alle patronen Hierbij stelt Wmn de weegfactor voor tussen de m-e ingang en het n-e neuron en On is de n-e uitvoer die we van het netwerk willen zien. Met andere woorden: We kunnen de weegfactor voor de verbinding van ingang m met neuron n berekenen door voor alle te herkennen patronen het me uitgangssignaal met het ne te vermenigvuldigen en deze producten bij elkaar op te tellen. Figuur 5 brengt dit in beeld. De uitgangen van de neuronen zijn verbonden met de ingangen van alle andere neuronen, maar niet met de ingang van het neuron zelf. De weegfactoren Wnn zijn daarom gelijk aan 0. Stel dat we drie patronen willen leren: Patroon 1: °A(1) = Patroon 2: -1 0B(1) = -1 oC(1) = 1 0A(2) Patroon 3: 1 °b(2) - -1 0C(2) = -1 °a(3) - -1 °b(3) - 1 °c(3) Wj i = 0 w1.2 = °a(1) x °b(1) + °a(2) x Ob(2) + 0A(3) X 0B(3) = (-1) X (-1) + 1 X (-1) + -1) X 1 = -1 wl.3 = Oa(1) x 0C(1) + 0A(2) x Oc(2) + 0A(3) x 0C(3) = (-1) x 1 + 1 x (-1) + (-1) x 1 = -3 W2 2 = 0 w2,i = Ob(1| x Oaa, + Ob(2) x Oa(2) + Ob(3) x Oa(3) = (-1) X (-1) + (-1) X 1 + 1 X (-1) = -1 w2.3 = °b(l) x °c(l) + °b(2) x Oc(2) + Ob|3) X Oc(3) = (-l)xl +-f)x(-l) + 1x1 = 1 w3 3 = 0 w3.1 = °c(l) x °a(l) + °c(2) x °a|2) + Oc(3) x Oa(3) = 1 x (-1) + (-1) x 1 + 1 x (-1) = -3 w3.2 = Oc(i, x Ow) + Oc(2) x Ob(2l + Oc(3) x Ob(3) = 1 X (-1) + (_l)x(_l) + ixi = i Daarmee is de berekening klaar. We hoeven geen herhaalde berekeningen uit te voeren, zoals bij het BP-netwerk. Listing 1 toont een simpel algoritme om de weegfactoren voor een Hopfield-netwerk te berekenen. We hebben hier gebruik gemaakt van de in deel 1 beschreven wijze van opslag van de weegfactoren in een tweedimensionaal array. De te herkennen patronen zijn van te voren opgeslagen in een array i(patroon_nummer, pixel nummer). Mogelijkheden Als we het Hopfield-netwerk vergelijken met de eenvoudige neurale netwerken uit deel 1, dan valt het dynamische gedrag van het Hopfield-netwerk op. De netwerken uit deel 1 waren te vergelijken met combinatorische logica: We kunnen daarmee elke gewenste I npuTs T1 0 u T puT s 020324 . 3 • I« Figuur 6: Een gegeneraliseerd neuraal netwerk. Listing I for f = 1 to no_of_inputs for t = no of inputs + 1 to no_of_inputs + no_of_outputs for p = 1 to no_of_patterns w(f, t) = w(f, t) + i(p, f) * i(p, t - no_of_inputs) next p if t = no_of_inputS + f then w(f, t) = 0 next t next f Input I Input 2 Output I Output 2 Output 3 0203:4-.3. 17 Figuur 7: Een simpel competitief netwerk. Output 1 Output 2 Output 3 020324 - 3 - IS Figuur 8: Een winnend neuron. de vaste taak krijgt om dit andere patroon te herkennen. Het netwerk organiseert zichzelf op die manier. Toepassingen We kunnen het competitieve netwerk loslaten op gegevens. Bijvoorbeeld op de aandelenkoersen. Het netwerk gaat dan zichzelf organiseren op het herkennen van patronen in deze gegevens. Wat dat precies voor patronen zijn, dat weten we niet. Het netwerk beslist daar zelf over. We werken niet met voorbeelden zoals bij de eerdere netwerken. Hierin schuilt zowel de aantrekkingskracht als het nadeel van dit type netwerk: Het kan belangrijke patronen ontdekken, die we zelf niet gezien hadden, maar het kan ook gebeuren, dat het netwerk niet vindt waar we op gehoopt hadden en in plaats daarvan een ander patroon in de invoer gaat herkennen. Een ander probleem van dit type netwerk hangt hiermee samen: Het netwerk zal ook patronen gaan herkennen, waarvan het vindt dat die lijken op het te herkennen patroon, ook als de overeenkomst tussen die twee patronen voor de gebruiker onduidelijk is. Een competitief netwerk leert zonder besturing, het doet wat het zelf wil. Natuurlijk kan een competitief netwerk ingezet worden voor gewone patroonherkenning, maar dat heeft niet zoveel nut. Een gewoon back propagation netwerk is voor die taak minstens zo geschikt en het is gemakkelijker op te bouwen. Meer details Om nog wat meer te weten te komen over de subtiliteiten van het competitieve netwerk, kijken we nogmaals naar figuur 7 en 8. Het netwerk in dit voorbeeld heeft twee ingangen. We kunnen het ingangssignaal voorstellen als twee getallen, maar het kan ook in de vorm van een vector. De waarde op de ene input geeft dan de lengte van de vector in X-richting en de waarde van de andere input geeft de lengte in Y-richting. Dit is weergegeven in figuur 9. Deze methode kan voor elk aantal ingangen toegepast worden, maar bij twee ingangen is het gemakkelijk om het op papier weer te geven. De lengte van de vector kunnen we uitrekenen met behulp van de stelling van Pythago-ras: Lengte = <l(inputl)2+ (input 2)2 Net als de input-waarden kunnen we ook de weegfactoren voor dit neuron uitzetten als Weegvector Weegvector 2 Wccgvector 3 Input-vector met lengte L -> Alle vectorlengtcs zijn identiek (ze liggen allemaal op de/elfde cirkel) 020324 -3-21 Figuur I I: Weegvectoren van de drie neuronen. door training verschuif! 020324 ¦ 3 -22 Figuur 12: Het effect van de training. • • • • O O O • • • • • O O O • • • • • O O O • O O "winnend" neuron, volledie getraind Omringende, gedeeltelijk getrainde neuronen 020324 - 3 - 23 • • • • • • • • • Figuur 13: Een zelforganiserende matrix. een vector in de grafiek, zoals in figuur 10. Als we de output van het neuron bepalen, rekenen we in feite het inproduct uit van de vector die de input voorstelt met de vector die de weegfactoren weergeeft. (O = ijWj + i2w2) We kunnen het inproduct beschouwen als een getal dat aangeeft in hoeverre twee vectoren op elkaar lijken qua richting. Als de twee vectoren dezelfde richting hebben, krijgen we een grotere uitkomst dan wanneer de twee vectoren een hoek met elkaar maken. Als alle vectoren even lang waren, zou de waarde van het inproduct alleen bepaald worden door de hoek die ze met elkaar maken. En het is juist deze hoek waarin we geïnteresseerd zijn. Daarom normeren we onze vectoren. Dat wil zeggen, dat we de richting van de vector behouden, maar de lengte exact gelijk aan 1 maken. We kunnen dat doen door zowel de X- als de Y-component van de vector te delen door de lengte. In figuur 11 zijn alle weegvectoren van het netwerk en het ingangssignaal genormaliseerd en ingetekend. We zien nu aan de richting van de weegvector van neuron 3, dat deze het meest overeenkomt met het ingangssignaal. Neuron 3 wint hier dus. Dat blijkt niet alleen uit de tekening, maar het blijkt ook als we het inproduct van de inputvector met elk van de weegvectoren onderling vergelijken: Voor neuron 3 levert dat het grootste getal op. Het effect van het trainen is dat de weegvector van neuron 3 naar de input-vector toe gedraaid wordt (zie figuur 12). Dit zorgt er voor dat dit invoersig-naal, en signalen die erop lijken, waarschijnlijk weer neuron 3 zullen activeren. De formule die bij het leren gebruikt wordt om de nieuwe weegfactoren te bepalen, W+ = W + rj(Input -W), houdt geen rekening met de lengte van de vectoren. Daarom moeten we na het leren de weegvector opnieuw normeren voor een eerlijke vergelijking. De verdeling van de weegvectoren over de cirkel heeft een grote invloed op het succes van het netwerk. Daarom kan het nuttig zijn om er bij het begin van het trainingsproces voor te zorgen dat de weegvectoren zo gelijk mogelijk over de cirkel verdeeld zijn. Netwerken met competitieve neuronen Competitieve neuron worden zelden afzonderlijk gebruikt. Meestal worden ze ingezet als bouwsteen in ingewikkelde netwerken. Ze worden vaak georganiseerd in de vorm van een tweedimensionale matrix, zoals te zien in figuur 13. We noemen dit een 'Kohonen Self Organising Map'. In dit geval wordt het winnende neuron volledig getraind, zoals eerder beschreven, maar de aangrenzende neuronen worden ook getraind, alleen in mindere mate. Dat is te realiseren, door bij de aangrenzende neuronen een kleinere waarde voor de factor n te kiezen. Het effect van deze manier van trainen is, dat neuronen die dicht bij elkaar liggen getraind worden voor patronen die op elkaar lijken. Patronen met weinig overeenkomst zullen herkend worden door neuronen die ver uit elkaar liggen. Een andere belangrijke techniek waarbij competitieve neuronen gebruikt worden, is de 'Adaptive Resonance Theory' (ART). Hierbij worden netwerken gebruikt, die kunnen groeien naarmate ze meer patronen herkennen. In het laatste deel van deze serie zullen we aandacht besteden aan nog enkele toepassingen van neurale netwerken en aan technieken voor gevorderden, waar de wetenschappers in de kunstmatige intelligentie op dit moment mee aan het worstelen zijn. 1020324 3i Neurale netwerken in de praktijk Deel 4: Toepassingen en grote netwerken In dit laatste deel van de serie zullen we een aantal toepassingen bespreken en we gaan in op enkele vraagstukken waar onderzoekers in de neurale netwerken op dit moment mee worstelen. We hebben ons in deze serie vooral bezig gehouden met het herkennen van patronen in beelden. Dat was niet alleen omdat beeldherkenning een van de meest voorkomende toepassingen van neurale netwerken is. maar ook omdat dit soort toepassingen goed aanschouwelijk gemaakt kan worden. We kunnen de te herkennen beelden zelf zien. Maar, zoals al in deel 1 vermeld werd, hebben neurale netwerken veel meer mogelijkheden. Als het netwerk uit minimaal drie lagen bestaat, kan het gebruikt worden als een logische schakeling die elke denkbare waarheidstabel kan realiseren (figuur 1). Als we gebruik maken van neuronen die met de Sigmoid-functie werken, dan werkt het netwerk niet als een gewone, binaire, logische schakeling, maar hebben we in feite te maken met een toepassing van 'Fuzzy logic'. De uitgangen worden geen '0' of '1', maar kunnen alle waarden daartussen aannemen en zijn dus analoog. Dat is heel nuttig bij het aanpakken van praktijktoepassingen, waarbij tussen zwart en wit nog vele tinten grijs te onderscheiden zijn. Toepassingen in de robotica Een voorbeeld van het nut van een trainbare waarheidstabel zien we bij de robotbesturing in figuur 2. We kunnen de robot het gewenste gedrag aanleren door hem te trainen op de mogelijke ingangssignalen van zijn sensoren te reageren met de juiste uitgangssignalen naar zijn motoren. Een robot met dierachtige eigenschappen wordt wel een Animat' genoemd Logische input 1 Logische input 2 Logische input 3 Output. Trainbare waarheidstabel 02032-1 - 4 - 11 Figuur I. Universele, trainbare logica. Input I Linker druksensor Input 2 Rechter druksensor Aansturing voor linker wiel Aansturing 'voor rechter wiel 020524 . 4. 12 Figuur 2. Een robotbesturing. en het netwerk dat voor dit gedrag zorgt, noemen we dan een kunstmatig zenuwstelsel (ANS, oftewel Artificial Nervous System). Een manier om zo'n robot te trainen is met behulp van het back propagation algoritme. Een andere manier is het gebruik van een zogenaamd 're-enforcement' algoritme. Zo'n methode werkt door het juiste gedrag van de robot te belonen, waarbij de weegfactoren die tot dat goede gedrag geleid hebben, worden versterkt. Fout gedrag wordt afgestraft, waarbij de weegfactoren die daarvoor verantwoordelijk waren worden verzwakt. Zoiets kan de robot volautomatisch doen, mits hij beschikt over een waardensysteem waarmee hij zijn eigen gedrag kan beoordelen. Een variant op deze methode is het gebruik van een genetisch algoritme. Hierbij laten we een soort Input I (positiesensor Input 2 (snciheidssensor) Input 3 t\crsnol I ingsscnsorI Output naar motor 02012-1 - 4 - I < Figuur 3. Opzet voor een motorregelaar. Spanning f 1 Sample 1 >v Sample li \ciu erk getraind om golfvorm te herkennen Ouipui 020324-4- 14 Figuur 4. Een gesamplede golfvorm in een netwerk invoeren. evolutie plaatsvinden van een grote groep netwerkvarianten. De varianten die tot goed gedrag leiden, worden beloond doordat ze zich mogen 'voortplanten': Ze worden gebruikt om een nieuwe generatie van netwerken te creëren. De varianten die tot verkeerd gedrag leiden, krijgen deze beloning niet. Ze worden gewoon vergeten. Men noemt deze methode wel EARL (Evolutionary Algorithm for Re-enforcement Learning). Toepassingen in de regeltechniek We kunnen deze besturingsmethoden ook gebruiken in andere systemen. Stel bijvoorbeeld dat we een gelijkstroommotor willen regelen, zoals weergegeven in figuur 3. Netwerk start met scannen van beeld linksboven en schuif) steeds een pixel verder. Wanneer liet einde van de rij wordt bereikt, wordt een pixel omlaag gesprongen en verder gescand naar links. Scannen stopt wanneer het pixel rechtsonder bereikt is. 020324 -4-1« Figuur 5. Het scannen van een beeld. De conventionele manier om een motor te regelen is bijvoorbeeld een standaard PID-regelaar (PID = Proportioneel, Integrerend, Differentiërend), maar we kunnen ook gebruik maken van een neuraal netwerk en dan spreken we van een 'neurocontroller'. Zo'n neuro-controller kan bijvoorbeeld leren van een normale regelaar, door de output van de normale regelaar te gebruiken als target in een back propagation algoritme. Maar het is veel interessanter om het netwerk niet te laten leren van een gewone regelaar, maar uit ervaring. We kunnen daarbij dan gebruik maken van de re-enforcement methode of van een genetisch algoritme. Mens-machine-interface en intelligente sensoren In het bovengenoemde regelsysteem maakte het netwerk gebruik van de sensoringangen om het gewenste gedrag te bepalen. Neurale netwerken zijn heel geschikt om de informatie van vele sensoren te combineren tot een gewenste respons. Daarvoor hoeven we zelf niet de samenhang tussen de verschillende sensorsignalen te begrijpen, dat doet het netwerk wel voor ons. Alles wat we hoeven te doen is het netwerk voeden met voorbeelden van het gewenste gedrag in verschillende situaties. Het netwerk leert dan vanzelf het verband tussen de verschillende ingangssignalen. Een mogelijke toepassing van zo'n intelligent sensorsysteem ligt in de koppeling tussen mens en machine. Als we bijvoorbeeld kunstmatige ledematen willen koppelen aan het menselijke zenuwstelsel, dan zouden we eerst moeten onderzoeken wat alle signalen op de vele zenuwen die dat lichaamsdeel besturen, te betekenen hebben. Sommige van die signalen zijn voor de besturing waarschijnlijk helemaal niet nodig en andere signalen moeten misschien op een ingewikkelde manier gecombineerd worden. Het neurale netwerk lost dat probleem voor ons op. Herkennen van golfvormen Bij zo'n besturing vanuit het menselijke zenuwstelsel is het nodig om de golfvormen te herkennen, die de menselijke neuronen opwekken. Dat gaat heel goed met een neuraal netwerk, omdat dat even goed patronen in de tijd (zoals golfvormen) kan herkennen als patronen in de ruimte (zoals bij tekstherkenning). We kunnen een golfvorm geschikt maken voor verwerking door een neuraal netwerk door het signaal te samplen, zoals in figuur 4. Er is echter nog een probleem dat we moeten oplossen. In deel 2 kwam dit al ter sprake bij het herkennen van beelden, maar hetzelfde geldt voor golfvormen: Het patroon moet de juiste grootte hebben en het mag niet verschoven zijn ten opzichte van onze ingangen. Voorbewerking Er is dus een voorbewerking van de signalen nodig, voordat we ze aan een neuraal netwerk kunnen aanbieden. De voorbewerking bestaat uit het schalen en centreren van het ingangssignalen op onze netwerkingangen. Er zijn verschillende manieren om dat te doen. In het geval van golfvormen kijken we Beeld Nei I: Verticale detector Net 2: Horizontale detector Net 3: Combineren van output I en 2 T 020324-4 - 17 Net werk-ingangsbereik slart met volledige beeldgrootte. Wanneer het beeld geseand is. wordt de grootte van het ingangsbereik verkleind. De beeldinformatie wordt verminderd tot de correcte grootte voor de netwerk-input door het uitmiddclcn van pixels of soortgelijke methodes. ? Het ingangsbereik wordt steeds verder verminderd tot het de kleinste praktische afmeting bereikt heefl. Figuur 7. Modulaire netwerken. Figuur 6. Bepaling van de schaalfactor. king van het signaal worden opgelost. We kunnen beginnen te scannen met een groot venster en dat venster dan stapsgewijs verkleinen, totdat we de juiste schaling bereikt hebben (zie figuur 6). In werkelijkheid kunnen we de grootte van ons venster niet veranderen. We zitten immers juist vast aan het aantal inputs van het netwerk. Maar we kunnen dit effect wel bereiken door het beeld te bewerken. Door de waarde van meerdere pixels te middelen bepalen we de waarde van elk pixel in een kleiner plaatje, dat precies op de ingangen van het netwerk past. o:ov:4 - 4 - K. Modulaire netwerken Onze hersenen herkennen patronen door te reageren op bepaalde kenmerken in het beeld. De letter L heeft twee belangrijke kenmerken: Een horizontale en een verticale lijn. Het maakt niet uit hoe groot de letter is, of waar hij in het beeld staat, hij behoudt altijd die twee kenmerken. Als we twee netwerken hebben, waarvan het ene horizontale lijnen herkent en het andere verticale lijnen, dan kan een derde netwerk de twee herkende kenmerken samen gebruiken om de letter L te herkennen (zie figuur 7). steeds naar een bepaald 'venster' in de tijd. Terwijl de golfvorm sample voor sample doorgaat, schuift het te herkennen patroon aan dat venster voorbij. Op een zeker moment zal het dus precies midden voor onze ingangen liggen en dan wordt het herkend. Bij het herkennen van beelden kunnen we op dezelfde manier te werk gaan. Ook hier kunnen we de ingangen van het netwerk zien als een venster op het binnenkomende signaal. Als we dat venster pixel voor pixel verschuiven over het totale ingangssignaal, dan komt er een moment dat het patroon precies uitgelijnd is met de ingangen van ons netwerk (zie figuur 5). In feite doen mensen hetzelfde als ze een beeld bekijken. Ze scannen (onbewust) het beeld af, op zoek naar herkenningspunten. Bij dit afscannen van de ingangssignalen is het wel belangrijk dat het netwerk in staat is om een onderscheid te maken tussen 'ruis', dus onherkenbare data, en bruikbare ingangssignalen. Als het dat niet kan, dan herkent het in elk invoersignaal wel iets en dat is natuurlijk niet de bedoeling. Het centreren van het ingangssignaal is daarmee opgelost, maar hoe zit het dan met de schaling? Ook dat kan met een voorbewerken sterk gestimuleerd neuron hen /wak gestimuleerd neuron produceen veel pulsen per seconde. produceert weinig pulsen per seconde Spanning Spanning. Tijd Tijd Output Output Tijd Sterk gestimuleerde kunstmatige neuronen leveren een hoge output. Tijd Zwak gestimuleerde kunstmatige neuronen leveren een geringe output. Figuur 8. Vergelijking tussen een biologisch en een kunstmatig neuron. Outpul Tijd t; is omgekeerd proportioneel aan de som van de inputs. Frequentie-gemoduleerd. Figuur 9. "Spiky' neuronen. A Output Tijd ti is proportioneel aan de som van de inputs. u * ti is een constante, Pulsbreedte-gemoduleerd. 020J24 .4-1» Dat is een simpel voorbeeld van een modulair netwerk. In plaats van een heel groot netwerk waarin alles met alles is verbonden, verdelen we het werk over meerdere kleine netwerken. Onderzoek heeft aangetoond dat dit de manier is waarop onze hersenen georganiseerd zijn: Niet als één groot netwerk, maar als een heleboel kleine netwerken die dan weer onderling gekoppeld zijn om tot een coherent geheel te komen. Op dit moment wordt er onderzoek gedaan of het mogelijk is om zulke groepen van netwerken te laten vormen met behulp van evolutionaire algoritmes. Dynamisch gedrag van neuronen Oplettende lezers hebben natuurlijk gemerkt dat de kunstmatige neuronen, waar we het tot nu toe over hebben gehad, anders werken dan biologische neuronen. Biologische neuronen hebben een dynamisch gedrag: Door vaker of minder vaak 'af te vuren' produceren ze signalen die in frequentie gemoduleerd zijn (zie figuur 8). Er zijn wetenschappers die van mening zijn, dat dit belangrijk is en dat onze gedachten, of zelfs ons bewustzijn, bestaan uit groepen van dit soort pulsen, die heen en weer flitsen door ons zenuwstelsel. Het gebruik van informatie die op deze manier (in frequentie of in pulsbreedte) gecodeerd is, blijkt voor een aantal praktische toepassingen ook veel handiger te zijn. Er zijn ook kunstmatige neuronen gemaakt, die dergelijk gedrag vertonen. Men noemt ze wel 'spiky' neuronen. In figuur 9 zien we twee van deze 'spiky' neuronen. Het eerste werkt met frequentiemodulatie en het tweede met pulsbreedtemo-dulatie. De weegfactoren en andere parameters zijn weer te bepalen met een genetisch algoritme of met de back-propagationmethode. Verbindingen en technologie Een interessant punt is nog het verschil in grootte tussen kunstmatige neurale netwerken en onze hersenen. Onze hersenen bevatten 100 miljard neuronen. Dat is even veel als het aantal sterren in ons melkwegstelsel. We kunnen de hersenen dan ook beschouwen als de meest ingewikkelde structuur in het ons bekende universum. Daar komt nog bij dat elk van die neuronen verbindingen kan hebben met wel 1000 andere neuronen. Sommige neuronen zijn zelfs met wel 100.000 andere neuronen verbonden. De hersenen bevatten dus misschien wel 100 biljoen verbindingen tussen neuronen. Met onze huidige technologie kunnen we dit niet namaken. Noch de dichtheid, noch het aantal verbindingen zijn te evenaren. We kunnen weliswaar transistoren maken die even klein zijn als neuronen, maar geïntegreerde schakelingen zijn altijd plat, dus tweedimensionaal, terwijl de neuronen in een driedimensionale structuur zitten. Deze problemen lijken onoplosbaar, maar elektronische schakelingen hebben ook een voordeel: Ze werken veel sneller dan neuronen. De pulsen van de neuronen bewegen zich voort met een snelheid van 'slechts' enkele honderden meters per seconde, maar elektrische signalen kunnen zich voortplanten met snelheden tot zo'n zestig procent van de lichtsnelheid. Als we een neuraal netwerk willen bouwen, mag dat dus best groter zijn dan de menselijke hersenen. Het probleem van het grote aantal verbindingen kan misschien opgelost worden door gebruik te maken van een soort netwerk waarin alle neuronen een eigen adres hebben in plaats van aparte verbindingen voor elke koppeling tussen twee neuronen. Neurale netwerken opbouwen in hardware is voor de amateur niet te doen, omdat geïntegreerde schakelingen niet zelf te maken zijn. En voor het opbouwen van een neuraal netwerk uit discrete componenten zou een astronomisch aantal onderdelen nodig zijn. Dat wordt nog erger als we de verbindingen ook nog variabel willen maken, zoals dat bij evolutionaire netwerken het geval is. Er zijn experimenten gedaan met FPGA's (Field Programmable Gate Arrays), maar die zijn niet zo geschikt voor het maken van neuronen en daardoor is voor elk neuron veel ruimte in de FPGA nodig. Neurale netwerken zijn nou eenmaal gebaseerd op de structuur van het menselijke brein en niet op de praktische mogelijkheden in de elektronica. We beschikken nog niet over een goede elektronische versie van een neuron (een universele, lerende rekeneenheid). Hiermee zijn we aan het einde gekomen van onze verkenningstocht door de wereld van neurale netwerken. Literatuur Enkele boeken over neurale netwerken voor hen. die zich verder in dit onderwerp willen verdiepen: K. Gurney, An introduction to Neural Networks, UCL Press, 1997 I. Pratt, Artificial Intelligence. MacMillan, 1994 PD. Wasserman. Neural Computing: theory and practice, Van Nostrand Reinhold, 1989