sunnuntai 6. toukokuuta 2018

Neuroverkoista - perseptronit ja sigmoid-neuronit


Olen kurssilla Johdatus tekoälyn taustalla olevaan matematiikkaan, ja siitä innostuneena päätin kirjoittaa hieman neuroverkoista. Todella mielenkiintoinen aihe ja kurssi! Olen jo pitkään haaveillut tekoälyyn liittyvistä kursseista, ja vihdoin se toteutui! Opin paljon paremmin silloin, kun kirjoitan aiheesta, joten päätin kirjoittaa tänne blogiini. Teksti on melko suoraan otettu sivulta http://neuralnetworksanddeeplearning.com/chap1.html, jota kurssilla tulee lukea. Kiinnostuneet voivat siis tutkailla aihetta enemmän sieltä! Sivusto on ilmainen nettikirja, mikä on todella hienoa. En siis väitä näitä tekstejä tai esimerkkejä omikseni, kaikki on kyseiseltä sivulta oppimistarkoituksessa suomennettuna. Olen ottanut myös hieman infoa kurssini luentomonisteesta, eli Jyväskylän yliopiston Johdatus tekoälyn taustalla olevaan matematiikkaan -kurssin Tim-sivuilta. P.s. jos tiedätte paremman suomennoksen jollekin termille, saa vinkata! :)

NEUROVERKOT


https://3c1703fe8d.site.internapcdn.net/newman/gfx/news/hires/2017/algorithmlev.jpg


Ihmisillä on näköaivokuoressa 140 miljoonaa hermosolua, joiden välillä on kymmeniä miljardeja yhteyksiä. Silti ihmisen näköön ja kuvien prosessointiin tarvitaan monia muitakin näköaivokuoria. Käsinkirjoitettujen numeroiden tunnistaminen ei siis ole helppoa, ja se tapahtuu ihmisillä alitajuisesti.

Visuaalisten kuvioiden tunnistamisen vaikeus tulee esille silloin, kun täytyy kirjoittaa tietokone-ohjelma, joka tunnistaisi käsinkirjoitettuja numeroita. Vaikka tunnistaminen on meille helppoa, se on todella vaikeaa ohjelmille. Ei ole helppoa ilmaista algoritmisesti muotojen tunnistamista. Esimerkiksi numerossa 9 tunnistamisen ohje voisi olla: "Numerossa 9 on silmukka ylhäällä ja pystysuuntainen veto oikealla alhaalla".

Neuroverkot lähestyvät ongelmaa eri tavalla. Ideana on ottaa suuri määrä käsinkirjoitettuja numeroita harjoitusesimerkkeinä ja kehittää siitä systeemi, joka voi oppia kyseisistä esimerkeistä. Toisin sanoen neuroverkko käyttää esimerkkejä apunaan tehdäkseen automaattisesti johtopäätöksiä, jotta se voi tunnistaa käsinkirjoitetut numerot. Mitä enemmän harjoitusesimerkkejä on, sitä paremman tarkkuuden verkko voi oppia käsinkirjoitetuista numeroista.

Keinotekoisia neuroneja on kahta tyyppiä, perseptroni (perceptron) ja sigmoid-neuroni (sigmoid neuron). Standardi oppimisalgoritmi neuroverkkoihin on stokastinen gradienttimenetelmä (stochastic gradient descent).

PERSEPTRONIT


Yksi keinotekoinen neuroni on perseptroni. Frank Rosenblatt kehitti perseptoronit 1950- ja 1960-luvulla Warren McCullochin ja Walter Pittsin töiden innoittamana. Nykyisin käytetään tavallisesti toisenlaisia keinotekoisten neuronien malleja, yleisesti sigmoid-neuroneja. Jotta voi kunnolla ymmärtää, miksi sigmaneuronit määritetään niin kuin ne määritetään, on hyvä ymmärtää perseptroneja.

Perseptroniin syötetään useita eri binäärisiä syötteitä (inputeja), ja se tuottaa yhden binäärisen ulostulon (outputin). Ulostulo, joka on arvoltaan 0 tai 1, lasketaan syötteiden painotuksien summan ∑jwjxj  avulla. Painotuksien summan tulee olla yli tai alle jonkin tietyn raja-arvon.

output = 0 jos ∑jwjxj ≤ threshold

output = 1 jos ∑jwjxj > threshold


Perspetronia voi ajatella laitteena, joka tekee päätökset painottamalla eri asioita. Esimerkiksi jos viikonloppuna on festarit, saatat painottaa eri asioita päättääksesi, menetkö sinne vai et. Päätökseen voi vaikuttaa 3 tekijää:

1. Millainen sää on 
2. Haluaako ystäväsi tulla mukaan 
3. Onko festivaaleille helppo päästä julkisilla kulkuvälineillä. 

Päätöksentekoa voi helpottaa mallintamalla sitä perseptroneilla. Näitä kolmea yllä mainittua tekijää voi vastata muuttujat x(sää), x(ystävä)ja x(julkinen liikenne). x1:n arvo voi olla 1, jos sää on hyvä ja 0, jos sää on huono. x2:n arvo voi olla 1, jos ystävä haluaa tulla mukaan ja 0, jos hän ei halua tulla mukaan. x3:n arvo on 1, jos festareille pääsee bussilla ja 0, jos sinne ei pääse bussilla. 

Eri tekijöille voi antaa erilaisia painotuksia. Pidät festareista niin kovasti, ettei päätöksentekoon vaikuta kovin paljon se, tuleeko ystäväsi mukaan vai ei tai se, onko sinne helppo päästä. Näissä painotukset ovat siis pienet ( w1 = 2 ja w3 = 2). Mutta et todellakaan haluaisi olla siellä sateessa, joten sää painaa vaakakupissa enemmän kuin seura ( w2 = 6). Valitset lopuksi perseptronin raja-arvoksi numeron 5. Näillä valinnoilla perseptroni toteuttaa päätöksenteon mallinnuksen tuottamalla ulostulon 1 jos sää on hyvä ja 0, jos sää on huono. Tulokseen ei vaikuta paljoakaan se, onko ystävä tulossa mukaan tai pääseekö sinne bussilla.

Painotuksia ja raja-arvoa muuttamalla saadaan erilaisia päätöksenteon malleja. Jos esimerkiksi raja-arvo olisi 3, halukkuus festareille menemiseen kasvaisi. Perseptronit voivat siis punnita erilaisia tekijöitä tehdäkseen päätöksiä. Mitä mutkikkaampia verkostoja, sitä hienovaraisempia päätöksiä tulisi.

Kuva on otettu osoitteesta http://neuralnetworksanddeeplearning.com/images/tikz1.png


Perseptroneja voi olla eri kerroksissa. Jokainen uusi kerros voi tehdä monimutkaisempia päätelmiä, koska se painottaa aiemman kerroksen syötteitä. Perspetronin kuvausta voidaan yksinkertaistaa esimerkiksi korvaamalla raja-arvo vaikotermillä (bias, b). En mene tässä postauksessa kovin paljon syvällisemmin matematiikkaan, kiinnostuneet voivat katsoa sitä alkuperäiseltä sivulta http://neuralnetworksanddeeplearning.com/chap1.html. Vakiotermi kertoo, miten helppo perseptronin on saada arvo 1, eli miten helppoa perseptronin on aktivoitua. Suurella vakiotermillä perseptronin on todella helppo tuottaa ulostulo 1.  Jos b on hyvin negatiivinen, perseptronin on vaikea saada arvoa 1.

Perseptroneja voidaan käyttää myös laskemaan loogisia funktioita, kuten AND, OR ja NAND-funktioita. NAND-portilla voi laskea mitä tahansa loogisia funktioita, koska se on universaali. Perseptronit ovat tavallaan vain uusi tyyppi NAND-porteista. 

Oppimisalgoritmien avulla voidaan kuitenkin automaattisesti säätää keinotekoisten neuroverkkojen painotuksia ja vakiotermejä. Kyseinen säätäminen tapahtuu vasteena ulkoiseen ärsykkeeseen ilman, että ohjelmoija vaikuttaa siihen suoraan. Oppimisalgoritmien avulla keinotekoisia neuroneja voidaan käyttää tavalla, joka on erilainen verrattuna loogisiin portteihin. Neuroverkot voivat oppia ratkaisemaan ongelmia, jotka olisi vaikea pala perinteisille virtapiireille, esimerkiksi loogisille porteille. Perseptronin ongelmana kuitenkin on, että pienet muutokset painotuksissa tai syötteissä aiheuttavat ison muutoksen tuloksessa (0 /1).


SIGMOID-NEURONIT


Miten oppimisalgoritmeja voi suunnitella neuroverkoille? Olkoon meillä perseptronien verkosto, jota haluaisimme käyttää ongelmanratkaisuun. Syötteet voivat olla esimerkiksi raakapikselidataa skannatusta, käsinkirjoitetusta numeron kuvasta. Verkoston halutaan oppivan painotukset ja vakiotermit niin, että verkoston ulostulo luokittelee luvut oikein. Jotta näemme, miten oppiminen voisi toimia, teemme pienen muutoksen joihinkin painotuksiin tai vakiotermeihin. Tämän pienen muutoksen painotusten suuruudessa tulisi muuttaa ulostuloa vain hieman. Verkosto voisi esimerkiksi virheellisesti luokitella numeron 8 numeroksi 9, jolloin voisimme selvittää, miten tehdä pieniä muutoksia painotuksiin ja vakiotermeihin, jotta verkosto osaisi paremmin luokitella kuvan numeroksi 9. Tätä toistettaisiin niin kauan, kunnes ulostulo olisi parempi, eli verkosto oppisi.

Näin ei kuitenkaan tapahdu, kun käytetään perseptroneja. Perseptroneja käytettäessä pienet muutokset painotuksessa tai vakiotermissä voi aiheuttaa verkon ulostulon ”flippaamisen” radikaalisti esimerkiksi nollasta ykköseen. Esimerkiksi 9 voidaan muutosten jälkeen tunnistaa oikein, mutta muiden kuvien tunnistaminen olisi tällöin luultavasti muuttunut vaikeasti kontrolloitavaksi. Tällöin on vaikea huomata, millä tavalla kannattaa vähitellen muokata painotuksia ja vakiotermejä, jotta verkosto pääsisi lähemmäksi haluttua lopputulosta. Ei siis ole täysin selvää, miten perseptronien verkko voidaan saada oppimaan.

Ongelma ratkeaa uuden tyyppisten keinotekoisten neuronien,  sigmoid-neuronien, avulla. Ne ovat samanlaisia kuin perseptronit, mutta pienet muutokset niiden painotuksissa ja vakiotermeissä aiheuttavat vain pienen muutoksen niiden ulostuloon. Se on tärkeä tekijä  sigmoid-neuronien kyvyssä oppia.

Kuva otettu osoitteesta http://neuralnetworksanddeeplearning.com/images/tikz11.png


Sigmoid-neuroneilla on sisääntulo, mutta ykkösen ja nollan sijaan ne voivat olla mitä tahansa arvoja 0:n ja 1:n väliltä. Sigmoid-neuroneilla on jokaiselle sisääntulolle painotus ja vakiotermi, mutta ulostulo ei ole 0 tai 1, vaan sigmoid-funktio σ(wx+b), joka määritellään σ(z)≡    1 / 1+e−z

Sigmoid-neuronin ulostulo syötteillä x1, x2,..., painotuksilla w1, w2,..., ja vakiotermillä b on

1 / 1+exp(−∑jwjxj−b)


Perseptronien ja sigmoid-neuronien väillä on kuitenkin monia yhtäläisyyksiä, sillä sigmoid-funktion algebrallinen muoto on lähinnä tekninen yksityiskohta. Havainnollistetaan sigmoid-funktion samankaltaisuutta perseptronimallin kanssa: olkoon z≡wx+b jokin suuri positiivinen luku. Tällöin e−z ≈ 0 ja σ(z) ≈ 1. Eli kun  z = w * x + b on suuri ja positiivinen luku, sigmoid-funktio on noin 1, kuten perseptronissa. Mutta jos z = w * x + b on hyvin negatiivinen, e−z → ∞ ja σ(z) ≈ 0, eli ulostulo on 0. Eli kun z = w * x + b on hyvin negatiivinen, sigmoid-neuronin käyttäytyminen on myös lähellä perseptronin käyttäytymistä. Vain silloin, kun z = w * x + b on maltillisen kokoinen, sigmoid-neuroni poikkeaa perseptronin mallista.

Sigmoid-funktion huono ominaisuus on se, että se kasvaa hyvin hitaasti kun x kasvaa ja vähenee hyvin hitaasti kun x vähenee. Sen derivaatta on hyvin lähellä nollaa kun x on suuri tai pieni. Tästä seuraa ongelmia, kun verkkoa opetetaan derivaattoihin perustuvilla menetelmillä. Koska virhefunktion osittaisderivaatat neuronin painotuksien ja vakiotermien suhteen riippuvat aktivointifunktion derivaatasta, ja painotuksien ja vakioiden muutokset koulutettaessa ovat pieniä jos osittaisderivaatat ovat pieniä, verkko oppii hitaasti. Toinen sigmoid-funktion huono puoli on se, että se ei ole symmetrinen nollan suhteen. Nykyisin sitä käytetään lähinnä ulostulokerroksessa varsinkin jos verkon tulokset ovat välillä [0,1][0,1].

HERMOVERKKOJEN ARKKITEHTUURI


Kuva otettu osoitteesta http://neuralnetworksanddeeplearning.com/images/tikz11.png


Vasemmanpuoleisin kerros on syötekerros (input layer), jossa olevat hermosolut ovat syöteneuroneja (input neurons). Oikeanpuolimmaisin ulostulokerros (outputlayer) sisältää ulostuloneuronit (output neurons), joissain tapauksissa vain yhden. Keskimmäinen kerros on piilokerros (hidden layer), koska siinä olevat neuronit eivät ole syötteitä tai ulostuloja. Jos piilokerroksia on useita, niitä kutsutaan joskus perseptronien monikerrokseksi eli MLP:ksi, vaikka siinä olisikin sigmoja.

Syötekerroksen ja ulostulokerroksen verkon suunnittelu on yleensä suoraviivaista, mutta piilokerrosten suunnittelu on usein melkoista taiteilua: ei ole peukalosääntöjä, joilla niitä voisi suunnitella. Piilokerrosten suunnittelussa käytetäänkin apuna heuristiikkaa.

Eteenpäin kytketyiksi verkoiksi (feedforward neural networks) kutsustaan neuroverkkoja, joissa yhden kerroksen ulosotuloa käytetään seuraavan kerroksen syötteenä. Verkossa ei ole siis loopeja eli kiertoja, koska informaatio syötetään aina eteenpäin, ei ikinä taaksepäin.

Toistuviksi / uusiutuviksi keinotekoisiksi neuroverkoiksi (recurrent neural networks) kutsutaan verkkojen malleja, joissa kierto on mahdollista. Näiden mallien ideana on neuronit, jotka ovat aktiivisia tietyn osan ajasta, ennen kuin niistä tulee uinuvia. Aktivointi voi stimuloida muita neuroneja vaikka hieman myöhemminkin, mikä johtaa lopulta monien neuronien aktivoitumiseen. Loopit eivät aiheuta mallissa ongelmia, koska neuronin ulostulo vaikuttaa sen sisääntuloon vasta vähän myöhemmin eikä heti. Nykyisin toistuvien neuroverkkojen opettelualgoritmit ovat vielä vähemmän voimakkaita kuin eteenpäin kytkettyjen verkkojen. Mutta toistuvat neuroverkot ovat silti mielenkiintoisia, koska ne toimivat samankaltaisemmin kuin omat aivomme.

YKSINKERTAINEN VERKKO KÄSINKIRJOITETTUJEN KIRJAINTEN TUNNISTAMISEEN



Käsialan tunnistaminen voidaan jakaa kahteen alaongelmaan.  Ensin kuva lukusarjasta tulisi jakaa yksittäisiin kuviin, esim 456 olisi 4, 5 ja 6. Kuvan jakaminen on helppoa meille ihmisille, muta haasteellista tietokoneohjelmalle. Toiseksi, kun kuva on jaettu, jokainen yksittäinen numero tulee luokitella. Lukusarjan jakaminen yksittäisiin lukuihin onnistuu esimerkiksi siten, että numeroiden luokittelua käytetään lähestymistapana. Kannattaa siis keskittyä toiseen ongelmaan eli numeroiden luokitteluun.

Erottelu saa korkeat pisteet, jos yksittäisen numeron luokittelija on varma kaikkien numeroiden luokittelussa. Alhaisen numeron erottelu saa, jos luokittelijalla on ongelmia joidenkin numeroiden kohdalla. Ideana on, että jos luokittelijalla on jossain ongelma, sillä on luultavasti vaikeuksia siksi, että erottelu on valittu väärin perustein. Tätä ja muita vaihtoehtoisia tapoja voidaan käyttää ratkaisemaan erotteluongelma melko hyvin.

Kuva otettu osoitteesta http://neuralnetworksanddeeplearning.com/images/tikz12.png


Käsinkirjoitetun yksittäisen numeron tunnistamiseen tarvitaan kolmekerroksista neuroverkkoa (yllä). Syötekerros sisältää neuroneja, jotka koodaavat syötepikselien arvot. Verkoston harjoitteludata koostuu monesta 28 x 28 pikselin käsinkirjoitettujen numeroiden kuvista, joten syötekerros koostuu 784 = 28 x 28 neuronista. Syötteen pikselit ovat harmaaväriskaalattuja: arvo 0.0 esittää valkoista, arvo 1.0 esittää mustaa ja väliin jäävät arvot esittävät asteittain tummenevia harmaan sävyjä.

Piilokerroksen neuronien lukumäärää kuvataan n:llä. Ulostulokerros sisältää 10 neuronia. Jos ensimmäinen neuroni aktivoituu eli sen ulostulo on 1, se merkitsee, että verkko ajattelee numeron olevan 0. Jos toinen neuroni aktivoituu, se osoittaa, että verkko ajattelee numeron olevan 1 jne. Tarkemmin sanottuna ulostuloneuronit numeroidaan luvuilla 0-9 ja selvitetään, millä neuroneista on korkein aktivointiarvo. Jos se on kutosella, verkko arvaa, että syötekuva oli 6.

OPPIMINEN GRADIENTTIMENETELMÄN AVULLA


Miten neuroverkko voi oppia tunnistamaan numeroita? Sen täytyy ensin oppia ns. harjoitusdatasetistä.  Esimerkiksi MNIST datasetti sisältää kymmeniätuhansia skannattuja kuvia käsinkirjoitetuista numeroista sekä niiden oikeat luokittelut. MNIST data on kaksiosainen. Ensimmäinen osa sisältää 60 000 kuvaa, joita käytetään harjoitusdatana. Nämä kuvat on skannattu 250 ihmisen käsinkirjoitetuista näytteistä. Kuvat harmaaväriskaalataan ja asetetaan 28 x 28 pikselin kokoisiksi. Toinen osa MNISTin datasetistä sisältää 10 000 kuvaa, joita voi käyttää testidatana. Nekin ovat 28 x 28 harmaaväriskaalattuja kuvia. Testitataa käytetään arvioimaan, kuinka hyvin hermoverkko on oppinut tunnistamaan numeroita. Jotta saavutettaisiin mahdollisimman hyvä suoritus, testitdata otettiin 250 eri ihmiseltä kuin alkuperäinen harjoitusdata. Se varmistaa, että systeemi kykenee tunnistamaan numeroita ihmisiltä, joiden kirjoitusta se ei ole nähnyt harjoituksen aikana.

x:llä ilmaistaan harjoitusyötettä. Jokainen harjoitussyöte x on 28 x 28=784 -ulotteinen vektori. Jokainen vektorin alkio edustaa kuvan yksittäisen pikselin harmaa-arvoa (grey value). Haluttua ulostuloa merkitään y = y(x), missä y on 10-ulotteinen vektori. Halutaan algoritmi, mikä auttaisi löytämään painotukset ja vakiotermit niin, että verkon ulostulo vastaisi y(x):ää kaikilla harjoitussyötteillä x. Jotta voidaan arvioida, miten hyvin tämä tavoite on saavutettu, määrittetään virhefunktio C:


Virhefunktio C kertoo, miten hyvin verkon ulostulo vastaa y(x):ää kaikilla harjoitussyötteillä x. Jos C on lähellä nollaa, harjoitusalgoritmi on suoriutunut hyvin. Mikäli C:n arvo on suuri, se tarkoittaisi, ettei y(x) ole monilla syötteillä lähellä ulostuloa a. Halutaan siis löytää sellaiset painotukset ja vakioarvot, jotka tekevät C:n mahdollisimman pieneksi. Se onnistuu käyttämällä algoritmiä nimeltään gradienttimenetelmä.

Gradienttimenetelmän päämääränä on siis löytää painotukset ja vakiotermit, jotka minivoivat virhefunktio C(w,b):n arvon. Oppimisessa gradienttimentelmää käytetään korjaamaan neuronien parametrit. Tarkempaa tietoa gradienttimenetelmän matemaattisesta puolesta ja sen periaatteista voi lukea alkuperäiseltä sivulta http://neuralnetworksanddeeplearning.com/chap1.html
_________________________________________________________________________

Siinä oli hieman infoa ja käsitteitä neuroverkoista ja siitä, mihin koneoppiminen neuroverkkojen avulla perustuu. Hirmuisen mielenkiintoista! 

Ei kommentteja:

Lähetä kommentti