Neuronová síť od nuly: zpětné šíření chyby krok za krokem
Dopředný průchod a zpětné šíření chyby ručně s konkrétními čísly, řetízkové pravidlo, kontrola numerickou derivací, učení XOR ze sta náhodných startů a síť, která si na dvou měsících ohne hranici sama.
Série Základy AI Díl 62 z 83
- Mapa umělé inteligence: co je co a jak to do sebe zapadá
- Stručná historie umělé inteligence: od Turinga po jazykové modely
- Data, model, trénink, inference: základní pojmy na jednom příkladu
- Jak číst matematický zápis: symboly, indexy, sumy a kvantifikátory
- Množiny a relace: stavebnice, ze které se skládají definice v AI
- Funkce a zobrazení: proč je každý model v AI funkce
- Logika a důkazy: pravidla, podle kterých se v AI uvažuje
- Grafy a stromy: struktura, na které stojí hledání i neuronové sítě
- Lineární algebra pro strojové učení: vektory, matice a proč AI hlavně násobí
- Derivace, gradient a řetízkové pravidlo: jak model zjistí, kterým směrem se učit
- Gradientní sestup: jak se model učí
- Co je pravděpodobnost: od hodu kostkou ke Kolmogorovovým axiomům
- Podmíněná pravděpodobnost a Bayesova věta: jak změnit odhad, když se dozvíte něco nového
- Náhodná veličina a distribuční funkce: jedna funkce, která o rozdělení řekne všechno
- Funkce hustoty a pravděpodobnostní funkce: proč má spojitá veličina v bodě pravděpodobnost nula
- Střední hodnota, rozptyl a kovariance: kde rozdělení leží, jak je široké a co s čím souvisí
- Přehled pravděpodobnostních rozdělení: Bernoulli, binomické, Poisson, rovnoměrné, normální a exponenciální
- Zákon velkých čísel a centrální limitní věta: proč se průměry chovají tak předvídatelně
- Statistika a odhady parametrů: maximální věrohodnost, MAP a intervaly spolehlivosti
- Teorie informace: entropie, křížová entropie a KL divergence — odkud se berou ztrátové funkce
- Prohledávání stavového prostoru: BFS, DFS, UCS a A* s animacemi
- Hry a protivník: minimax, alfa-beta ořezávání a Monte Carlo tree search
- Splňování omezujících podmínek: backtracking, propagace omezení a AC-3 na sudoku a mapě krajů
- Logika a znalostní systémy: dopředné a zpětné řetězení, rezoluce a expertní systémy
- Plánování: STRIPS, svět kostek, heuristiky z relaxace a plánování v AI agentech
- Lokální hledání a simulované žíhání: obchodní cestující přes krajská města
- Genetické algoritmy: populace, křížení, mutace a výběr na batohu na výlet
- Evoluční strategie a genetické programování: od pravidla jedné pětiny po Keplerův zákon
- Optimalizace mravenčí kolonií: jak feromonová stopa najde krátkou cestu
- Optimalizace hejnem částic: setrvačnost, vlastní zkušenost a zkušenost hejna
- Neuroevoluce: evoluce vah i tvaru neuronových sítí a algoritmus NEAT
- Fuzzy množiny a funkce příslušnosti: jak zapsat „trochu teplo“
- Fuzzy logika a pravděpodobnost: proč „trochu teplo“ neznamená „pravděpodobně teplo“
- Fuzzy logika: t-normy, implikace a pravidla KDYŽ–PAK
- Fuzzy řízení: Mamdani a Sugeno od ventilátoru po kyvadlo na vozíku
- Fuzzy shlukování: algoritmus fuzzy c-means a body mezi shluky
- Neuro-fuzzy systémy (ANFIS): fuzzy pravidla, která se učí z dat
- Markovovy řetězce: přechodová matice, stacionární rozdělení a PageRank
- Skryté Markovovy modely: Viterbiho algoritmus a nepoctivé kasino
- Bayesovské sítě: proč je tráva mokrá a co z toho plyne pro postřikovač
- Kalmanův filtr: jak z nepřesných měření odhadnout, kde auto je a jak rychle jede
- Druhy strojového učení: s učitelem, bez učitele, s částečným učitelem a další
- Přeučení a regularizace: proč model, který zná data nazpaměť, selže
- Vyhodnocení modelu: křížová validace, F1 a křivka ROC
- Shlukování a snížení dimenze: k-means, PCA a t-SNE
- Klasifikace a regrese: dvě úlohy učení s učitelem
- Lineární regrese: nejmenší čtverce geometricky i maticově
- Polynomiální a nelineární regrese: jak přímku ohnout
- Logistická regrese: sigmoida, šance a křížová entropie
- Vícetřídní klasifikace a softmax: od dvou tříd k mnoha
- Naivní Bayesův klasifikátor: spamový filtr, který funguje lépe, než by měl
- Ztrátové funkce: co přesně model minimalizuje
- Rozhodovací stromy a k nejbližších sousedů: modely bez vzorců
- Ansámbly: náhodný les a gradient boosting
- SVM a jádrový trik: nejširší hranice a jak ji ohnout
- Signál a vzorkování: proč platí Nyquistův teorém
- Fourierova transformace: rozklad signálu na frekvence
- Filtry a konvoluce: vyhlazení, hrany a odstranění šumu
- Zvuk a řeč: spektrogram, melová škála a MFCC
- Obraz jako signál: pixely, barvy, konvoluce a hrany
- Perceptron a umělý neuron: nejjednodušší neuronová síť a co neumí
- Neuronová síť od nuly: zpětné šíření chyby krok za krokem
- Aktivace, inicializace a normalizace: drobnosti, na kterých hluboká síť stojí
- Konvoluční sítě: jak síť poznává obrázky
- Rekurentní sítě: paměť pro posloupnosti a mizející gradient
- LSTM a GRU: brány, které rozhodují, co si síť zapamatuje
- Autoenkodéry: síť, která se učí data stlačit a zase rozbalit
- Embeddingy a word2vec: jak se slovo stane vektorem
- Mechanismus pozornosti: jak se model naučí, kam se dívat
- Transformery a velké jazykové modely: architektura krok za krokem
- Tokenizace: jak se text rozseká na kousky pro model
- Předtrénování a škálování: proč větší model a víc dat funguje
- Doladění a RLHF: jak se z doplňovače textu stane asistent
- Prompty, kontext a RAG: jak modelu dát správné informace
- Variační autoenkodéry (VAE): nové obrázky ze spojitého latentního prostoru
- Generativní adversariální sítě (GAN): padělatel proti detektivovi
- Difúzní modely: jak se z čistého šumu stane obrázek
- Markovovy rozhodovací procesy: stavy, akce, odměny a Bellmanovy rovnice
- Q-learning a DQN: učení hodnoty akcí od tabulky po neuronovou síť
- Policy gradient a PPO: učení přímo strategie
- Jak funguje AI agent: jazykový model ve smyčce s nástroji
- Programování s AI agenty: zadání, testy a kontrola
- Vyhodnocení a bezpečnost AI systémů: jak měřit a jak hlídat
Celá osnova série 83 z 83 témat hotovo
- Jak síť počítá výstup vrstvu po vrstvě.
- Jak zpětné šíření spočte gradient každé váhy a proč je tak levné.
- Proč na startu a počtu neuronů záleží a co znamená, že si síť vytváří příznaky sama.
Co se hodí znát předem: Perceptron a umělý neuron: nejjednodušší neuronová síť a co neumí, Derivace, gradient a řetízkové pravidlo: jak model zjistí, kterým směrem se učit, Gradientní sestup: jak se model učí
Minulý díl skončil otázkou, na kterou dvacet let nikdo neznal uspokojivou odpověď: jak naučit váhy neuronů, které jsou schované uvnitř sítě a nikdo jim neřekne, jaký mají mít výstup? Odpověď se jmenuje zpětné šíření chyby (backpropagation) a je to jen pečlivě použité řetízkové pravidlo pro derivace. Dnes na něm stojí učení všech neuronových sítí, od rozpoznávání obrázků po jazykové modely. V tomhle dílu ho spočítáme ručně — s konkrétními čísly — na síti se třemi neurony, a pak ho pustíme na úlohy, které perceptron nezvládl.
Navazuje na díly Perceptron a umělý neuron, Derivace a gradient a Gradientní sestup.
1. Síť a dopředný průchod
Definice — vícevrstvá síť a dopředný průchod
Nechť n ∈ ℕ, n ≥ 1, je počet vrstev, d0, d1, …, dn ≥ 1 jsou šířky vrstev (d0 je počet vstupů, dn počet výstupů), x ∈ ℝd0 je vstup a pro ℓ = 1, …, n jsou W(ℓ) ∈ ℝdℓ×dℓ−1 váhy a b(ℓ) ∈ ℝdℓ prahy vrstvy ℓ. Nechť f : ℝ → ℝ je diferencovatelná aktivační funkce; na vektor ji používáme po složkách, f((z1, …, zk)) = (f(z1), …, f(zk)). (Každá vrstva smí mít vlastní aktivaci fℓ; pro stručnost píšeme f.) Vícevrstvá síť (vícevrstvý perceptron, MLP) s těmito parametry je funkce ℝd0 → ℝdn, x ↦ ŷ = a(n), kde a(0) = x a pro ℓ = 1, …, n
z(ℓ) = W(ℓ)a(ℓ−1) + b(ℓ) ∈ ℝdℓ, a(ℓ) = f(z(ℓ)) ∈ ℝdℓ,
po složkách zi(ℓ) = ∑j=1dℓ−1 Wij(ℓ)aj(ℓ−1) + bi(ℓ) pro i = 1, …, dℓ. Číslo Wij(ℓ) je tedy váha spojení z neuronu j vrstvy ℓ − 1 do neuronu i vrstvy ℓ; protože je matice W(ℓ) plná, je každý neuron spojený se všemi neurony předchozí vrstvy. Vrstvy 1, …, n − 1 jsou skryté, vrstva n výstupní. Výpočet a(1), a(2), …, a(n) v tomto pořadí (vrstvu po vrstvě od vstupu k výstupu) je dopředný průchod.
Každý neuron udělá to, co neuron z minulého dílu — vážený součet a aktivaci — jen místo skoku použije hladkou sigmoidu σ(z) = 1/1 + e−z. Výstupy jedné vrstvy jsou vstupy další. Celá síť je tak jedna velká složená funkce: násobení maticí, sigmoida, násobení maticí, sigmoida.
a(ℓ) = f( W(ℓ) a(ℓ−1) + b(ℓ) )
- a(ℓ)
- výstupy (aktivace) vrstvy ℓ — vektor s jedním číslem za každý neuron; v obrázku zeleně. Poslední vrstva dává odpověď sítě ŷ
- a(ℓ−1)
- vstup vrstvy — výstupy předchozí vrstvy, u první vrstvy přímo x. Díky tomu, že vrstva bere výstupy té předchozí, se vrstvy dají skládat za sebe
- W(ℓ)
- matice vah, řádek = jeden neuron, sloupec = jeden vstup. Násobení maticí spočte vážené součty všech neuronů vrstvy najednou — proto se sítě tak dobře počítají na grafických kartách
- b(ℓ)
- prahy, jeden na neuron — posouvají hranici každého neuronu mimo počátek, stejně jako u perceptronu
- f
- aktivace, po složkách — bez ní by dvě vrstvy byly jen součin dvou matic, tedy zase jedna lineární vrstva, a síť by neuměla nic víc než logistická regrese. Musí být hladká, aby existovaly derivace
Definice — sigmoida a kvadratická ztráta
Sigmoida (logistická funkce) je funkce σ : ℝ → (0, 1),
σ(z) = 1/1 + e−z.
Pro každé z ∈ ℝ platí 0 < σ(z) < 1, σ(0) = 1/2, σ(−z) = 1 − σ(z), limz→∞ σ(z) = 1 a limz→−∞ σ(z) = 0 — pro velká |z| se tedy blíží skoku z perceptronu. Její derivace je σ′(z) = σ(z)(1 − σ(z)) (odvození v dílu Derivace a gradient) a největší hodnotu 1/4 má v z = 0.
Nechť k ≥ 1, y ∈ ℝk je požadovaný výstup (cíl) a ŷ ∈ ℝk výstup sítě pro jeden příklad. Kvadratická ztráta tohoto příkladu je číslo
E = 1/2 ∑i=1k (ŷi − yi)2, pro k = 1 tedy E = 1/2(ŷ − y)2.
Polovina je tam jen kvůli pohodlí: derivace pak vyjde ∂E/∂ŷi = ŷi − yi bez dvojky.
Naše síť má dva vstupy, dva skryté neurony a jeden výstup — dohromady 9 parametrů (6 vah a 3 prahy). Váhy nastavíme ručně na „náhodná“ čísla a podíváme se, co síť udělá se vstupem x = (1, 0), u kterého chceme výstup y = 1:
Horní skrytý neuron: z = 0,5 · 1 + (−0,4) · 0 + 0,1 = 0,6 a a = σ(0,6) = 0,646. Dolní: z = 0,3 + (−0,2) = 0,1 a a = 0,525. Výstup: z = 0,7 · 0,646 − 0,6 · 0,525 + 0,05 = 0,187 a ŷ = σ(0,187) = 0,547. Síť je nerozhodná, chtěli jsme 1. Chybu měříme kvadratickou ztrátou E = 1/2(ŷ − y)2 = 0,103.
Příklad — týž dopředný průchod maticově
Barvy podle vzorce a(ℓ) = f(W(ℓ)a(ℓ−1) + b(ℓ)) výše, s f = σ; ve druhé vrstvě jsou vstupem a(ℓ−1) výstupy první vrstvy.
z(1) = W(1)x + b(1) = (0,5 · 1 + (−0,4) · 0 + 0,1; 0,3 · 1 + 0,8 · 0 + (−0,2)) = (0,6; 0,1)
a(1) = σ(z(1)) = (1/1 + e−0,6; 1/1 + e−0,1) = (0,6457; 0,5250)
z(2) = 0,7 · 0,6457 + (−0,6) · 0,5250 + 0,05 = 0,1870
ŷ = σ(0,1870) = 0,5466, E = 1/2 · (0,5466 − 1)2 = 0,1028
Druhý sloupec W(1) (váhy ze vstupu x2) se násobí nulou — na výstup teď nemá vliv, a uvidíme, že se proto ani nebude učit.
Příklad — kolik parametrů má síť
Vrstva ℓ s dℓ neurony nad vrstvou s dℓ−1 výstupy má dℓ · dℓ−1 vah (prvků matice W(ℓ)) a dℓ prahů (složek b(ℓ)), celkem dℓ(dℓ−1 + 1). Síť s n vrstvami má ∑ℓ=1n dℓ(dℓ−1 + 1) parametrů; síť „d0-d1-d2“ tedy:
2-2-1: 2 · (2 + 1) + 1 · (2 + 1) = 9
2-8-1 (dva měsíce níže): 8 · (2 + 1) + 1 · (8 + 1) = 33
Počet roste se součinem šířek sousedních vrstev: dvě vrstvy po tisíci neuronech spojí milion vah.
2. Řetízkové pravidlo
Abychom mohli váhy zlepšit gradientním sestupem, potřebujeme pro každou z devíti vah vědět, jak by se změnila chyba, kdybychom ji o kousek posunuli — derivaci ∂E/∂w.
Věta — řetízkové pravidlo
Nechť z, g, E : ℝ → ℝ jsou funkce a w0 ∈ ℝ; nechť z je diferencovatelná v bodě w0, g v bodě z(w0) a E v bodě g(z(w0)). Píšeme ŷ = g(z) a chybu chápeme jako funkci váhy, w ↦ E(g(z(w))). Pak je tato složená funkce diferencovatelná v w0 a
∂E/∂w = ∂E/∂ŷ · ∂ŷ/∂z · ∂z/∂w,
kde každá derivace je vzata v odpovídajícím bodě (E′ v ŷ = g(z(w0)), g′ v z(w0), z′ v w0). Derivace řetězce funkcí je tedy součin derivací jednotlivých článků. Závisí-li veličina na w po několika cestách, příspěvky všech cest se sečtou (vícerozměrné řetízkové pravidlo, viz díl Gradientní sestup); v síti níže ostatní parametry vždy považujeme za pevné, proto píšeme parciální derivace ∂. Pro sigmoidu platí σ′(z) = σ(z)(1 − σ(z)).
Když převod na kole zvětší otáčky dvakrát a přehazovačka třikrát, pedál točí kolem šestkrát rychleji. Citlivosti se v řetězu násobí. Váha ve skryté vrstvě ovlivní chybu přes několik článků — skrytý neuron, výstupní neuron, ztrátu — a její vliv je součin citlivostí všech článků.
Rozepišme celý řetěz pro váhu W11(1), která vede ze vstupu x1 do horního skrytého neuronu. Do chyby se dostane přes čtyři články: svůj vážený součet z1(1), aktivaci a1(1), vážený součet výstupního neuronu z(2) a výstup ŷ:
∂E/∂W11(1) = (∂E/∂ŷ · ∂ŷ/∂z(2)) · ∂z(2)/∂a1(1) · ∂a1(1)/∂z1(1) · ∂z1(1)/∂W11(1)
- ∂E/∂W11(1)
- gradient — o kolik vzroste chyba na jednotku změny váhy; v obrázku zpětného průchodu červeně u šipek. Tohle chceme
- (ŷ − y) · ŷ(1 − ŷ)
- citlivost chyby na vážený součet výstupního neuronu: jak moc se výstup mýlí krát jak citlivě na změnu reaguje jeho sigmoida; (0,547 − 1) · 0,248 = −0,1124. Je společná všem vahám v síti — proto se počítá jen jednou
- W11(2) = 0,7
- váha z horního skrytého neuronu do výstupu — jak silně se změna skrytého neuronu na výstup přenese. Tudy chyba „teče zpátky“: kdyby byla 0, skrytý neuron by se o chybě nedozvěděl
- a1(1 − a1) = 0,229
- sklon sigmoidy skrytého neuronu — když je neuron nasycený (aktivace u 0 nebo 1), je skoro nula a dál k jeho vahám chyba nedojde
- x1 = 1
- vstup, který váha násobí — čím větší vstup, tím víc váha ovlivní součet; pro nulový vstup by byl celý gradient nula
3. Zpětné šíření chyby
Definice — zpětné šíření
Nechť je dána vícevrstvá síť z definice výše s n vrstvami, šířkami d0, …, dn, parametry W(ℓ), b(ℓ) (ℓ = 1, …, n) a sigmoidou σ jako aktivací ve všech vrstvách, dále příklad (x, y) se vstupem x ∈ ℝd0 a cílem y ∈ ℝdn a kvadratická ztráta E = 1/2 ∑k=1dn (ak(n) − yk)2. Chybový signál neuronu i ve vrstvě ℓ je
δi(ℓ) = ∂E/∂zi(ℓ), ℓ = 1, …, n, i = 1, …, dℓ.
Zpětné šíření je algoritmus:
- vstup: parametry sítě W(ℓ), b(ℓ) a příklad (x, y);
- výstup: ztráta E a všechny parciální derivace ∂E/∂Wkj(ℓ) a ∂E/∂bk(ℓ).
- Dopředný průchod: spočti a ulož a(0) = x, a(1), …, a(n) a ztrátu E.
- Výstupní vrstva: pro k = 1, …, dn polož δk(n) = (ak(n) − yk) · ak(n)(1 − ak(n)).
- Pro ℓ = n, n − 1, …, 1 (odzadu): pro všechna k = 1, …, dℓ a j = 1, …, dℓ−1 polož ∂E/∂Wkj(ℓ) = δk(ℓ) · aj(ℓ−1), ∂E/∂bk(ℓ) = δk(ℓ), a je-li ℓ ≥ 2, spočti chybové signály o vrstvu níž: pro j = 1, …, dℓ−1 δj(ℓ−1) = (∑k=1dℓ Wkj(ℓ) δk(ℓ)) · aj(ℓ−1)(1 − aj(ℓ−1)).
- Vrať E a spočtené derivace.
Vzorce v krocích 2 a 3 plynou z řetízkového pravidla (∂E/∂ak(n) = ak(n) − yk, σ′ = σ(1 − σ) a zk(ℓ) závisí na Wkj(ℓ) a aj(ℓ−1) lineárně); obecné odvození je v dílu Gradientní sestup (odkaz níže). Algoritmus tedy počítá chybové signály od výstupu ke vstupu a každý gradient váhy dostane jako součin chybového signálu cílového neuronu a aktivace zdrojového neuronu. V rozboru níže píšeme zkráceně wkj = Wkj(ℓ), δk = δk(ℓ), δj = δj(ℓ−1) a aj = aj(ℓ−1).
Chyba se počítá na výstupu a pak se po stejných spojích pošle zpátky: každý skrytý neuron dostane díl výstupní chyby úměrný váze, kterou na výstup působí. Tím se vyřeší, co Rosenblatt neuměl — skrytý neuron sice nezná správnou odpověď, ale dozví se, jak moc přispěl k chybě. Všechno se spočte jedním průchodem odzadu, zhruba stejně drahým jako průchod dopředu.
Výstup: δ = (0,547 − 1) · 0,547 · 0,453 = −0,1124. Gradient váhy z horního skrytého neuronu je −0,1124 · 0,646 = −0,0725, z dolního −0,0590. Do skryté vrstvy se chyba pošle přes výstupní váhy: horní neuron dostane 0,7 · (−0,1124), vynásobené jeho sklonem sigmoidy 0,229, tedy δ = −0,0180; dolní −0,6 · (−0,1124) · 0,249 = 0,0168 (barvy podle vzorce níže). Váhy ze vstupu x2 = 0 mají gradient nulový — ten vstup k chybě nepřispěl, a tak se jeho váhy nemění.
δj = ( ∑k wkj δk ) · aj(1 − aj), ∂E/∂wkj = δk · aj
- δj
- chybový signál skrytého neuronu j — jak by se změnila chyba, kdyby se pohnul jeho vážený součet. Tohle skrytý neuron potřebuje místo „správné odpovědi“, kterou nemá
- δk
- chybové signály neuronů o vrstvu výš, už spočtené — proto se jde odzadu: každá vrstva potřebuje hotová δ té následující
- wkj
- váha z neuronu j do neuronu k — tytéž váhy jako při dopředném průchodu, jen se jimi chyba posílá opačným směrem. Neuron s velkou vahou dostane velký díl viny
- aj(1 − aj)
- sklon sigmoidy neuronu j — převádí „chybu na výstupu neuronu“ na „chybu na jeho váženém součtu“
- ∂E/∂wkj
- gradient váhy — to, co nakonec potřebuje gradientní sestup
- aj
- aktivace neuronu, ze kterého váha vede (u první vrstvy vstup xj) — váha z neaktivního neuronu výsledek neovlivnila, a tak se neučí
Pro tuhle síť se sigmoidami a kvadratickou ztrátou to stačí. Obecnou verzi pro libovolně hlubokou síť — včetně odvození, proč se chyba vrací přes transponovanou matici vah, a příkladu se softmaxem v každé vrstvě — najdete v dílu Gradientní sestup, oddíl o zpětném šíření sítí se softmaxem; tady ji nebudeme opakovat. Celý postup jako algoritmus:
def zpetne_sireni(W, b, x, y):
# dopředný průchod — aktivace všech vrstev si zapamatujeme
a = [x]
for l in range(L):
a.append(sigmoida(W[l] @ a[l] + b[l]))
E = 0.5 * sum((a[L] - y) ** 2)
# zpětný průchod — od poslední vrstvy k první
delta = (a[L] - y) * a[L] * (1 - a[L]) # výstupní vrstva
for l in reversed(range(L)):
dW[l] = outer(delta, a[l]) # δ cíle × aktivace zdroje
db[l] = delta
if l > 0:
delta = (W[l].T @ delta) * a[l] * (1 - a[l]) # chyba o vrstvu níž
return E, dW, db
Záporný gradient znamená „zvětši váhu, chyba klesne“. Krok gradientního sestupu s rychlostí učení 1 posune každou váhu o minus svůj gradient — a chyba na tomtéž příkladu klesne z 0,103 na 0,082.
Příklad — krok sestupu na všech devíti parametrech
Krok θ ← θ − η · ∂E/∂θ s η = 1:
výstup: W11(2): 0,7 − (−0,0725) = 0,7725, W12(2): −0,6 − (−0,0590) = −0,5410, b(2): 0,05 − (−0,1124) = 0,1624
horní skrytý: W11(1): 0,5 − (−0,0180) = 0,5180, b1(1): 0,1 − (−0,0180) = 0,1180
dolní skrytý: W21(1): 0,3 − 0,0168 = 0,2832, b2(1): −0,2 − 0,0168 = −0,2168
váhy ze vstupu x2 = 0 (W12(1), W22(1)): gradient 0, beze změny
nový průchod: ŷ = 0,5958, E = 1/2 · (0,5958 − 1)2 = 0,0817 (předtím 0,1028)
Nejvíc se pohnul práh výstupu, protože jeho „vstup“ je vždy 1. Dolní skrytý neuron má kladné δ: přes zápornou váhu −0,6 výstup tlumí, a tak se jeho práh sníží, aby tlumil méně.
4. Kontrola: numerická derivace
Definice — numerická kontrola gradientu
Nechť θ ∈ ℝp je vektor všech p parametrů sítě, E : ℝp → ℝ ztráta jako funkce parametrů, i ∈ {1, …, p}, ei ∈ ℝp i-tý jednotkový vektor (1 na místě i, jinde 0) a h > 0. Centrální diference ztráty podle parametru θi je číslo
Di,h(θ) = E(θ + hei) − E(θ − hei)/2h,
tedy změna ztráty, když jedním parametrem pohneme o h nahoru a dolů a ostatní necháme pevné. Je-li E diferencovatelná, pak Di,h(θ) → ∂E/∂θi(θ) pro h → 0. Numerická kontrola gradientu spočte Di,h(θ) pro malé h a všechna i = 1, …, p a porovná je s derivacemi ∂E/∂θi(θ) ze zpětného šíření; implementaci považujeme za správnou, jsou-li rozdíly řádově na úrovni zaokrouhlovací chyby. Je to standardní test, ne důkaz — ověřuje gradient jen v testovaném bodě θ.
Pootočíme jednou vahou o setinu tisíciny tam a zpátky a podíváme se, jak se změní chyba. Je to pomalé — pro každou váhu dva dopředné průchody — ale nedá se v tom splést. Pro všech 9 parametrů naší sítě se gradient ze zpětného šíření od numerického liší nejvýš o 2 · 10−12, tedy jen zaokrouhlovací chybou počítače.
Věta — proč centrální, a ne dopředná diference
Nechť E : ℝ → ℝ je na okolí bodu w ∈ ℝ třikrát spojitě diferencovatelná (ztráta jako funkce jedné váhy, ostatní parametry pevné) a h > 0. Dopředná diference je E(w + h) − E(w)/h, centrální diference E(w + h) − E(w − h)/2h. Pak pro h → 0 platí
dopředná: E(w + h) − E(w)/h = E′(w) + h/2 E″(w) + O(h2) — chyba úměrná h
centrální: E(w + h) − E(w − h)/2h = E′(w) + h2/6 E‴(w) + o(h2) — chyba úměrná h2
Důkaz. Taylorův rozvoj dává E(w ± h) = E(w) ± hE′(w) + h2/2 E″(w) ± h3/6 E‴(w) + o(h3). Dosazením „+“ do dopředné diference vyjde první řádek; odečtením obou rozvojů se členy se sudou mocninou h zruší, zůstane 2hE′(w) + h3/3 E‴(w) + o(h3), a po vydělení 2h druhý řádek. ∎
V centrální diferenci se tedy členy se sudou mocninou h odečtou. Ověření na váze W11(2) naší sítě (odchylka od gradientu ze zpětného šíření, −0,0725):
| h | chyba dopředné | chyba centrální |
|---|---|---|
| 0,1 | 1,5 · 10−3 | 1,7 · 10−5 |
| 0,01 | 1,5 · 10−4 | 1,7 · 10−7 |
| 0,001 | 1,5 · 10−5 | 1,7 · 10−9 |
Desetkrát menší h zmenší chybu dopředné diference desetkrát, centrální stokrát. Příliš malé h ale také nepomůže: rozdíl dvou skoro stejných čísel ztratí platné číslice a zaokrouhlovací chyba roste jako 1/h. Proto se bere něco kolem 10−5.
Proč tedy nepočítat gradient vždycky takhle? Síť s miliardou vah by potřebovala dvě miliardy dopředných průchodů na jediný krok učení. Zpětné šíření spočte všechny gradienty najednou za cenu zhruba dvou průchodů — to je celý jeho význam.
5. Síť se naučí XOR
Teď to pustíme naostro: síť 2-2-1 se sigmoidami, váhy náhodné, učení gradientním sestupem na čtyřech příkladech XOR s křížovou entropií (3 000 epoch). A protože výsledek závisí na náhodném startu, zkusíme sto různých startů.
Definice — křížová entropie a dávkový gradientní sestup
Nechť y ∈ {0, 1} je cíl a ŷ ∈ (0, 1) výstup sítě (odhad pravděpodobnosti třídy 1). (Binární) křížová entropie je číslo
L(ŷ, y) = −[y ln ŷ + (1 − y) ln(1 − ŷ)] ≥ 0,
měřené v natech (ln je přirozený logaritmus). Pro y = 1 je tedy L = −ln ŷ, pro y = 0 je L = −ln(1 − ŷ).
Nechť N ≥ 1 a (xi, yi), i = 1, …, N, jsou trénovací příklady, θ ∈ ℝp vektor všech parametrů sítě a Li(θ) ztráta sítě s parametry θ na příkladu i. Celková ztráta je průměr
J(θ) = 1/N ∑i=1N Li(θ).
Dávkový gradientní sestup je gradientní sestup (viz díl Gradientní sestup) použitý na J:
- vstup: počáteční parametry θ0 ∈ ℝp, rychlost učení η > 0 a počet epoch T ∈ ℕ;
- výstup: parametry θT ∈ ℝp.
- Pro t = 0, 1, …, T − 1 (jedna epocha): spočti zpětným šířením ∇Li(θt) pro každý příklad i = 1, …, N a polož θt+1 = θt − η ∇J(θt), kde ∇J(θt) = 1/N ∑i=1N ∇Li(θt).
- Po T epochách zastav a vrať θT.
Na rozdíl od učení po jednom příkladu tedy udělá za epochu jediný krok, s gradientem zprůměrovaným přes všechna data. Tady N = 4, η = 1 a T = 3 000.
L = −[ y ln ŷ + (1 − y) ln(1 − ŷ) ]
- L
- ztráta jednoho příkladu — nula, když síť odpoví s jistotou správně, a neomezeně roste, když s jistotou odpoví špatně
- y
- vypínač: pro y = 1 nechá platit jen první člen, pro y = 0 ho vynuluje
- ln ŷ
- trest za to, že síť dala správné třídě 1 malou pravděpodobnost; logaritmus z jistoty „0,99“ udělá skoro nulu a z omylu „0,01“ velké číslo (ln 0,01 ≈ −4,6) — proto minus před závorkou
- (1 − y)
- opačný vypínač: platí jen pro příklady s cílem 0
- ln(1 − ŷ)
- totéž pro třídu 0, jejíž pravděpodobnost je 1 − ŷ
Síť se naučila XOR v 66 ze 100 startů. Ve zbylých uvízla: ztráta klesne na 0,349 a dál se nehne — síť dva body ze čtyř zařazuje správně jen napůl a gradient je tam skoro nulový. S pouhými dvěma skrytými neurony má úloha lokální minima a sedla. Se čtyřmi skrytými neurony se XOR naučila ve všech 100 startech. Víc neuronů, než je nezbytně nutné, dělá krajinu ztráty přívětivější — jedno z vysvětlení, proč se dnes používají obří sítě.
Příklad — odkud se bere 0,349
První uvízlá síť z obrázku dává pro vstupy (0, 0), (0, 1), (1, 0), (1, 1) výstupy 0,002; 0,499; 0,997; 0,501. Dva body zařazuje skoro jistě správně, u dvou říká „nevím“ (≈ 0,5). Ztráta „nevím“ je pro libovolný cíl −ln 0,5 = ln 2, takže průměr přes čtyři body je
J ≈ 0 + 0 + ln 2 + ln 2/4 = 1/2 ln 2 = 0,347
skutečně: J = 0,349 (zbytek dávají dva „jisté“ body, které nejsou jisté úplně)
Hodnotu 1/2 ln 2 si tedy můžete pamatovat jako podpis tohohle uvíznutí: síť se vzdala dvou bodů ze čtyř.
6. Hranice, kterou si síť ohne sama
Dva zaklesnuté měsíce, 200 bodů. Síť bez skryté vrstvy je logistická regrese a umí jen přímku. Síť s osmi skrytými neurony (aktivace tanh, 33 parametrů):
Definice — hyperbolický tangens a přesnost
Hyperbolický tangens je funkce tanh : ℝ → (−1, 1),
tanh z = ez − e−z/ez + e−z = 2σ(2z) − 1.
Je to sigmoida roztažená na interval (−1, 1) a vycentrovaná na nulu (tanh 0 = 0); derivace je tanh′ z = 1 − tanh2 z, v nule 1 (u sigmoidy jen 1/4). Ve zpětném šíření se pak u neuronu s aktivací a = tanh z místo a(1 − a) násobí 1 − a2. Výstupní neuron má dál sigmoidu, protože jeho výstup čteme jako pravděpodobnost.
Nechť M ≥ 1 a (xi, yi), i = 1, …, M, jsou testovací body s třídami yi ∈ {0, 1}, na kterých se síť neučila (nové body ze stejného rozdělení), a ŷi ∈ (0, 1) výstup sítě pro xi. Bod zařadíme do třídy ci = 1, je-li ŷi > 0,5, jinak do ci = 0. Přesnost je podíl správně zařazených bodů,
přesnost = |{i ∈ {1, …, M} : ci = yi}|/M ∈ [0, 1].
Bez skryté vrstvy má síť na 2 000 nových bodech přesnost 87,1 %, s osmi skrytými neurony 98,3 %. V dílu o logistické regresi jsme hranici ohýbali ručně přidanými příznaky jako x12. Tady jsme nic takového nepřidali: skryté neurony si vhodné příznaky vytvořily samy. Každý z nich kreslí jednu měkkou přímku a výstupní neuron je skládá do zakřivené hranice. Právě tohle — učení příznaků — odlišuje neuronové sítě od modelů z předchozích dílů.
7. Trocha historie a dnešek
- Objev. Obecnou metodu zpětného výpočtu derivací (dnes „automatická derivace ve zpětném režimu“) popsal Seppo Linnainmaa v roce 1970, na neuronové sítě ji navrhl Paul Werbos v disertaci z roku 1974 (podrobně rozpracoval v roce 1982). Proslavil ji až článek Davida Rumelharta, Geoffreyho Hintona a Ronalda Williamse v Nature z roku 1986.
- Automatická derivace. Dnes zpětné šíření nikdo nepíše ručně. Knihovny jako PyTorch si při dopředném průchodu zapamatují výpočetní graf a gradienty spočtou samy, pro libovolnou síť.
- Co zůstalo stejné. Dopředný průchod, ztráta, zpětný průchod, krok gradientního sestupu. Jazykový model se učí přesně tímhle cyklem, jen s miliardami vah a biliony slov.
8. Shrnutí
- Vícevrstvá síť střídá násobení maticí a aktivaci; naše síť 2-2-1 má 9 parametrů a pro vstup (1, 0) dala 0,547 místo 1 (chyba 0,103).
- Zpětné šíření spočte chybový signál δ na výstupu a pošle ho po vahách zpět; gradient váhy je δ cíle krát aktivace zdroje.
- Gradienty ze zpětného šíření se od numerické derivace lišily nejvýš o 2 · 10⁻¹²; jeden krok snížil chybu na 0,082.
- XOR se síť 2-2-1 naučila v 66 ze 100 startů, se čtyřmi skrytými neurony ve všech.
- Skryté neurony si vytvoří příznaky samy: na dvou měsících 98,3 % proti 87,1 % bez skryté vrstvy.
Chcete si to osahat? Nechte AI agenta napsat tuhle síť v čistém Pythonu bez knihoven — a pak tutéž v PyTorchi se zapnutou automatickou derivací. Vyjdou stejné gradienty?
Máte na to jiný názor? Napište na support@coden-app.com.