ImageRecognition toteutus Simo Korkolainen 27 kesäkuuta 2016 Projektin tarkoituksena on tehdä ohjelma, joka opettaa neuroverkon tunnistamaan kuvia backpropagation-algoritmin avulla Neuroverkon opetuksessa verkon painoja muutetaan liikuttamalla niitä virhefunktion gradientin vastaiseen suuntaan, kunnes virhefunktio on minimoitunut ja neuroverkko on oppinut tunnistamaan kuvat Derivoinnin ketjusääntöön perustuva backpropagation-algoritmi mahdollistaa gradientin nopean laskemisen 1 Neuroverkko Neuroverkko koostuu kerroksista, joissa on neuroneita Olkoon L neuroverkon kerroksien lukumäärä Olkoon l k kerroksen k = 1,, L neuronien lukumäärä Merkitään kerroksen k aktivaatiota vektorina z k R l k Ensimmäisen kerroksen aktivaatio z 1 on neuroverkon syöte ja viimeisen kerroksen aktivaation z L on neuroverkon antama tuloste Jokaisen kerroksen k > 1 aktivaation voidaan ajatella laskettavan parametrisoidun funktion f k : R l k 1 A k R l k avulla Tässä A k on verkon kerroksien k 1 ja k yhteyksien painoina toimivien parametrien joukko Kerroksen aktivaatio lasketaan rekursiivisesti kaavan z k = f(z k 1, a k ) avulla, missä a k A k Parametrit a 1,, a L on tarkoitus oppia backpropagationalgoritmia käyttäen 2 Aineisto ja kokonaisvirhe Olkoon x 1, x 2,, x n R l 1 neuroverkon opetussyötteitä ja y 1, y 2,, y n R l L syötteitä vastaavia tavoitetuloksia Olkoon E : R l L R l L R virhefunktio Merkitään syötteen x j aiheuttamaa aktivaatiota kerroksessa k merkinnällä z j k, jolloin syötekerroksessa pätee zj 1 = x j Määritellään neuroverkon kokonaisvirhe kaavalla n E tot = E(z j L, y j) j=1 Backprobagation-algoritmin tarkoituksena on valita parametrien a 1,, a L arvot siten, että kokonaisvirhe E tot minimoituu 1
Jos neuroverkkoa käytetään syötteiden luokittelemiseen erillisiin luokkiin 1,, S = l L, viimeisen kerroksen z L = (z L1,, z LS ) aktivaation z Lm tulkitaan tarkoittavan todennäköisyyttä, että syöte x j kuuluu luokkaan m Halutuksi tulokseksi valitaan y jm = 1, kun x j kuuluu luokkaan m ja y jm = 0 muulloin Luokittelun tapauksessa on luontevaa käyttää viimeisessä kerroksessa softmax-funktiota f L : R S A L (0, 1) S, missä f Lm (z L 1 ) = ll 1 e i=1 a mi z (L 1)i Sk=1 e l L 1 i=1 a ki z (L 1)i Softmax-funktion kuva-alkion komponenttien summa on yksi Luokittelussa virhefunktiona käytettään yleensä logloss-virhettä Tässä tapauksessa virhefunktio määritellään kaikilla s {0, 1} S ja t (0, 1) S kaavalla S E(s, t) = s m log(t m ) m=1 3 Derivaatta ja ketjusääntö Tässä kappaleessä käytetään yleisiä differentiaalilaskennan merkintöjä aiemmista merkinnöistä huolimatta Olkoon funktio f = (f 1,, f n ) : R m R n derivoituva Derivaatalla pisteessä x 0 R m tarkoitetaan matriisia missä osittaisderivaatat f i(x 0 ) x j f 1 (x 0 ) f x f 1 1 (x 0 ) x m (x 0 ) =, f n(x 0 ) x 1 f n(x 0 ) x m on määritelty kaavalla f i (x 0 ) x j f i (x 0 + he j ) f i (x 0 ) = lim h 0 h 2
Olkoon lisäksi funktion g : R n R p derivoituva Tällöin yhdistetty kuvaus g f : R m R p on myös derivoituva ja yhdistetyn kuvauksen derivaatan pisteessä x 0 on mahdollista laskea kaavalla (g f) (x 0 ) = g (f(x 0 ))g (x 0 ) 4 Backpropagation-algoritmi Backpropagation algoritmi perustuu edellä mainittuun differentiaalilaskennan ketjusääntöön Merkitään +1 = z (i+1)1 z (i+1)1 li 1 z (i+1)li+1 1 = a i 1 li+1, ja z (i+1)li+1 li [ ] tot tot = z 1 tot li i Ketjusäännön perusteella eri kerrosten aktivaatioiden virhegradientti voidaan laskea rekursiivisesti tot = tot +1 +1 Eli, jos tiedämme ylemmän kerroksen virhegradientin tot +1 arvon, voimme laskea alemman kerroksen virhegradientin kertomalla gradienttia tot +1 oikealta matriisilla +1 Parametrien virhegradientti voidaan laskea vastaavasti käyttäen aktivaatioiden virhegradienttia tot = tot Seuraavaksi on esitettynä pseudokoodi backpropagation-algoritmille, 3
Algorithm 1 Backpropagation-algoritmi 1: procedure Backpropagation(x, y, α) 2: 3: for j = 1,, n do 4: 5: Forward propagation(x j ) 6: Backward propagation(y j, α) 7: 8: end for 9: 10: end procedure 11: 12: procedure Forward propagation(x) 13: 14: Aseta syöte z 1 = x 15: for jokaiselle kerrokselle k = 2,, L do 16: Laske aktivaatio z k := f k (z k 1, a k ) 17: end for 18: 19: end procedure 20: 21: procedure Backward propagation(y, α) 22: 23: Laske virhegradientti z L arvojen y ja z L avulla 24: for jokaiselle kerrokselle k = L 1,, 2 do 25: 26: Laske ensiksi z k+1 z k arvon z k avulla 27: Laske toiseksi z k := z k+1 z k+1 z k 28: Laske kolmanneksi tot 29: := tot 30: Päivitä painot a i := a i α tot 31: 32: end for 33: 34: end procedure 4
5 Aikavaativuus Tarkastellaan seuraavaksi Backpropagation-algoritmin aikavaativuutta Neuroverkoon liittyvät aikavaativuudet riippuvat paljon neuroverkon rakenteesta Tarkastellaan ensiksi eteenpäinvirtauksen, eli neuroverkon aktivaatioden laskemisen aikavaativuutta Ohjelmassa käytetään vain eteenpäin kytkettyjä neuroverkkoja Neuroneiden aktivaatio z k kerroksessa k lasketaan täsmälleen edellisen kerroksen aktivaatioiden perusteella eli z k = f(z k 1, a k ) missä f on aktivaatiofunktio Kuten aikasemmin olkoon L neuroverkon kerroksien lukumäärä ja olkoon l k kerroksen k = 1,, L neuronien lukumäärä Jos jokainen kerroksen k neuroni on kytketty kaikkiin edellisen kerroksen solmuihin ja neuronipariin liittyvän laskennan aikavaativuus on luokkaa O(1), yhden kerroksen k neuronin aktivaation laskemisen aikavaativuus on luokkaa O(l k 1 ) Koska kerroksessa k on l k neuronia, koko kerrokseen liittyvän laskennan aikavaativuus on O(l k 1 l k ) Ensimmäisen kerroksen eli syötekerroksen aktivaatioden asettamisen aikavaativuus on O(l 1 ) Koko neuroverkon aktivaatioden laskennan aikavaativuus T act on kerrosten aikavaativuuksien summa eli T act = O(l 1 + l k 1 l k ) Edellisen summan ymmärtämiseksi tarkastellaan erikoistapausta, jossa kerrosten neuronien lukumäärä pienee eksponentiaalisesti eli l k = α k 1 l 1, missä 0 < α < 1 Tällöin l 1 + l k 1 l k = l 1 + α k 2 l 1 α k 1 l 0 = l 1 + l1 2 α 2k 3 L 2 = l 1 + l1α 2 (α 2 ) k Saamme, että T act = O(l1 2 α ), koska l 1 + l 2 1α k=0 k=0 = l 1 + l1 2 α 1 α 2 5 1 α 2 (α 2 ) k on positiivinen vakio
Vaikka takaisinvirtaus vaikuttaa vaikeammalta, soittautuu, että takaisinvirtausvaiheen laskenta on yhtä haastastavaa kuin eteenpäinvirtauksen laskenta Ohjelmassa jokaiseen kerroksen k neuroniin m liittyy painovektori a km ja yksittäisen neuronin aktivaatio lasketaan tyypillisesti kaavan z km = f km (a T kmz (k 1)m ) avulla Tässä kuvaus f km : R R on neuronin aktivaatiofunktio, joka on derivoituva Osittaisderivaatta km z z voidaan laskea ketjusääntöä käyttäen (k 1)m seuraavan kaavan avulla z (k 1)j = a kmj f km(a T kmz (k 1)m ) Pistetulon a T km z (k 1)m laskemisen aikavaativuus on O(l k 1 ), koska kerroksessa k 1 on l k 1 neuronia Nyt voisi ajatella, että vaakavektorin z [ km zkm = z z (k 1)1 (k 1) ] z (k 1)lk 1 laskennan aikavaativuus olisi O(l 2 k 1 ), koska O(l k 1) operaatiota toistetaan l k 1 kertaa Kuitenkin huomaamme, ettei skalaaria f km (at km z (k 1)m) tarvitse laskea useita kertoja Tätä ajatusta jalostaen pätee kaava z (k 1) = f km(a T kmz (k 1)m )a T km, z k z k 1 z (k 1) jossa vektorin ja skalaarin kertolaskun aikavaativuus on O(l k 1 ) Yhteensä vektorin laskemisen aikavaativuus on O(l k 1 +l k 1 ) = O(l k 1 ) Matriisin R l k 1 l k laskemiseen kuluu kaikkien rivien laskemiseen tarvittavien aikojen summa, joten aikavaativuus on O(l k 1 l k ) Kaikkien kerrosten matriisien laskemisen aikavaatimus on z k z k 1 Kerroksen virhegradientin O( l k 1 l k ) z k 1 on mahdollista laskea kaavalla = z k z k 1 z k z k 1 Tällöin lasketaan 1 l k 1 -vektorin ja l k 1 l k -matriisin tulo, jonka aikavaativuus on O(l k 1 l k ) Viimeisen kerroksen virhegradientti z L pitää laskea 6
erikseen Laskennan aikavaativuus on O(l L ), koska virhegradienttin laskeminen vie vakioajan jokaista vektorin z L komponenttia kohden Vastaavasti kaikkien kerroksien virhegradienttien z L laskemisen aikavaativuus on O(l L + l k 1 l k ) = O( l k 1 l k ) Virhegradientin parametrivektorin a km suhteen pystyy laskemaan kaavalla a km = a km = f km(a T kmz (k 1)m )z T (k 1) a km Tämän laskennan aikavaatimukseksi tulee O(l k 1 ) Kaikkien gradienttien laskennan aikavaativuus kerroksessa k on O(l k 1 l k ) Koko neuroverkoon littyvien gradienttien a km O( laskennan aikavaativuus on l k 1 l k ) Edellisten päättelyiden perusteella koko takaisinvirtauksen aikavaativuus on O(3 l k 1 l k ) = O( l k 1 l k ) Kokonaisuudessaan yhden backpropagation-algoritmin iteraation aikavaativuus on myös O( L l k 1 l k ) Kun iteraatiota on K kappaletta ja kuvia on n kappaletta, aikavaativuus on yhteensä O(nK L l k 1 l k ) Algoritmin aikavaativuutta on vaikeaa parantaa lisäämällä tilavaativuutta, koska aikavaativuus aiheutuu neuroverkon rakenteesta Tilavaativuutta lisäämällä on kuitenkin mahdollista vaikuttaa aikavaativuuden vakiokertoimeen Tämä tapahtuu tallentamalla laskennan välitulokset taulukkoihin sen sijaan, että samat laskut suoritettaisiin aina uudelleen 6 Ohjelman toimivuus ja syötteiden vaikutus Jos opetusdatassa on vähän kuvia ohjelma oppii tunnistamaan opetusdatan kuvat täydellisesti Neuroverkkojen teorian perusteella neuroverkon on mahdollista saada vastaamaan mitä tahansa hyvin käyttäytyvä funktiota, kunhan neuroneja ja kerroksia on tarpeeksi Hyvästä opetusdatan oppimistuloksesta huolimatta ohjelma ei opi tunnistamaan testidatan kuvia kovinkaan hyvin 7
e x 0 e x +e x 1 0 Jos opetusdatan kuvien määrä on suuri, opetukseen kuluu paljon aikaa Oppimistulos opetusdatassa ei ole niin hyvä kuin siinä tapauksessa, että neuroverkko pääsee ylisovittamaan painonsa pieneen määrään opetuskuvia Testidatan kuvia ohjelma luokittelee paremmin kuin silloin kuin opetusdatassa oli vähän kuvia Jos oppimisnopeutta säätelevä parametri (learning rate) valitaan väärin tulokset eivät ole kovinkaan hyviä, koska painot eivät muutu alkuperäisistä satunnaisista painoista Jos learning rate on liian suuri painot rupeavat värähtelemään voimakkaasti Esimerkiksi painot voivat tässä tilanteessa saada arvoja 0, 10, 100, 1000, 10000, 100000 Pahimmassa tapauksessa painot muuttuvat NaN arvoisiksi, koska e x pyöristyy nollaksi, kun x on suuri Tällöin ohjelmassa yritetään laskea jakolaskun tapainen lasku, mikä ei ole määritelty Ohjelma ei kaadu vaikka painot muuttusivat NaN arvoisiksi, mutta neuroverkko pitää alustaa uudelleen, jos haluaa käyttää kaikkea ohjelman toiminnallisuutta 7 Parannusehdotuksia Yksi tapa parantaa ohjelman toimintaa olisi datan esikäsittely pääkomponenttianalyysin avulla Pääkomponenttianalyysin avulla kuvista olisi saanut valmiiksi hyviä piirteitä, jotka olisivat helpottaneet neuroverkon oppimisprosessia Pääkomponenttianalyysin toteuttaminen on sen verran haastavaa, että siitä olisi voinut tehdä oman kurssityön Toinen tapa parantaa ohjelman toimintaa olisi ollut konvoluutioden lisääminen neuroverkkoon Konvoluutiot ovat hyödyllisiä kuvantunnistuksessa, koska kuvan kaikki pikselit käyttäytyvät melko samalla tavalla riippumatta pikselin sijainnista kuvasta Jos jostakin kohtaa kuvaa opitaan hyvä piirre, kuten reuna, tästä piirteestä olisi mahdollisesti hyötyä myös muualla Konvoluutiot eivät nykyisyydellään sovellu ohjelman rakenteeseen ilman merkittävää laskennallista haittaa, joka vältettäisiin erilaisella ohjelman rakenteella Ohjelmakoodissa on oletettu, että neuroverkon kerrokset ovat kokonaan kytkettyjä edelliseen kerrokseen Lisäksi on oletettu, että painot liittyvät vain yhteen neuroniin Nämä oletukset yksinkertaistavat differentiaalilaskennan matematiikkaa Konvoluutiot lisättäessä molemmat oletukset jouduttaisiin hylkäämään, minkä seurauksena suuri osa ohjelmakoodia pitäisi kirjoittaa ja testata kokonaan uudelleen 8