Neurális Hálók és a Funkcionális Programozás Berényi Dániel Wigner GPU Labor
Alapvető építőkövek Függvény kompozíció Automatikus Differenciálás (AD) 2
Neurális Háló, mint kompozíció Bemenetek Súlyok w Függvények Súlyok Függvények Kimenetek x i y k w z l g f o o = f g net = f g x i y k = g i w ik x i + b k z l = f k w kl y k + b l 3
Neurális Háló, mint kompozíció Felügyelt tanítás esetén vannak bemenet-kimenet párjaink: s q = (x i q, o q) A háló kimenetén definiálunk egy hibafüggvényt (loss) az elvárt és kapott kimenet közé, pl.: L 0 (u, v) = 1 u v 2 2 Ha rögzítjük az elvárt kimeneteket a hibafüggvényben: L v q = L 0 (o q, v q ) 4
Neurális Háló, mint kompozíció A neurális háló tanítása a súlyok (w_ij) és biasok (b_i) beállítása A tanításhoz írjuk teljes hálót a hibával együtt röviden kompozícióként: Cél e(x) minimalizálása A minimumban: e x = (L f g)(x) e w ij = 0 e b i = 0 Illetve bármilyen más paraméterre a hálóban... 5
Neurális Háló, mint kompozíció A legegyszerűbb és legszéleskörűbben használt módszer a Gradiens Módszer: ahol α a tanulási ráta w (n+1) = w (n) α e w e(w) α e w e w Elő kell tehát állítani a teljes háló paraméterek szerinti deriváltját 6
Neurális Háló, mint kompozíció Szükség van tehát a teljes kompozíció deriváltjára, de ismert: Továbbá: f g = f g g f g h = f g h g h h 7
Automatikus differenciálás Ha van egy függvény kompozíciónk (vagy egy számítási gráfunk), az automatikus differenciálás segítségével kiszámolhatjuk a deriváltak numerikus értékeit, két féle módszerrel: Előrefelé módszer Hátrafelé módszer 8
Automatikus differenciálás Előrefelé módszer f g h = f g h g h h 1. Rögzítjük a független változót, ami szerint szeretnénk deriválni pl.: x j h 2. Kiszámoljuk és lederiváljuk a legbelső lépést, pl.: h x i = x i, = δ x ij j 3. Továbbadjuk az függvény értéket és a derivált értékét h x i, h x j 4. Kiértékeljük a következő függvényt az előző értéknél g(h x i ), Kiszámoljuk a következő függvény deriváltját és beszorozzuk az előző deriválttal: g h h x j 5. tovább adjuk a párt: g(h x i ), g h 6. Ismételjük kifelé a 4-5. lépéseket h x j 9
Automatikus differenciálás f g h = f g h g h h Hátrafelé módszer 1. Kiszámoljuk előre az egyes műveleteket és letároljuk a részeredményeket 2. Rögzítjük a kimeneten (f) a függő változót, aminek a deriváltja 1f 3. Kiszámoljuk ennek az utolsó függvénynek a deriváltját a bemenetek szerint, pl.: f g 1, g 2 = g 2 f 1 + 3g 2, = 2g g 1 g f 1, = 3g 1 g 2 2 Ahol expliciten kell egy részeredmény (csak nem lineáris esetben!) oda behelyettesítjük az 1. lépésből 4. Visszük magunkkal a kapott rész kifejezéseket a megfelelő irányokba 5. Kiszámoljuk az eggyel korábbi kifejezések deriváltjait: g g 1 = 5h 1, 1 g = 5h h 1 g 2 = 9 + 10h 2, 2 = 10h 1 h 2 2 6. Hozzá szorozzuk a korábbi részkifejezésekhez és visszük tovább: (2g 1 5, 3 10) 7. Ismételjük kifelé 10
Automatikus differenciálás Ha több változós függvényeink vannak, akkor a lánc szabály: f g i f g = g g i i x j Azaz, összegezni kell a bemenő élekre i f g 1 g 2 Ez iterálva kombinatorikus felrobbanáshoz vezet, ha sok a bemenő él és az előre felé módszerrel számoljuk, mert minden kezdőpontból nagyon sok út mentén kellene követni a deriváltakat x 1 x 2 x 3 11
Automatikus differenciálás Másképp, ha a függvényünk R n R m, és a fában N művelet van, Akkor az előre módszernél minden változóra egyenként végig kell mennünk a fán, ami nn költségű f A hátra módszernél minden végpontból egyszer kell elindulni a fán, ezért ennek a költsége mn g 1 g 2 x 1 x 2 x 3 Ez a két módszer csak két szélsőség, az optimális kiértékelés NP nehéz 12
Automatikus differenciálás Következmény: Összegző, redukáló jellegű hálózatoknál a hátrafelé módszer kevesebb műveletet igényel, mint az előrefelé módszer A kevés bemenetből egyre több és több kimenetet előállító hálózatok azonban az előrefelé módszerrel deriválhatóak könnyebben f g 1 g 2 x 1 x 2 x 3 13
Tanítás A Neurális Hálók tipikusan sok adatból állítanak elő kevés adatot, ezért a hátrafelé módszerrel deriválhatóak (back propagation) További könnyedség, hogy a legtöbb lépés lineáris, ekkor nincs szükség a függvény értékre, csak a súlyok szorzófaktoraira A hátrafelé szállított szorzatot most δ-val fogjuk jelölni. 14
Tanítás A derivált számolását a háló kimenetén kezdjük, ahol a hiba függvény (L) található: f(x i ) = i w i x i + b e = L f = L f f w i n+1 = w i n α e w i = w i n α L f x i x i δ 15
Tanítás A háló egy belső rétegében: y = g x i = w i x i + b f k y = w k q(y) i e = f k g = f k g g w i n+1 = w i n α e w i k k f 1 f 2 g = w i n α k f k g i (x k ) x i x 1 x 2 x 3 16
Tanítás A háló egy belső rétegében: y = g x i = w i x i + b f k y = w k q(y) i e = f k g = f k g g w i n+1 = w i n α e w i k k f k y = q y w k δ k = w i n α f k g i (x k ) x i = w i n α δ k w k x i k k 17
Tanítás A paramétereket változtató gradienseket igazából fel kell összegezni a tanító halmaz elemeire, és elvileg csak azután lenne egy léptetés, ha mindegyikre kiszámoltuk a gradienst: s q = (x i q, o q) tanító halmaz, q = 1 N n e(xi w (n+1) = w (n) q α ) w q Praktikusan általában kisebb csoportokban frissítik a súlyokat (batching): n < N 18
Gyakori réteg típusok 19
Gyakori réteg típusok Elemenkénti transzformáció (1 bemenet, 1 kimenet) Leginkább a nemlinearitás, általában: f x = tanh x f x = tanh x f x = 1 + e x 1 (szigmoid) f x = max 0, x (Rectified Linear Unit, ReLU) f x = ln(1 + e x ) (softplus) 20
Gyakori réteg típusok Affin transzformáció: f x i = i w i x i + b f x i f x i f x i = w x i = x i w i i b = 1 21
Gyakori réteg típusok Teljesen összefüggő: A két réteg minden eleme minden másikkal össze van kötve Minden élre egyedi súlyt teszünk, azaz Két N elemű réteg között N 2 számú súly lesz Ez nagyon flexibilis, de az N 2 költség a gyakorlatban túl nagy 22
Gyakori réteg típusok Konvolúció (igazából autokorreláció): w kevesebb elemű, mint x, és f x w darab elemet fog tartalmazni. f x n = i w i x n+i f x n x i = w i n f x i w i = x n+i 23
Gyakori réteg típusok Redukció (pooling, subsampling): Lényegében bármilyen R n R deriválható fv., a lényeg: nincs átfedés a bemenetek között (szemben a konvolúcióval). y = f(x 1, x 2, x n ) Példák: átlag: f x = 1 n σ i n x i, max: f x = max x i, f x i = 1 n f = ቊ 1, x j = max(x i ) x j 0, else A fordított is létezik, de nehezebb: dekonvolúció 24
Gyakori réteg típusok Más redukció, kifejezetten a hibafüggvényre: Cross-entropy C = 1 n x o ln y + 1 o ln 1 y ahol o az elvárt kimenet, y az aktuális kimenet, x-ek a bemenetek, y = f i w i x i + b Tulajdonságok: C > 0, ha belül minden változó [0, 1]-beli Ennek a deriváltja nem arányos f -el, ezért nem lassul le a tanulás kis hibáknál. 25
Gyakori réteg típusok Redukciós transzformáció elemsokaságon Példa: Softmax R n R n f x 1,, x n i = ex i σ k e x k Ez egy normalizált összeg, ahol a végén σ i f i = 1 Tipikusan a klasszifikáló hálók kimenetén található 26
Bonyolultabb hálózatok Az eddigi hálók irányított aciklikus gráfokkal reprezentálhatóak Ez izomorf egy névfeloldásos számítási fával, mint egy lambda kalkulus 27
Rekurrens hálózatok Visszakötés, visszacsatolás a saját/korábbi csúcsokhoz 28
LSTM Manapság a legnépszerűbb RNN: Long short-term Memory (LSTM) (link) Könnyű tanítani, 4 súly f:felejtés, i:input, o:output, c:cell (memória) C t = σ W f h t 1, x t + b f C t 1 + σ W i h t 1, x t + b i tanh W C h t 1, x t + b C h t = σ W o h t 1, x t + b o tanh(c t ) *: pontonkénti szorzás Forrás: colah.github.io 29
LSTM tanítás Az LSTM és néhány más rekurrens háló úgy tanítható, hogy valamennyi lépésig kitekerjük az ismétlést: Ezek után olyan hosszú bemenet-kimenet pár sorozat kell, amennyi lépést kitekertünk +egy kezdő tipp x0-ra Innen már a szokásos backpropagation használható 30
Encoder-Decoder RNN-ek Eredeti cikk: K. Cho et al Encoder: egy változó hosszú inputot egy fix hosszú vektorba kódol Decoder: egy fix hosszú inputot egy változó hosszú outputtá alakít Az adatok végét speciális értékek jelzik mindkét esetben 31
Általános adatfolyam transzformátorok Ha egyszerre történik az encode és decode lépés, az lényegében egy általános RNN, általános transzformációról beszélhetünk 32
Kétirányú transzformátorok Ha a tradicionális RNN-el szemben ellenkező irányba is van csatolás Tanítás a két irányban függetlenül 33
RNN alkalmazási területek Természetes nyelvek feldolgozása (fordítás, beszéd felismerés) Kézírás felismerés Idősorok jóslása (akár zene) Kémiai szerkezet jóslás 34
Rekurzív Neurális Hálók (Nem rekurrens!) Itt egy fa struktúrában minden elágazásál ugyan azokat a súlyokat használják A tanítás nehézkesebb (sztochasztikus gradiens módszer) 35
Rekurzív Neurális Hálók (Nem rekurrens!) Alkalmazások: Mondatelemzés Parafrázis detektálás Kép értelmezése 36
NN programozási rendszerek Caffe (UC Berkeley, C++, python) TensorFlow (Google, C++, python) Theano (Université de Montréal, python) Torch (C++, Lua) 37
Funkcionális Programozás Mi köze a neurális hálóknak a funkcionális programozáshoz? 38
Funkcionális Programozás 1.: A hálók általánosan egy irányított gráffal reprezentálhatóak Ha a rekurrens részeket nem tekintjük, akkor irányított aciklikus gráffal (Directed Acyclic Graph, DAG) Ezek izomorfak egy névfeloldásos számítási fával, ami izomorf a lambda kalkulussal, ami mint korábban láttuk a Cartesian Closed Category-k természetes nyelve Ha van ciklikus rész, az egy rekurzióval helyettesíthető 39
Funkcionális Programozás 2.: A hálók alapvető építőköveiben felismerhetjük az ismert funkcionális programozási magasabb rendű műveleteket 40
Funkcionális Programozás Elemenkénti nemlinearitás, vagy más függvény hattatása egy Funktor struktúrára (s): map :: (a->b) -> s a -> s b 41
Funkcionális Programozás Elemenkénti összefésülés, egyesítés: zip :: (a->b->c) -> s a -> s b -> s c 42
Funkcionális Programozás Elemsokaság redukálása egy bináris művelettel: foldl :: (a->b->a) -> a -> s b -> a foldr :: (b->a->a) -> a -> s b -> a 43
Funkcionális Programozás Egy elemből elemsokaság előállítása egy művelettel: unfoldl :: (a->(a, b)) -> a -> s b unfoldr :: (b->(b, a)) -> a -> s b 44
Funkcionális Programozás Elemsokaságból redukció és transzformáció egyben (egy map és egy fold lépésenkénti összefésülése) mapaccuml :: (a->b->(a, c))-> a -> s b -> (a, s c) 45
Funkcionális Programozás Rekurzív struktúrák redukálása / alulról felfelé transzformációja: Katamorfizmus: cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree 46
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree Típusa: Fix f ahol f a = Const Int Add a a Mul a a 47
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Az unfix után a típusa: f (Fix f) 48
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a A map mind két gyerekre hattatja a (cata alg) függvényt 49
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Újabb unfix, felfedi a belső típust... 50
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Ezen az ágon még egy map fog történni... Majd utána unfix... 51
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a A végső konstans ágakban a map nem csinál semmit, mert nincs gyerek... 52
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Ekkor jutunk csak el oda, hogy hattassuk alg-ot, az algebrát 53
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Legyen most az algebra egy kiértékelő algebra, ami a következőt csinálja: Const esetben visszaadja a tárolt Int-et Add esetben visszaadja a két ág összegét Mul esetben visszaadja a két ág szorzatát 54
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a alg tehát először a konstansokat értékeli ki, és visszaadja az előző függvényhívásba A visszaadott érték a=int, ez a carrier type 55
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a A szorzásnál a map cata alg eredménye egy f Int, mégpedig Mul Int Int ággal Tehát ezt az alg megfelelő ága le tudja kezelni és kiszámolja a szorzatot 56
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a A szorzásnál a map cata alg eredménye egy f Int, mégpedig Mul Int Int ággal Tehát ezt az alg megfelelő ága le tudja kezelni és kiszámolja a szorzatot 57
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Ekkor a legkülső cata híváshoz térünk vissza Ahol az alg Add Int Int ága összeadja a 10-et és 3-at. 58
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree f a = Const Int Add a a Mul a a Ekkor a legkülső cata híváshoz térünk vissza Ahol az alg Add Int Int ága összeadja a 10-et és 3-at. 59
Funkcionális Programozás cata :: (f a -> a) -> Fix f -> a A katamorfizmus direktben kategóriaelméletből jön ki (linkek), ahol rekurzív típusokra belátható az alábbi diagramm kommutálása: fmap (cata alg) f (Fix f) f a unfix alg Fix f cata a 60
Funkcionális Programozás A katamorfizmusok speciális esetei a fold-ok, hiszen a listák (vektorok) rekurzív típusok: List a r = [a] = Empty Node a r ahol a a tárolt adat típusa, r a rekurzív pozíció. 61
Funkcionális Programozás A katamorfizmusok duálisai az anamorfizmusok, Amelyek lebontás helyett felépítenek, vagy felülről lefelé járnak be. Ezek spec esetei az unfoldok. cata :: (f a -> a) -> Fix f -> a cata alg tree = (alg. (map cata alg). unfix) tree ana :: (a -> a) -> a -> Fix f ana coalg tree = (fix. (map ana coalg). coalg) seed 62
Funkcionális Programozás A funkcionális építőkövek és réteg típusok megfeleltetése: Háló réteg típus Funkcionális primitív Elemenkénti függvény hattatás map Kódoló RNN fold Dekódoló RNN unfold Általános RNN mapaccum Kétirányú RNN Zip f (mapaccuml...) (mapaccumr...) Konvolúció első szomszéddal Rekurzív NN Zip f xs (tail xs) cata 63
Funkcionális Programozás 3.: A FP magasabb rendű függvényei differenciálható függvényekre differenciálható függvényeket eredményeznek Ezért ha ezeket komponáljuk, akkor az egész kifejezés deriválható lesz. A neurális hálók optimalizálása (tanítása) ezért lehetséges 64
Funkcionális Programozás 3.: A FP magasabb rendű függvényei differenciálható függvényekre differenciálható függvényeket eredményeznek Ez onnan látható, hogy a magasabbrendű függvények csak a szerkezetet mondják meg (gráfként nézve a topológiát), a konkrét függvényt mindig a felhasználó adja meg. Ha a megadott függvény differenciálható, akkor a magasabbrendű függvény is az. 65
Funkcionális Programozás 4.: Mivel a hálók függvények kompozíciói, ezért tárgyalhatóak kategória elméleten belül, és azonosságok vezethetőek le számos speciális esetben. Ezek a fúziós összefüggések lehetővé teszik egyes lépések összeolvasztását, egyszerűsítését. map f. map g = map (f.g) zip f (map g u) (map h v) = zip (\x, y->f (g x) (h y)) u v fold f z (map g u) = fold (\x, y -> f x (g y)) u cata alg1. cata alg2 = cata (alg1. alg2) 66
Összefoglalás A neurális hálók lényegében differenciálható függvények kompozíciói A hálók rétegei magasabb rendű függvényekként is tekinthetőek Ezek fajtái kategória elméletből motiváltak és innen következnek a műveleti tulajdonságaik is A műveleti tulajdonságok következményeként hatékony eljárások léteznek a deriválásra (ami a tanítás alapvető eleme), valamint az egyszerűsítésre 67