Evert
Artikelen: 0
Berichten: 142
Lid geworden op: za 09 feb 2008, 23:31

Neural networks tutorial

Hoi,

Ik heb geprobeerd om in VB6 een programmaatje te maken dat m.b.v. een neural network boter-kaas-en-eieren speelt.

Daarvoor heb ik natuurlijk eerst wat tutorials gezocht over het maken van een neural network.

In kort was het allemaal samen te vatten tot:

Je hebt een laag input-neurons. Die geef je enkel de input die het neural network krijgt, ze doen er verder niets mee.

Dan heb je 1 of meerdere tussen lagen met neurons, die doen de nodige operations. Elke neuron van een laag X is verbonden met elke neuron van laag X-1 d.m.v. dendrites. Dendrites hebben "gewichten". Die geeft aan hoeveel de verbinding tussen 2 neuronen meetelt. Elke neuron van laag X krijgt dus alle informatie van elke neuron in laag X-1 met een bepaald "gewicht". Die doet daar wat leuke berekeningen mee (met een zogenaamde "bias", dat is een constante waarde die in elke neuron zit ingebouwd. De bias verschilt per neuron.) en geeft dat weer door aan elke neuron in laag X+1.

Dan heb je nog een output-layer die eventueel nog een laatste berekening doet en dan de output terug geeft.

Nou, ik heb dus een class gemaakt die een neural network maakte en letterlijk álles kon variabel gemaakt worden, het aantal lagen, het aantal neuronen in elke laag, de gewichten van de dendrites, de bias-waarden, álles...

Toen probeerde ik met evolutie (ja in die tuts stonden ook dat ik evolutie moest gebruiken) de beste boter-kaas-en-eieren-spelers te selecteren en laten voortplanten en de rest te laten sterven.

Helaas is het hard gefaald, want alle, echt ALLE neural networks met ELKE variatie deden 1 zet en dan bleven ze steeds die eerste zet doen, maakt niet uit hoe het bord veranderde. En ik heb echt honderden neural networks geladen. Het was een ramp.

Later bedacht ik mij dat dit neural network helemaal geen neural network is zoals ik dacht dat het zou zijn. Het hele idee achter neural networks is toch juist dat het kan leren? Niet dat je de domme networks gewoon laat sterven?

Volgens mij heb ik het helemaal verkeerd aangepakt en heb ik de verkeerde tuts gevonden.

Kan iemand mij vertellen hoe je een neural network maakt dat daadwerkelijk leert?

Tot dusver heb ik het volgende begrepen:

Je moet de gewichten van de dendrites een constante daling geven, dus elke verbinding wordt langzamerhand steeds minder belangrijk. En dan als er 2 neurons zijn die tegelijk "vuren" dan wordt de verbinding tussen die neurons sterker, dus het gewicht van de dendrite wordt hoger. Maar wat ik dan niet begrijp is, wat beslist dan of 2 neurons "vuren"? Want in mijn oude model zoals hierboven beschreven "vuurt" elke neuron altijd wel iets.

Kan iemand mij hier bij helpen?
Gebruikersavatar
Cycloon
Artikelen: 0
Berichten: 4.810
Lid geworden op: ma 24 jan 2005, 20:56

Re: Neural networks tutorial

Wat jij beschrijft is een genetisch algoritme waarmee je na x aantal generaties de beste kandidaat oplossing zou krijgen. Ik kan je echter niet verder helpen met je probleem.
Evert
Artikelen: 0
Berichten: 142
Lid geworden op: za 09 feb 2008, 23:31

Re: Neural networks tutorial

Klopt, in het model dat ik nu heb gemaakt wordt er gebruik gemaakt van een genetisch algoritme, maar daar wil ik dus juist van af. :eusa_whistle:
virtlink
Artikelen: 0
Berichten: 158
Lid geworden op: di 21 mar 2006, 18:44

Re: Neural networks tutorial

Het volgende weet je al wel en je hebt het grootste deel volgens mij goed begrepen. Toch heb ik het voor de volledigheid allemaal erbij gezet. Een micro-cursus zelflerende neurale netwerken:
neuron
neuron 634 keer bekeken
Een neuraal netwerk bestaat uit neuronen. Een neuron kan één of meer inputs
\(x_i\)
hebben met elk een gewicht
\(w_i\)
en één of meer outputs. Het neuron gebruikt de gewogen invoer van het neuron en laat daar een zogenaamde activatiefunctie op los. De gewogen invoer
\(X\)
is als volgt:
\(X = \displaystyle\sum_{i=1}^n x_i w_i - \theta\)
Er wordt gebruik gemaakt van een grens (threshold, jij noemt het bias)
\(\theta\)
die mag verschillen voor elk neuron. Er zijn verschillende activatiefuncties mogelijk, maar de meest gebruikte is de sign functie. Deze geeft 1 als
\(Y^{sign} = X \geq 0\)
en anders -1. Andere mogelijke activatiefuncties zijn:
  • \(Y^{step} = 1 \mbox{ als X \geq 0} \mbox{ anders } -1\)
  • \(Y^{sigmoid} = \frac{1}{1 + e^{-X}}\)
  • \(Y^{linear} = X\)
Welke activatiefunctie je het beste kan gebruiken hangt van je opzet af. Allemaal zullen ze wel werken, alleen sommige beter dan andere. Elk van de outputs krijgt de waarde
\(Y\)
van de activatiefunctie, en zo loopt een signaal door het netwerk.

Hoe leert een neuraal netwerk? Vaak wordt er gekeken naar de afwijking van de uitvoer van het netwerk ten opzichte van de gewenste uitvoer. Maar aangezien je wilt dat het netwerk boter-kaas-en-eieren kan spelen, heb je hier weinig aan. Wat jij volgens mij nodig hebt is een netwerk wat zelf kan leren (unsupervised learning). Een manier om dit te doen is met Hebb's leertheorie. Het idee hierachter is dat als de neuronen aan twee zijden van een verbinding allebei worden geactiveerd, dat dan die verbinding sterker mag worden. Daarentegen, als ze niet tegelijk worden geactiveerd, dan mag de verbinding worden afgezwakt. Kohonen beschrijft een specifieke variant van Hebb's wet met de volgende berekening voor de gewichtsaanpassing
\(\Delta w_{ij}(p)\)
op iteratie
\(p\)
op de verbinding tussen neuronen
\(i\)
en
\(j\)
, met leerfactor
\(\alpha\)
(hoe snel leert het netwerk) en vergeetfactor
\(\phi\)
(hoe snel vergeet het netwerk). Een netwerk met een hogere leerfactor zal radicaler reageren op kleine stimuli en de vergeetfactor is er om te voorkomen dat het netwerk alle gewichten alleen maar naar boven bijstelt (want dan zouden alle gewichten op een gegeven moment het maximum bereiken en heeft het netwerk nog steeds niks geleerd). De formule is als volgt:
\(\Delta w_{ij}(p)=\phi y_j(p)(\frac{\alpha}{\phi} x_i(p) - w_{ij}(p))\)
De stappen voor het leren zijn dan voor iteratie
\(p\)
als volgt:
  1. Initialisatie: Zet alle gewichten en thresholds op een kleine willekeurige waarde, bijvoorbeeld tussen 0 en 1. Geef ook een kleine positieve waarde aan leerfactor
    \(\alpha\)
    en vergeetfactor
    \(\phi\)
    .
  2. Activatie: Bereken de output
    \(Y\)
    van elk neuron.
  3. Leren: Update de gewichten in het netwerk:
    \(w_{ij}(p + 1)=w_{ij}(p) + \Delta w_{ij}(p)\)
  4. Iteratie: Verhoog
    \(p\)
    met 1, ga terug naar stap 2 en ga door totdat de gewichten niet meer zoveel veranderen.
Omdat de outputwaarde ook in de berekening voor
\(\Delta w_{ij}(p)\)
zit zorgt die ervoor dat de gewichten van de verbindingen meer worden opgehoogd als de outputwaarde meer van 0 afwijkt. Hoop dat dit helpt.
"Niet gehinderd door enige kennis van zaken..."
Evert
Artikelen: 0
Berichten: 142
Lid geworden op: za 09 feb 2008, 23:31

Re: Neural networks tutorial

Allereerst, sorry voor mijn late reactie. Ik kreeg een tentamenweek en daar moest ik keihard voor werken, want ik moest voor 3 vakken 3 maanden werk inhalen en voor 1 vak een half jaar werk...

Ik heb uiteindelijk 2 vakken gehaald en 2 gefaald, helaas..

Anyways, om even terug te komen op dit topic.
Deze geeft 1 als
\(Y^{sign} = X \geq 0\)
Hoe leert een neuraal netwerk? Vaak wordt er gekeken naar de afwijking van de uitvoer van het netwerk ten opzichte van de gewenste uitvoer. Maar aangezien je wilt dat het netwerk boter-kaas-en-eieren kan spelen, heb je hier weinig aan. Wat jij volgens mij nodig hebt is een netwerk wat zelf kan leren (unsupervised learning).
Dat dacht ik ook. :eusa_whistle:
Een manier om dit te doen is met Hebb's leertheorie. Het idee hierachter is dat als de neuronen aan twee zijden van een verbinding allebei worden geactiveerd, dat dan die verbinding sterker mag worden. Daarentegen, als ze niet tegelijk worden geactiveerd, dan mag de verbinding worden afgezwakt.
Maar dan leg je nog steeds niet uit wat "activeren" inhoudt. Ik neem aan dat je dan geen sigmoid-function kunt gebruiken of een linear-function? En alleen neurons uit dezelfde laag kunnen "tegelijk" activeren hè. Want anders wacht de neuron op laag X nog steeds op de output van de neurons van laag X-1 en die kunnen dus nooit "tegelijk" activeren. En zoals ik het nu doe communiceren neurons uit dezelfde laag sowieso nooit, neurons hebben enkel verbindingen met onder- en bovenliggende lagen...

Zou je dit nog even voor mij kunnen verduidelijken?
virtlink
Artikelen: 0
Berichten: 158
Lid geworden op: di 21 mar 2006, 18:44

Re: Neural networks tutorial

Evert schreef:Maar dan leg je nog steeds niet uit wat "activeren" inhoudt. Ik neem aan dat je dan geen sigmoid-function kunt gebruiken of een linear-function? En alleen neurons uit dezelfde laag kunnen "tegelijk" activeren hè. Want anders wacht de neuron op laag X nog steeds op de output van de neurons van laag X-1 en die kunnen dus nooit "tegelijk" activeren. En zoals ik het nu doe communiceren neurons uit dezelfde laag sowieso nooit, neurons hebben enkel verbindingen met onder- en bovenliggende lagen...

Zou je dit nog even voor mij kunnen verduidelijken?
'Activeren' bij Hebb leren is het berekenen van de output van élk neuron, op één moment. Dus nadat je het netwerk hebt geïnitialiseerd met willekeurige waarden, bereken je de output van álle neuronen 'tegelijk'. Dan komt er dus ook al een output uit, terwijl de input (het bord) nog niet bij de output is aangekomen. Daarvoor zijn meerdere activaties (iteraties) nodig.

Dat is dus meteen ook een probleem wat ik eerder vergat. Misschien is een back-propagation netwerk handiger hiervoor. Dan activeer je de eerste laag, de outputs worden de inputs voor de tweede laag die je dan activeert, en zo loop je door naar het eind. Dan gebruik je back-propagation om de foutcorrectie te doen: als het een onmogelijke zet is of als er verloren wordt, wordt het pad verzwakt en als er gewonnen wordt wordt het pad versterkt. Dit doe je dan op een aantal training sets en het getrainde netwerk gebruik je dan op een 'echt spel' (met alle mogelijkheden, ook die anders zijn dan de training sets) zonder back-propagation om te kijken hoe goed het werkt. Hoe simpel boter-kaas-en-eieren ook mag lijken, het is voor een neuraal netwerk nog best lastig. Een situatie kan hem geleerd zijn, maar dan gedraaid of gespiegeld. Dat maakt de situatie niet wezenlijk anders maar is wel een probleem voor het netwerk. Verder, als je trainingset te veel omvat dan reduceer je je neurale netwerk tot een database: voor elke situatie kent hij een goede bijbehorende zet. Als je trainingset te weinig omvat dan maakt hij veel fouten of onmogelijke zetten.
"Niet gehinderd door enige kennis van zaken..."
Evert
Artikelen: 0
Berichten: 142
Lid geworden op: za 09 feb 2008, 23:31

Re: Neural networks tutorial

Ok, dank je wel voor de uitleg.

Dan komen er nog een paar vragen in me op.

Ik heb tot nu toe de sigmoid-function gebruikt, maar welke adviseer jij eigenlijk voor een boter-kaas-en-eieren AI?

En ook, hoeveel lagen en neuronen-per-laag adviseer jij voor zo'n AI? Zijn daar vuistregels/richtlijnen voor? Of is het echt gewoon puur gokken?

[edit] Ik wilde net die backpropagation gaan programmeren, maar ik bedenk me net, het is onmogelijk om in mijn AI een "pad" terug te vinden.

Ik heb gewoon 9 inputs (elk voor 1 vlak van het veld) en 9 outputs (wederom 1 voor elk vlak) en de output met het hoogste getal wordt gezien als voorkeursvlak om een zet in te doen. Er is echter niet echt een pad te vinden die van input naar output gaat, alles gaat gewoon naar alles.
virtlink
Artikelen: 0
Berichten: 158
Lid geworden op: di 21 mar 2006, 18:44

Re: Neural networks tutorial

Evert schreef:Ok, dank je wel voor de uitleg.

Dan komen er nog een paar vragen in me op.

Ik heb tot nu toe de sigmoid-function gebruikt, maar welke adviseer jij eigenlijk voor een boter-kaas-en-eieren AI?

En ook, hoeveel lagen en neuronen-per-laag adviseer jij voor zo'n AI? Zijn daar vuistregels/richtlijnen voor? Of is het echt gewoon puur gokken?

[edit] Ik wilde net die backpropagation gaan programmeren, maar ik bedenk me net, het is onmogelijk om in mijn AI een "pad" terug te vinden.

Ik heb gewoon 9 inputs (elk voor 1 vlak van het veld) en 9 outputs (wederom 1 voor elk vlak) en de output met het hoogste getal wordt gezien als voorkeursvlak om een zet in te doen. Er is echter niet echt een pad te vinden die van input naar output gaat, alles gaat gewoon naar alles.
Juist in een back-propagation network is een sigmoid functie de meest gebruikte. Voor zo'n netwerk natuurlijk negen neuronen voor de input, en negen voor de output. Daartussen één of twee hidden layers. Ik denk dat één hidden layer genoeg is maar je kan twee ook best proberen. Als je te weinig neuronen in de hidden layers hebt, dan kan het netwerk niet zo veel onthouden. Heb je er te veel in, dat gaat ie alles uit z'n hoofd leren en maak je niet optimaal gebruik van het netwerk. Een vuistregel is er niet eigenlijk. Als je begint met een klein aantal, zeg 9 of 12, dan kan je altijd nog omhoog schalen als blijkt dat hij oudere geleerde dingen weer vergeet. Geef je hem meteen te veel, dan onthoudt hij alleen wat je hem geeft maar kan hij geen verbanden leggen.

Voor back-propagation bereken je de foutwaarde en propageer je die terug vanaf de output naar de input. Inderdaad. meerdere wegen kunnen een bepaalde output beinvloeden, dus back-propagation pakt álle wegen in meer of mindere mate aan.

Eerst bereken je het verschil tussen de verwachtte waarde (uit je trainingset)
\(y_{d,k}\)
en de verkregen waarde (output van de laatste neuronen)
\(y_k\)
voor elk neuron
\(k\)
in de output laag.
\(f_k(p) = y_{d,k}(p) - y_k(p)\)
Het updaten van de gewichten van neuron
\(j\)
naar
\(k\)
in de outputlaag gaat dan als volgt:
\(w_{jk}(p+1) = w_{jk}(p) + \Delta w_{jk}(p)\)
\(\Delta w_{jk}(p) = \alpha \cdot y_j(p) \cdot \delta_k(p)\)
Voor de sigmoid activatiefunctie geldt dan:
\(\delta_k(p) = y_k(p) \cdot (1 - y_k(p)) \cdot f_k(p)\)
\(y_k(p) = \frac{1}{1 + \exp(-X_k(p))}\)
Waarbij
\(X_k(p)\)
de gewogen input van die neuron is (die moet je dus onthouden bij het voorwaarts gaan).

Voor de neuronen in de verborgen lagen (neuron
\(i\)
naar
\(j\)
) is het weinig anders:
\(\Delta w_{ij}(p) = \alpha \cdot x_i(p) \cdot \delta_j(p)\)
\(\delta_j(p) = y_j(p) \cdot (1 - y_j(p)) \cdot \displaystyle\sum_{k=1}^l \delta_k(p)w_{jk}(p)\)
Waarbij
\(l\)
het aantal neuronen in de outputlaag is.

De formules ken ik niet uit mijn hoofd hoor. Die haal ik uit het boek 'Artificial Intelligence' van Michael Negnevitsky, tweede editie.
"Niet gehinderd door enige kennis van zaken..."

Terug naar “Informatica en programmeren”