III.Multi-layer Perceptron &
Backpropagation
A. Inleiding
Perceptrons zijn netwerkjes met twee
lagen, een inputlaag en een outputlaag, die in staat zijn zo ongeveer
elke mapping van inputs op outputs te leren. Ongeveer,
want zoals je ongetwijfeld al etterlijke malen gehoord hebt toonden
Minsky & Papert in 1969 aan dat bepaalde mappings, bijv. XOR,
niet te leren zijn door Perceptrons.
De meerlagige perceptron of MLP was
een antwoord op hun boek. De MLP kan, in combinatie met het krachtige
error-backpropagation leeralgoritme, wel die problematische
mappings leren. Backprop-netwerken, zoals
MLPs met backpropagation meestal worden aangeduid, werden
meteen na hun ontstaan dan ook uiterst populair. Ze bleken in staat
te zijn de meest verschillende taken te leren uitvoeren, zoals het
vinden van de juiste uitspraak gegeven de spelling, of het produceren
van de verleden tijd van Engelse werkwoorden, het herkennen van
onderzeemijnen of het afhandelen van bagagestromen op vliegvelden. De
laatste tijd is deze populariteit overigens aan het afkalven: er zijn
krachtige statistische methoden die net zo goed maar efficiënter
de typische backprop-taken aankunnen. Bovendien zijn de statistische
methoden inzichtelijker dan backprop netwerken, die vaak als black
box gebruikt worden: je stopt er iets in en er komt iets uit, zonder
dat je hoeft te begrijpen wat er precies gebeurt. Als model voor het
functioneren van de hersenen is de populariteit van het backprop
netwerk ook tanende. Steeds meer mensen binnen de connectionistische
gemeenschap vinden het problematisch dat backpropagation biologisch
gezien weinig plausibel is.
In deze opdracht introduceren we
backprop, en laten we je een dataset met een backprop netwerk
aanpakken.
B. Het trainen van een backprop netwerk
Stap 1: de dataset
Voor dit practicum hebben we vier
datasets voorbereid, met heel uiteenlopende onderwerpen. Een dataset
kan van alles zijn, het kunnen klanten aantallen per kassa zijn of
schoenmaten of misdaadcijfers of taalconstructies. Al deze informatie
moet worden omgezet in iets waar een neuraal netwerk iets mee kan;
meestal houdt dit een proces in van schonen en schalen en
voorbewerken in dat bij werkelijke toepassingen, zoals het
voorspellen van aardbevingen of beurskoersen, een enorme klus kan
zijn. De dataset moet bestaan uit een aantal inputvariabelen en één
of meer outputvariabelen, waarbij de inputvariabelen gebruikt kunnen
worden voor het voorspellen van de output. Bij één van
onze datasets kan je bijvoorbeeld demografische variabelen (leeftijd,
geslacht, opleiding) gebruiken om salaris te berekenen. De
inputvariabelen vormen het inputpatroon, de outputvariabelen het
outputpatroon, en de combinatie een van input- en outputpatroon wordt
aan het netwerk aangeboden.
Stap 2: leren
Het leren in een backprop-simulatie
is meestal het heel vaak duizenden keren- aanbieden van de
input- en outputcombinaties uit de dataset. Het netwerk past tijdens
het leren zijn gewichten aan tot het de set kan voorspellen.
Het backpropagation-algoritme
bestaat uit twee delen (lees ook hfdst. 3 van de reader):
1. Een voorwaartse berekening
waarbij de activatiewaarden van de elke laag uit de activatie van de
vorige laag wordt berekend (in het Nutshell-backprop-paradigma heet
dit Upsweep).
2. Een terugwaartse berekening
waarin verschil tussen het gewenste outputpatroon en de werkelijke
patroon in de uitvoerlaag wordt berekend (de fout), en
daarna naar de vorige lagen terug wordt berekend (in het paradigma
heet dit Downsweep). Vervolgens worden de gewichten in
het hele netwerk veranderd m.b.v. de delta-leerregel op basis van dit
verschil: het netwerk wordt zo aangepast dat het bij een volgende
iteratie een kleinere fout zou opleveren.
Het netwerk leert zo de gewenste
output voorspellen op basis van de ingekomen input. Statistisch is
dit overigens equivalent aan niet-lineaire regressie (perceptrons
doen lineaire regressie). Leren in Backprop gaat meestal langzaam,
met heel kleine stapjes. Dit is omdat bij grotere veranderingen het
netwerk vaak instabiel wordt: in plaats van dat de gewichten naar een
stabiele toestand convergeren schieten ze wild heen en weer en leert
het netwerk nooit goed voorspellen. De leersnelheid wordt bepaald
door de leerparameter eta (vaak wordt het symbool m
gebruikt voor de leerparameter).
Stap 3: testen
In de testfase wordt het
inputpatroon aangeboden, en wordt er enkel gekeken in hoeverre de
door het netwerk gegenereerde output overeen komt met de bedoelde
output. Meestal worden niet alleen al geleerde patronen getest, maar
wordt er ook een deel van de dataset achter gehouden voor
verificatiedoeleinden: met deze, niet geleerde patronen test je of
het netwerk goed kan generaliseren.
C. Opdracht 3: backprop
In zowel opdracht 3.1 als 3.2 is het
de bedoeling om een dataset aan te leren. Om te zorgen dat niet
iedereen hetzelfde hoeft te doen hebben we 4 datasets van het Net
gehaald - echte data, overigens.
Open het bestand opdr3
datasets; op elke sheet staat een andere dataset. Dataset 1
bestaat uit hier verzamelde data over een steekproef ouderen waarvan
wordt vermoed dat er risico voor dementie bestaat; voor elke oudere
zijn er uitslagen op een aantal geheugentests, samen met
demografische variabelen en de scores op een dementietest en een
depressievragenlijst. Dataset 2 geeft voor een aantal personen een
stel demografische gegevens (geslacht, opleiding, functiesoort
)
en hun salaris. Voor de hardcore determinist: dataset 3 geeft
informatie over IQ en breingrootte van 12 tweelingen=24
tweelinghelften. Dataset 4 geeft voor een aantal Nederlandse
gemeenten de score van de belangrijkste partijen bij de verkiezingen
van 1998. De eerste set komt van Paulien Spaan (waarvoor dank), de
volgende twee zijn gedownload van de site:
http://www.stat.cmu.edu/datasets/, en de laatste is een bewerking van
data van het Centraal Bureau voor de Statistiek2.
Kies een dataset. Bepaal in deze
dataset welke variabelen de inputvariabelen worden, en welke de
outputvariabelen. Als je bijvoorbeeld dataset 4 kiest, kan je
bijvoorbeeld proberen de score van de grote partijen (PvdA, VVD, CDA)
te voorspellen uit de score van de kleine partijen. Kies minstens 4
inputvariabele en minstens 1, maar liever meer, outputvariabelen.
Zowel input- als outputvariabelen moeten cijfers zijn, dus kies bij
set 4 bijvoorbeeld niet de gemeentenaam als variabele. Regel 3 van de
sheets is de regel waarin je moet aangeven wat de input- en wat de
outputvariabelen zijn. Zet boven elke inputvariabele een kleine i,
boven elke outputvariabele een kleine o (de letter oooo,
niet het getal 0).
Open bestand Backpropscripts.
Open de Visual Basic-code. Er zijn drie modules, oftewel
codevensters. De code voor het inlezen van de dataset en het
wegschrijven van de data staat in een aparte module voor de
overzichtelijkheid. Open deze module en kijk even of je kunt snappen
wat de code hierin allemaal gaat doen.
Klik terug naar Excel. Open weer het
bestand opdr3 datasets, en zorg dat de dataset die
jullie willen gebruiken degene is die actief is
(d.w.z., degene die geheel zichtbaar is). Als je dat niet doet krijg
je een foutmelding bij de regel:
ReDim
learnPats(nrLearnPats - 1, nrInputs + nrOutputs - 1)
Sla, na het actief maken van je
datasheet, tegelijk de toetsen Alt en F8 aan;
dit zorgt ervoor dat je een lijstje te zien krijgt met scripten die
je kunt runnen. Selecteer datavoorbereiden, en klik op
run. Dit zorgt ervoor dat er verschillende gegevens op je
datasheet terecht komen. op de bovenste regel komen achtereenvolgens:
het aantal variabelen (cel D1), het aantal cases
oftewel het aantal patronen (cel E1), het aantal inputvariabelen dat
jullie hebben aangegeven (cel F1) en het aantal outputvariabelen (cel
G1).Op de derde regel komt een schalingsfactor te staan. Deze is
gelijk aan de maximum waarde op de variabele. Alle waarden worden
gedeeld door deze schalingsfactor, zodat geen enkele boven de 1 uit
komt. Dit versnelt het leren: anders is het netwerk eerst eindeloos
bezig met het schalen van de gewichten zo dat elke variabele ongeveer
evenveel invloed heeft.
Het databestand is nu klaar voor de
opdracht. In beide opdrachten zal het databestand ingelezen worden,
en automatisch opgedeeld worden in een leerset van ¾ van alle
cases (leerpatronen) en een testset van ¼
van de cases, waarmee generalisatie wordt getest (testpatronen).
De leerset wordt geleerd met door jou aangegeven parameters, en
vervolgens wordt het netwerk getest.
3.1 Perceptron.
Open de module Perceptron
in het bestand Backpropscripts. In deze module staat het
raamwerk van een simulatie waarin een tweelagig netwerk je dataset
aan gaat leren. Het is overigens niet echt een perceptron waar je in
deze opdracht mee werkt. Een tweelagig backprop-netwerk wat je
in feite hier bouwt is niet gelijk aan een perceptron, maar
werkt in essentie hetzelfde.
Het meeste werk aan de simulatie is
gedaan de procedures zijn geschreven die de data inlezen, het
leren uitvoeren, het netwerk testen. Wat ontbreekt is het netwerk
zelf.
a) schrijf een
stukje code op de aangewezen plaats (zie commentaar in de macro) dat
een netwerk aanmaakt met twee lagen. De ene laag (de inputlaag) moet
een aantal knopen hebben dat overeenkomt met het aantal dat je in je
dataset hebt gemarkeerd als inputvariabelen. De andere laag
(outputlaag) moet een aantal knopen hebben gelijk aan het aantal
outputvariabelen. Zorg dat de eerste laag, die met nummer 0,
de inputlaag is, en de tweede laag, die met nummer 1, de
outputlaag. Kijk naar appendix 1 en de bestanden uit opdracht 2 om te
zien hoe alles moet.
b) Stel de twee
belangrijkste variabelen bij het leren in: het aantal leerepisodes
(LearnEpochs) en de leersnelheid (learning rate). Begin
met een kleine waarde voor de leersnelheid en een grote voor het
aantal episodes. Er is een derde constante, het aantal tests dat het
model doet geef deze constante de waarde 4. De simulatie doet
een test om de zoveel leerepisodes; als je 200 leerepisodes opgeeft
en 4 testen zal hij een test uitvoeren elke 200 / 4 = 50 leerepisodes
(overigens doet hij automatisch een test aan het begin, voor er
sprake is van leren, zodat je een vergelijking hebt). Zo kan je de
voortgang van het leren zien, en hoef je niet voor elk aantal
leerepisodes een nieuwe test te doen. De resultaten van elke test
worden in een Excel workbook op steeds een nieuwe worksheet gezet.
Zorg wel dat het aantal leerepisodes deelbaar is door het aantal
testen (als je niets aan het aantal testen verandert: deelbaar door
4).
Run het script Perceptron.
Hiervoor moet je wel het bestand opdr3 datasets open
hebben, en de sheet met jouw dataset als de actieve bovenaan
hebben. Als het goed is wordt er nu een workbook aangemaakt met
daarop de uitvoer van de simulatie. Bekijk hoe goed het model het
heeft gedaan. Zie je vooruitgang van de ene test naar de volgende?
Gaan de testpatronen (zie boven) even veel vooruit als de geleerde
patronen?
c) Varieer de
leersnelheid en het aantal leerepisodes net zo lang tot je het
volgende kunt beantwoorden:
- Welke combinatie is optimaal? -
Wat is de invloed van de leersnelheid? - Wat is de invloed van het
aantal leerepisodes?
Wat is de procedure die je gevolgd
hebt om dit uit te zoeken?
d) Als je
netwerk een staat heeft bereikt waarin de output goed wordt
voorspeld, kijk naar de gewichten tussen de input- en de
outputknopen. Beantwoord voor elke outputvariabele de volgende vraag:
welke inputvariabele voorspelt de outputvariabele het best? (Hint: de
knopen in de inputlaag hebben dezelfde volgorde als de
inputvariabelen in je datafile).
Als je netwerk zon staat nooit
bereikt en de output knudde blijft voorspellen, beantwoord de
bovenstaande vraag niet maar probeer te bedenken waarom het
voorspellen niet wil lukken.
e) Sommige
patronen blijven het een stuk slechter doen dan anderen. Probeer dit
te verklaren.
3.2. Backprop
In deze opdracht moet je een
drielagig netwerk loslaten op je data. Gebruik precies dezelfde
dataset als in 3.1, met precies dezelfde mapping. Open de module
Backprop
a) Maak, zoals
je dat in opdracht 3.1 deed met twee lagen, een drielagig netwerk
aan. Zorg dat dezelfde variabelen naar de input- en outputlagen
verwijzen als in opdracht 3.1. Zorg ervoor dat de variabele
hiddenlayer verwijst naar de hidden layer.
Het aantal knopen in de hidden layer moet je straks gaan
variëren. Maak ook de juiste verbindingen (Tracts)
aan. Je kunt degene kopiëren uit opdracht 3.1, maar i.p.v. een
tract van de input- naar de outputlaag heb je tracts nodig van de
input- naar de verborgen laag, en van de verborgen laag naar de
outputlaag (let op: in overeenstemming met connectionistische
conventies komt de doellaag van de tract eerst in het commando, en
dan pas de bronlaag). Controleer of het netwerk goed wordt aangemaakt
met behulp van een breakpoint.
Een breakpoint
onderbreekt een programma zodat je kunt zien wat er tot dan toe
allemaal gebeurd is. Een manier om een breakpoint te zetten is door
de cursor te plaatsen op de regel waar je je programma wilt
onderbreken, en dan onder het menu Debug Toggle
breakpoint te klikken (zet hem hier bijv. net na de code voor
het aanmaken van je netwerk). Je kunt een break point niet zetten op
een lege regel of eentje die begin met Dim of ReDim,
of enkel commentaar bevat. Zet de breakpoint in de eerstvolgende
regel waar het wel kan, en run je code op de normale manier. Het
programma zal nu stoppen bij de break point. Je kunt nu
naar Nutshell klikken en kijken hoe het netwerk eruit ziet. Om weer
verder te kunnen met programmeren moet je in Visual Basic
op de reset-knop drukken (blauw vierkant), of de
reset-optie aanklikken onder het run-menu.
Breakpoints zijn een handig middel om te kijken of je programma doet
wat het moet doen.
b) Je hebt nu
drie variabelen om mee te variëren: de leersnelheid, het aantal
leerepisodes, en het aantal hidden units het
aantal knopen in de verborgen laag. Stel de leersnelheid laag in en
het aantal leerepisodes hoog, en vergelijk in ieder geval de volgende
drie simulaties: met 1 hidden unit, met een aantal
hidden units dat even groot is als het aantal
outputknopen, en 100 hidden units. Wat is het effect van
het aantal hidden units?
c) Zoek weer
naar een optimale instelling van de drie variabelen. Kan het netwerk
goed voorspellen? Is het drielagig netwerk beter, sneller en/of
efficiënter dan het tweelagig netwerk? Vergelijk de twee
netwerken; welke bevalt je beter en waarom?
!!!!! DENK AAN DE DEADLINE !!!!!
[2]
Mocht je overigens met een andere dataset aan de slag willen,
dan mag dat. Maak binnen "opdr3 datasets" een nieuwe sheet aan,
en zet je dataset erop in hetzelfde formaat als de andere sets:
met de verschillende variabelen in verschillende kolommen, de
data vanaf cel B5 naar rechts en onder, etc. Je kunt de
opdrachten verder gewoon afwerken.
|