Preskočiť na obsah
coden

Neuroevolúcia: evolúcia váh aj tvaru neurónových sietí a algoritmus NEAT

Neurón a sieť v kocke, evolúcia regulátora pre kyvadlo na vozíku, prečo evolúcia namiesto gradientu, XOR a skryté neuróny, NEAT s historickými značkami a speciáciou, čo sa stane bez speciácie a nasledovníci od HyperNEAT po AmoebaNet.

15 minút Matěj Žalmánek 2026-10-15

Séria Základy AI Diel 31 z 52
  1. Mapa umelej inteligencie: čo je čo a ako to do seba zapadá
  2. Stručná história umelej inteligencie: od Turinga po jazykové modely
  3. Dáta, model, tréning, inferencia: základné pojmy na jednom príklade
  4. Ako čítať matematický zápis: symboly, indexy, sumy a kvantifikátory
  5. Množiny a relácie: stavebnica, z ktorej sa skladajú definície v AI
  6. Funkcie a zobrazenia: prečo je každý model v AI funkcia
  7. Logika a dôkazy: pravidlá, podľa ktorých sa v AI uvažuje
  8. Grafy a stromy: štruktúra, na ktorej stojí hľadanie aj neurónové siete
  9. Lineárna algebra pre strojové učenie: vektory, matice a prečo AI hlavne násobí
  10. Derivácie, gradient a reťazové pravidlo: ako model zistí, ktorým smerom sa učiť
  11. Gradientný zostup: ako sa model učí
  12. Čo je pravdepodobnosť: od hodu kockou ku Kolmogorovovým axiómam
  13. Podmienená pravdepodobnosť a Bayesova veta: ako zmeniť odhad, keď sa dozviete niečo nové
  14. Náhodná premenná a distribučná funkcia: jedna funkcia, ktorá o rozdelení povie všetko
  15. Funkcia hustoty a pravdepodobnostná funkcia: prečo má spojitá premenná v bode pravdepodobnosť nula
  16. Stredná hodnota, rozptyl a kovariancia: kde rozdelenie leží, aké je široké a čo s čím súvisí
  17. Prehľad pravdepodobnostných rozdelení: Bernoulliho, binomické, Poissonovo, rovnomerné, normálne a exponenciálne
  18. Zákon veľkých čísel a centrálna limitná veta: prečo sa priemery správajú tak predvídateľne
  19. Štatistika a odhady parametrov: maximálna vierohodnosť, MAP a intervaly spoľahlivosti
  20. Teória informácie: entropia, krížová entropia a KL divergencia — odkiaľ sa berú stratové funkcie
  21. Prehľadávanie stavového priestoru: BFS, DFS, UCS a A* s animáciami
  22. Hry a protivník: minimax, alfa-beta orezávanie a Monte Carlo tree search
  23. Splňovanie obmedzujúcich podmienok: backtracking, propagácia obmedzení a AC-3 na sudoku a mape krajov
  24. Logika a znalostné systémy: dopredné a spätné reťazenie, rezolúcia a expertné systémy
  25. Plánovanie: STRIPS, svet kociek, heuristiky z relaxácie a plánovanie v AI agentoch
  26. Lokálne hľadanie a simulované žíhanie: obchodný cestujúci cez krajské mestá
  27. Genetické algoritmy: populácia, kríženie, mutácia a výber na batohu na výlet
  28. Evolučné stratégie a genetické programovanie: od pravidla jednej pätiny po Keplerov zákon
  29. Optimalizácia mravčou kolóniou: ako feromónová stopa nájde krátku cestu
  30. Optimalizácia rojom častíc: zotrvačnosť, vlastná skúsenosť a skúsenosť roja
  31. Neuroevolúcia: evolúcia váh aj tvaru neurónových sietí a algoritmus NEAT
  32. Fuzzy množiny a funkcie príslušnosti: ako zapísať „trochu teplo“
  33. Fuzzy logika a pravdepodobnosť: prečo „trochu teplo“ neznamená „pravdepodobne teplo“
  34. Fuzzy logika: t-normy, implikácie a pravidlá AK–TAK
  35. Fuzzy riadenie: Mamdani a Sugeno od ventilátora po kyvadlo na vozíku
  36. Fuzzy zhlukovanie: algoritmus fuzzy c-means a body medzi zhlukmi
  37. Neuro-fuzzy systémy (ANFIS): fuzzy pravidlá, ktoré sa učia z dát
  38. Markovove reťazce: prechodová matica, stacionárne rozdelenie a PageRank
  39. Skryté Markovove modely: Viterbiho algoritmus a nepoctivé kasíno
  40. Bayesovské siete: prečo je tráva mokrá a čo z toho vyplýva pre postrekovač
  41. Kalmanov filter: ako z nepresných meraní odhadnúť, kde auto je a ako rýchlo ide
  42. Druhy strojového učenia: s učiteľom, bez učiteľa, s čiastočným učiteľom a ďalšie
  43. Prompty, kontext a RAG: ako modelu dať správne informácie
  44. Variačné autoenkodéry (VAE): nové obrázky zo spojitého latentného priestoru
  45. Generatívne adversariálne siete (GAN): falšovateľ proti detektívovi
  46. Difúzne modely: ako sa z čistého šumu stane obrázok
  47. Markovove rozhodovacie procesy: stavy, akcie, odmeny a Bellmanove rovnice
  48. Q-learning a DQN: učenie hodnoty akcií od tabuľky po neurónovú sieť
  49. Policy gradient a PPO: učenie priamo stratégie
  50. Ako funguje AI agent: jazykový model v slučke s nástrojmi
  51. Programovanie s AI agentmi: zadanie, testy a kontrola
  52. Vyhodnocovanie a bezpečnosť AI systémov: ako merať a ako strážiť

Celá osnova série Hotovo: 52 z 83 tém

Čo si odnesiete
  • Ako evolúcia nájde váhy siete, keď sa o úspechu dozvieme až na konci.
  • Prečo na XOR nestačí ladiť váhy a ako NEAT necháva sieť rásť od minima.
  • Prečo NEAT bez speciácie takmer nefunguje a kam neuroevolúcia vedie dnes.

Čo sa hodí vedieť vopred: Genetické algoritmy: populácia, kríženie, mutácia a výber na batohu na výlet, Evolučné stratégie a genetické programovanie: od pravidla jednej pätiny po Keplerov zákon

Neurónové siete sa dnes učia takmer výlučne gradientovým zostupom: sieť urobí chybu, vypočíta sa, ktorým smerom pootočiť každú váhu, a pootočí sa. Čo ak sa však chyba derivovať nedá — keď sa o úspechu dozvieme až na konci hry, alebo keď nevieme ani to, ako má sieť vyzerať? Vtedy prichádza na rad evolúcia. Neuroevolúcia necháva evolučné algoritmy pestovať váhy sietí a v najzaujímavejšej podobe aj ich tvar. Týmto dielom sa končí modul o algoritmoch inšpirovaných prírodou a zároveň sa otvárajú dvere k neurónovým sieťam.

Nadväzuje na diely Genetické algoritmy a Evolučné stratégie a genetické programovanie.

1. Neurónová sieť v kocke

Definícia — umelý neurón a sieť

Nech n ∈ ℕ, n ≥ 1, w = (w1, …, wn) ∈ ℝn sú váhy, b ∈ ℝ je prah a σ : ℝ → ℝ je funkcia, ktorú nazývame aktivačná funkcia. Neurón s týmito parametrami je funkcia y : ℝn → ℝ, ktorá vstupom x = (x1, …, xn) priradí

y(x) = σ(w1x1 + … + wnxn + b) = σ(∑i=1n wixi + b).

Bežné aktivačné funkcie sú sigmoida σ(z) = 1/1 + e−z a skok σ(z) = 1 pre z > 0, σ(z) = 0 pre z ≤ 0.

Neurónová sieť je orientovaný graf G = (V, E), kde

  1. množina uzlov V = Vin ∪ VN je disjunktné zjednotenie vstupov siete Vin a neurónov VN, pričom do vstupov nevedie žiadna hrana;
  2. každá hrana (u, v) ∈ E vedie do neurónu v ∈ VN a má váhu wuv ∈ ℝ;
  3. každý neurón v ∈ VN má prah bv ∈ ℝ a aktivačnú funkciu σv a jeho hodnota je yv = σv(∑u : (u, v) ∈ E wuv yu + bv), kde yu je pre vstup u ∈ Vin zadaná vstupná hodnota;
  4. neprázdna množina Vout ⊆ VN sú výstupné neuróny; ich hodnoty sú výstupom siete.

Sieť je dopredná práve vtedy, keď graf G nemá orientovaný cyklus — potom možno hodnoty neurónov vypočítať jednu po druhej v topologickom poradí. Neuróny z VN ∖ Vout (nie sú vstupom ani výstupom) sú skryté.

Laicky povedané

Neurón sčíta vstupy, každý vynásobený svojou váhou, a podľa súčtu sa „rozsvieti“, alebo nie. Váhy určujú, na čom mu záleží. Sieť je veľa neurónov zapojených za sebou. Celé správanie siete je v číslach váh a v tom, kto je s kým spojený — a oboje sa dá pestovať evolúciou. Neurónovým sieťam a ich učeniu gradientom sa v osnove venuje celý samostatný modul.

y = σ( ∑i=1n wi xi + b )

xi
vstupy — to, čo neurón „vidí“ (pri kyvadle poloha, rýchlosť, uhol); neurón ich nemení, len s nimi počíta
wi
váhy — jediné, čo sa učí alebo vyvíja evolúciou; znamienko hovorí, či neurón vstup podporuje, alebo tlmí, veľkosť, ako veľmi na ňom záleží
b
prah — posunie rozhodovaciu hranicu; bez neho by nulové vstupy dali vždy to isté σ(0) a hranica by musela prechádzať začiatkom
σ
aktivačná funkcia — nelinearita; bez nej by aj sieť s mnohými vrstvami počítala len lineárnu funkciu, pretože zloženie lineárnych funkcií je opäť lineárne
Súčet ∑ wixi + b je vážené hlasovanie vstupov; σ z neho urobí výstup. Hranica medzi „rozsvieti sa“ a „nerozsvieti sa“ je množina, kde je súčet nula — priamka (v rovine), všeobecne nadrovina.

2. Evolúcia váh: kyvadlo na vozíku

Klasická úloha riadenia: na vozíku stojí tyč na kĺbe a vozík ju musí udržať vo zvislej polohe tým, že popojíždza doľava a doprava — ako keď balansujete metlu na dlani.

Definícia — úloha kyvadla na vozíku
  1. Stav je štvorica s = (x, v, θ, ω) ∈ ℝ4: poloha x (m) a rýchlosť v (m/s) vozíka, uhol θ (rad) tyče od zvislice a jej uhlová rýchlosť ω (rad/s). Vozík má hmotnosť 1 kg, tyč 0,1 kg a dĺžku 1 m.
  2. Akcia: v každom kroku t = 0, 1, 2, … (krok trvá 0,02 s) zvolí regulátor silu Ft ∈ {−10 N, +10 N}.
  3. Prechod: st+1 sa vypočíta z st a Ft podľa pohybových rovníc nižšie.
  4. Koniec pokusu: pokus skončí po kroku t práve vtedy, keď |θt+1| > 12° ∨ |xt+1| > 2,4 m (tyč spadla alebo vozík vyšiel z koľajnice), alebo keď prebehlo 1 000 krokov (20 s). Cieľom je vydržať 1 000 krokov.

Regulátorom bude jediný neurón so skokovou aktiváciou: pre váhy (w1, w2, w3, w4, b) ∈ ℝ5 je

u(s) = w1x + w2v + w3θ + w4ω + b,   F(s) = +10 N pre u(s) > 0,   F(s) = −10 N pre u(s) ≤ 0.

Regulátor teda tlačí vozík v smere kladného x práve vtedy, keď je vážený súčet stavu kladný. Zdatnosť regulátora (priemerný počet krokov z troch rôznych štartov) definujeme nižšie.

Laicky povedané

Päť čísel rozhoduje, kedy vozíkom trhnúť doľava a kedy doprava. Žiadny učiteľ nepovie, aká sila bola v ktorej chvíli správna — dozvieme sa len, ako dlho tyč vydržala. Presne takáto situácia sa gradientom rieši ťažko a evolúciou ľahko.

Definícia — pohybové rovnice kyvadla na vozíku

Nech s = (x, v, θ, ω) je stav (uhol θ meriame od zvislice) a F ∈ {−10, +10} N sila regulátora; kladná sila tlačí vozík v smere kladného x. Konštanty: hmotnosť vozíka mv = 1 kg, hmotnosť tyče mt = 0,1 kg, ich súčet M = mv + mt = 1,1 kg, l = 0,5 m polovica dĺžky tyče (vzdialenosť ťažiska od kĺbu) a tiažové zrýchlenie g = 9,8 m/s². Bez trenia (rovnice v tvare, ako ich uvádzajú Barto, Sutton a Anderson, 1983, a ako ich dodnes používa väčšina implementácií) sú pomocné zrýchlenie aF, uhlové zrýchlenie tyče ε a zrýchlenie vozíka a dané predpismi

aF = F + mt l ω² sin θ/M

ε = g sin θ − cos θ · aF/l (4/3 − mt cos² θ/M)

a = aF − mt l ε cos θ/M

Simulácia postupuje Eulerovou metódou s krokom Δt = 0,02 s: zo stavu st a sily Ft sa vypočítajú a a ε a nový stav je

xt+1 = xt + Δt vt,   vt+1 = vt + Δt a,   θt+1 = θt + Δt ωt,   ωt+1 = ωt + Δt ε,

t. j. nová poloha je stará plus Δt krát stará rýchlosť a nová rýchlosť je stará plus Δt krát zrýchlenie.

ε = g sin θ − cos θ · aF/l (4/3 − mt cos² θ/M)

g sin θ
tiaž — dôvod, prečo tyč padá: čím viac je naklonená, tým silnejšie ju gravitácia prevracia ďalej; vo zvislej polohe je nulová, takže zvislá poloha je rovnováha, lenže vratká
aF
zrýchlenie vozíka od sily regulátora (plus malá odstredivá sila tyče) — jediná cesta, ktorou regulátor na tyč pôsobí: vozík podíde pod tyč a kĺb ju „postrčí“ späť
cos θ
aká veľká časť vodorovného postrčenia tyč otáča — pri zvislej tyči takmer všetko, pri ležiacej nič; preto sa tyč naklonená o viac než pár stupňov zachraňuje ťažko
l (4/3 − …)
zotrvačnosť tyče — 4/3 pochádza z momentu zotrvačnosti homogénnej tyče okolo konca, 1/3 m(2l)² = 4/3 ml²; odčítaný člen opravuje to, že pri otáčaní tyče ucukne aj vozík pod ňou
Uhlové zrýchlenie tyče je súboj dvoch členov: tiaž tyč prevracia, zrýchlenie vozíka ju vracia.
Príklad — jeden krok simulácie

Štart (0, 0, 0,05, 0), teda tyč naklonená o 0,05 rad ≈ 2,9°; cos 0,05 ≈ 0,9988 a sin 0,05 ≈ 0,0500. Farby podľa rozboru vzorca pre ε vyššie. Menovateľ: 0,5 · (4/3 − 0,1 · 0,9988²/1,1) ≈ 0,621.

bez sily (F = 0, teda aj aF = 0): ε = 9,8 · 0,0500/0,621 ≈ +0,79 rad/s² — tyč začína padať

sila +10 N: aF = 10/1,1 ≈ 9,09 m/s²,   ε = 0,490 − 0,999 · 9,09/0,621 ≈ −13,8 rad/s²

po kroku: ω = 0 + 0,02 · (−13,8) ≈ −0,28 rad/s,   v ≈ 0 + 0,02 · 9,72 ≈ 0,19 m/s

Sila ±10 N je oproti tiaži obrovská — jediné trhnutie obráti smer pádu. Úloha teda nie je v sile, ale v načasovaní: kedy prestať tlačiť, aby sa tyč neprehupla na druhú stranu.

Koľko dá náhoda? Z tisícky regulátorov s náhodnými váhami vydržal všetkých 20 sekúnd jediný; medián je 9 krokov — tyč spadne za necelú pätinu sekundy. Priamočiary regulátor, ktorý len ide tam, kam sa tyč nakláňa, vydrží 39 krokov: tyč síce chytí, ale rozkmitá ju. Evolučná stratégia (5, 20) z dielu o evolučných stratégiách našla regulátor, ktorý vydrží celých 20 sekúnd zo všetkých troch štartov, v 15. generácii — po zhruba troch stovkách vyskúšaných regulátorov:

len podľa uhla 0,8 s evolúcia váh 20,0 s+
Kyvadlo na vozíku: prvých 8 sekúnd simulácie

Vyvinutý regulátor dáva najväčšiu váhu uhlovej rýchlosti — tyč nechytá, až keď padá, ale už keď sa do pádu rozbieha. Nezanedbateľné váhy má aj uhol a rýchlosť vozíka, takže vozík nekmitá a nevyjde z koľajnice. Takéto „pravidlo“ nikto nenapísal; vypadlo z evolúcie.

Definícia — zdatnosť regulátora a evolúcia váh

Nech w = (w1, …, w4, b) ∈ ℝ5 sú váhy regulátora z úlohy kyvadla a s(1) = (0, 0, 0,05, 0), s(2) = (0, 0, −0,08, 0), s(3) = (0,5, 0, 0,02, 0,1) tri štartovacie stavy. Pre k ∈ {1, 2, 3} označme Tk(w) ∈ {1, …, 1 000} počet krokov, ktoré pokus zo štartu s(k) s týmto regulátorom trvá (do pádu tyče alebo vyjazdu vozíka, najviac 1 000). Zdatnosť regulátora je

Z(w) = T1(w) + T2(w) + T3(w)/3 ∈ [1, 1 000].

Tri štarty namiesto jedného bránia tomu, aby evolúcia našla regulátor, ktorý zvláda len jednu východiskovú polohu. Z je po častiach konštantná — malá zmena váh počet krokov väčšinou nezmení vôbec, takže gradient je takmer všade nula. Preto evolúcia.

Evolúcia váh evolučnou stratégiou (5, 20) (pozri diel Evolučné stratégie a genetické programovanie): vstupom je funkcia Z a počet generácií G ∈ ℕ, výstupom najlepšie nájdené váhy.

  1. Zvoľ 5 rodičov w(1), …, w(5) ∈ ℝ5, každú ich zložku nezávisle a rovnomerne z [−1, 1].
  2. V každej generácii g = 1, …, G vytvor 20 potomkov: pre každého zvoľ rodiča w rovnomerne náhodne z piatich a polož w′ = w + 0,5 · z, kde z ∈ ℝ5 má zložky nezávislé so štandardným normálnym rozdelením N(0, 1) (pozri diel Prehľad pravdepodobnostných rozdelení).
  3. Novými rodičmi je 5 potomkov s najväčšou zdatnosťou Z; starí rodičia do ďalšej generácie nepostupujú.
  4. Po G generáciách vráť váhy s najväčšou zdatnosťou, aká sa počas behu objavila.
import random

def regulator(w, s):                 # s = (x, v, θ, ω)
    u = w[0]*s[0] + w[1]*s[1] + w[2]*s[2] + w[3]*s[3] + w[4]
    return 10 if u > 0 else -10       # skoková aktivácia: sila ±10 N

def zdatnost(w):                     # simuluj(): kroky do pádu, najviac 1000
    return sum(simuluj(regulator, w, start) for start in STARTY) / 3

rodice = [[random.uniform(-1, 1) for _ in range(5)] for _ in range(5)]
for generace in range(30):
    deti = [[wi + 0.5 * random.gauss(0, 1) for wi in random.choice(rodice)]
            for _ in range(20)]
    deti.sort(key=zdatnost, reverse=True)
    rodice = deti[:5]                # (5, 20): prežijú len potomkovia
Príklad — ako sa vyvinutý regulátor rozhoduje

Váhy nájdené evolúciou (zaokrúhlene): w = (0,05; 1,01; 1,37; 4,23), b = 0,09 pre (x, v, θ, ω). Farby podľa rozboru neurónu na začiatku dielu: váhy, vstupy, prah.

tyč naklonená, stojí: (0, 0, 0,05, 0) → u = 1,37 · 0,05 + 0,09 ≈ +0,16 → +10 N, vozík podíde pod tyč

tyč naklonená, ale už sa vracia: (0, 0, 0,05, −0,1) → u = 1,37 · 0,05 + 4,23 · (−0,1) + 0,09 ≈ 0,07 − 0,42 + 0,09 ≈ −0,26 → −10 N, vozík brzdí

V druhom prípade je tyč naklonená rovnako, ale regulátor tlačí opačne: uhlová rýchlosť −0,1 rad/s s váhou 4,23 má väčšiu váhu než uhol 0,05 rad s váhou 1,37. Tyč sa vracia sama, a keby vozík ďalej tlačil, prehupla by sa. Priamočiary regulátor „len podľa uhla“ by v oboch stavoch tlačil rovnako — preto tyč rozkmitá.

3. Prečo evolúcia, a nie gradient

  • Riedka odmena. Pri kyvadle, hre alebo robotovi sa kvalita pozná až po celej epizóde. Evolúcii stačí jedno číslo na konci.
  • Nederivovateľné časti. Skoková aktivácia, simulátor fyziky, pravidlá hry — evolúcia ich nemusí derivovať.
  • Paralelnosť. Každého jedinca možno ohodnotiť na inom počítači nezávisle.
  • Štruktúra. Gradient vie ladiť váhy, ale nie pridať neurón. Evolúcia môže meniť aj to, ako sieť vyzerá.

Nevýhodou je nenásytnosť: namiesto jedného gradientu, ktorý povie smer pre všetky váhy naraz, skúša evolúcia náhodné zmeny. Pre siete s miliónmi váh býva gradient oveľa úspornejší, ak sa ho vôbec dá vypočítať.

4. Keď nestačia váhy: XOR

Funkcia XOR vracia 1, keď je práve jeden z dvoch vstupov 1. Ako ukázal diel Logika a dôkazy, jediný neurón ju nezvládne: jeho výstup delí rovinu vstupov priamkou a body (0, 1), (1, 0) od (0, 0), (1, 1) žiadna priamka neoddelí. Na XOR treba aspoň jeden skrytý neurón. A tým sa otvára otázka, ktorú samotná evolúcia váh nevyrieši: koľko neurónov a ako ich zapojiť?

Veta — XOR nie je lineárne separovateľný

Nech XOR : {0, 1}2 → {0, 1} je funkcia daná predpisom XOR(x1, x2) = 1 ⇔ x1 ≠ x2. Potom neexistujú čísla w1, w2, b ∈ ℝ také, že pre všetky (x1, x2) ∈ {0, 1}2 platí

w1x1 + w2x2 + b > 0  ⇔  XOR(x1, x2) = 1.

Žiadna priamka teda neoddelí body, kde sa XOR rovná 1, od bodov, kde sa rovná 0.

Dôkaz. Keby také čísla existovali, platilo by

(0, 0): b ≤ 0    (1, 1): w1 + w2 + b ≤ 0

(1, 0): w1 + b > 0    (0, 1): w2 + b > 0

Sčítaním prvého riadka dostaneme w1 + w2 + 2b ≤ 0, sčítaním druhého w1 + w2 + 2b > 0. Spor. ∎

Dôkaz nepoužíva tvar aktivačnej funkcie — platí pre každý jediný neurón, ktorého výstup závisí len od znamienka váženého súčtu (skok aj sigmoida s prahom 0,5).

Odpovedať sa dá ručne — navrhnúť architektúru a evolúciou ladiť len váhy. Ale pri zložitejších úlohách netušíme, aká architektúra je správna. Prečo ju nenechať vyvinúť tiež?

5. NEAT: evolúcia rastúcich sietí

Pokusy vyvíjať evolúciou štruktúru sietí narážali na tri problémy. Ako krížiť dve siete s iným tvarom? Ako dať šancu novej štruktúre, ktorá je spočiatku horšia, pretože jej nové váhy ešte nie sú vyladené? A ako zabrániť, aby siete zbytočne napučiavali? Kenneth Stanley a Risto Miikkulainen v roku 2002 odpovedali algoritmom NEAT (NeuroEvolution of Augmenting Topologies) s tromi myšlienkami.

Definícia — genóm NEAT a historické značky

Nech uzly siete (vstupy, prah, výstupy a skryté neuróny, pozri definíciu neurónovej siete vyššie) sú označené prirodzenými číslami. Gén spoja je pätica (u, v, w, e, i), kde u je zdrojový a v cieľový uzol spoja u → v, w ∈ ℝ jeho váha, e ∈ {0, 1} príznak (e = 1: spoj je zapnutý a v sieti sa počíta, e = 0: vypnutý) a i ∈ ℕ jeho inovačné číslo. Genóm je konečná množina génov spojov, v ktorej majú rôzne gény rôzne inovačné čísla; určuje sieť, ktorej hrany sú zapnuté spoje.

Inovačné čísla prideľuje jeden čítač pre celú populáciu: kedykoľvek mutácia prvýkrát vytvorí spoj u → v, dostane ďalšie voľné číslo; ak vznikne rovnaká štruktúrna zmena (spoj medzi tými istými uzlami) u iného jedinca, dostane rovnaké číslo.

Mutácie genómu sú tri:

  1. zmena váh — váhy w génov sa zmenia (pripočítaním náhodného čísla alebo novou náhodnou hodnotou);
  2. pridanie spoja — pribudne gén (u, v, w, 1, i) s náhodnou váhou w pre dva doteraz nespojené uzly u, v (náš program pridá spoj, len keď nevznikne cyklus, takže sieť zostáva dopredná);
  3. pridanie neurónu — pre zvolený zapnutý gén (a, b, w, 1, i) vznikne nový skrytý neurón h, gén sa vypne (e ← 0) a pribudnú gény (a, h, 1, 1, i′) a (h, b, w, 1, i″) s novými inovačnými číslami.

Kríženie dvoch rodičov zarovná ich gény podľa inovačných čísel. Potomok dostane každý zhodný gén (inovačné číslo je v oboch rodičoch) od rodiča zvoleného náhodne s rovnakou pravdepodobnosťou a každý ostatný gén (je len v jednom z rodičov) len vtedy, ak je v genóme zdatnejšieho rodiča.

Laicky povedané

Inovačné číslo je rodný list spoja. Keď dve siete majú spoj s číslom 7, ide o „ten istý“ spoj, aj keď sa k nemu každá dostala inou cestou — a pri krížení sa dajú spárovať ako rovnaké gény u dvoch rodičov. Nový neurón sa vkladá tak, aby sieť spočiatku počítala podobne ako predtým; nič zásadné sa nerozbije, len pribudne možnosť.

Príklad — pridanie neurónu na spoj s váhou 2

Náš NEAT používa rovnako ako pôvodný článok strmšiu sigmoidu σ(z) = 1/1 + e−4,9z. Spoj x1 → y s váhou 2 prispieval do výstupu 2x1. Po rozdelení vedie x1 → h s váhou 1 a h → y s váhou 2:

x1 = 1:   2 · σ(1) = 2 · 0,993 ≈ 1,985   (predtým 2)

x1 = 0:   2 · σ(0) = 2 · 0,5 = 1   (predtým 0)

„Podobne“ tu teda znamená len sčasti: pre vstup 1 je zmena zanedbateľná, pre vstup 0 pribudne do súčtu jednotka, pretože sigmoida v nule vracia polovicu. Sieť sa tým trochu pokazí — a práve preto potrebuje nová štruktúra ochranu, o ktorej je reč ďalej.

Definícia — speciácia a zdieľanie zdatnosti

Nech G1, G2 sú neprázdne genómy (pozri definíciu genómu vyššie) a I1, I2 množiny inovačných čísel ich génov. Označme m = min(max I1, max I2) a

  1. zhodné gény: inovačné čísla z I1 ∩ I2;
  2. disjunktné gény: čísla i ∈ (I1 ∖ I2) ∪ (I2 ∖ I1) s i ≤ m (chýbajú jednému z genómov „v strede“); D je ich počet;
  3. prebytočné gény: čísla i ∈ (I1 ∖ I2) ∪ (I2 ∖ I1) s i > m (za koncom kratšieho genómu); E je ich počet;
  4. W̄ je priemer |wi(1) − wi(2)| cez zhodné gény i (rozdiel váh toho istého génu v oboch genómoch; ak nemajú zhodné gény, W̄ = 0);
  5. N = max(|G1|, |G2|) je počet génov väčšieho genómu, ak je aspoň 20, inak N = 1.

Pre konštanty c1, c2, c3 ≥ 0 je kompatibilitná vzdialenosť genómov G1, G2 číslo

δ(G1, G2) = c1 E/N + c2 D/N + c3 W̄.

Speciácia: nech δt > 0 je prah a každý druh má zástupcu. Genóm patrí do prvého druhu, s ktorého zástupcom Z má δ(genóm, Z) < δt; ak taký neexistuje, založí nový druh. Druhy S1, …, SK tak rozdelia populáciu veľkosti P na disjunktné neprázdne časti.

Zdieľanie zdatnosti: ak má jedinec i ∈ Sk zdatnosť fi ≥ 0, je jeho zdieľaná zdatnosť f′i = fi/|Sk|, druh k má F̄k = ∑i ∈ Sk f′i (priemernú zdatnosť svojich členov) a dostane

nk = P · F̄k/∑j=1K F̄j

potomkov (zaokrúhlené nadol, zvyšok dostane druh s najlepšou sieťou). Podobné genómy teda tvoria druh, zdatnosť jedinca sa delí veľkosťou jeho druhu a potomkovia sa rozdeľujú medzi druhy podľa ich priemernej zdatnosti.

Laicky povedané

Siete s podobnou stavbou súťažia hlavne medzi sebou, nie s celou populáciou. Nový neurón tak dostane pár generácií na to, aby sa jeho váhy vyladili, namiesto toho, aby ho hneď zmietli zavedené siete. A pretože sa zdatnosť v druhu delí, žiadny druh nemôže ovládnuť celú populáciu.

δ = c1 E/N + c2 D/N + c3 W̄

c1 E
prebytočné gény — štruktúra, ktorú jeden genóm získal až po poslednom spoločnom „vynáleze“; znamená mladšiu, odlišnú vetvu vývoja
c2 D
disjunktné gény — vynálezy z čias, keď už oba existovali, ktoré má len jeden z nich; ďalšia miera rozdielu stavby
N
veľkosť väčšieho genómu — aby dva veľké genómy, ktoré sa líšia o pár génov z mnohých, nevyšli rovnako vzdialené ako dva malé, ktoré sa líšia takmer vo všetkom; pri genómoch pod 20 génov sa berie N = 1
c3 W̄
priemerný rozdiel váh zhodných génov — rovnako zapojené siete s veľmi odlišnými váhami počítajú iné funkcie; váha c3 je menšia, pretože stavba sa mení zriedkavejšie a znamená viac
Konštanty c1 = c2 = 1, c3 = 0,4 a prah δt = 3 sú hodnoty, ktoré pre XOR použili Stanley a Miikkulainen (2002); rovnaké má aj náš program.
Príklad — vzdialenosť po pridaní neurónu

Genóm A má gény 1–5. Genóm B vznikol z podobného predka: má tiež gény 1–5 (gén 3 vypnutý, pretože ho rozdelil nový neurón) a navyše gény 6 a 7 z pridania neurónu. Váhy zhodných génov sa líšia o 0,2; 0,6; 0; 0,9 a 0,8.

zhodné: 1–5 → W̄ = 0,2 + 0,6 + 0 + 0,9 + 0,8/5 = 0,5

prebytočné: 6, 7 (za koncom kratšieho genómu, ten končí génom 5) → E = 2;   disjunktné: žiadne → D = 0;   genómy majú menej ako 20 génov → N = 1

δ = 1 · 2/1 + 1 · 0/1 + 0,4 · 0,5 = 2,2 < 3 → rovnaký druh   (farby podľa vzorca vyššie)

Keby B získal ešte jeden spoj (gén 8), vyšlo by E = 3 a δ = 3,2 ≥ 3 — B by založil nový druh. Jediný nový neurón teda sieť z druhu nevyradí, ale nový neurón s novým spojom už áno.

nk = P · F̄k/∑j F̄j,   F̄k = ∑i ∈ Sk fi/|Sk|

nk
počet potomkov druhu k v ďalšej generácii — týmto sa v NEATe odmeňuje úspech, nie výberom jednotlivcov z celej populácie
P
veľkosť populácie (150) — potomkovia sa delia ako koláč, populácia nerastie ani sa nezmenšuje
|Sk|
počet členov druhu — zdieľanie zdatnosti: zdatnosť každého člena sa delí veľkosťou jeho druhu, f′i = fi/|Sk|; veľký druh tak nemôže získať viac len tým, že je veľký
F̄k
súčet zdieľaných zdatností druhu, teda jeho priemerná zdatnosť — o podiele na koláči rozhoduje kvalita, nie počet
∑j F̄j
súčet cez všetky druhy — delením vznikne podiel, ktorý sa sčíta na 1, takže sa rozdelí presne P potomkov (po zaokrúhlení nadol dostane zvyšok najlepší druh)
Príklad — prečo zdieľanie chráni nový druh

Populácia 150: zavedený druh A má 120 sietí s priemernou zdatnosťou 9,0, nový druh B so skrytým neurónom 30 sietí s priemernou zdatnosťou 7,5.

so zdieľaním (farby podľa vzorca vyššie): nA = 150 · 9,0/16,5 ≈ 81,8 → 81 (+1 zvyšok) = 82,   nB = 150 · 7,5/16,5 ≈ 68,2 → 68

bez zdieľania (podľa súčtu zdatností 120 · 9,0 = 1 080 a 30 · 7,5 = 225): A ≈ 150 · 1 080/1 305 ≈ 124,   B ≈ 26

Bez zdieľania by nový druh za pár generácií vymrel, pretože je horší a menší. So zdieľaním dostane viac potomkov, než má členov, a má čas vyladiť váhy.

Tretia myšlienka je najjednoduchšia: začať od minima. Všetky siete na začiatku nemajú žiadny skrytý neurón — vstupy vedú rovno do výstupu. Štruktúra pribúda len vtedy, keď sa oplatí. Výsledné siete preto bývajú malé.

Všetko dohromady — jedna generácia nášho zjednodušeného NEATu (pravdepodobnosti sú tie, s ktorými beží program pre XOR):

populácia ← 150 minimálnych sietí (x₁, x₂ a prah rovno do y, váhy náhodne z [−2, 2])
pre generáciu g = 0, 1, …, 100:
    ohodnoť každú sieť zdatnosťou f
    ak niektorá sieť rieši úlohu: koniec
    rozdeľ siete do druhov: sieť patrí do prvého druhu, s ktorého zástupcom má δ < 3,
                            inak založí nový
    vyraď druhy, ktoré sa 15 generácií nezlepšili (okrem druhu s najlepšou sieťou)
    druhu k prideľ n_k = 150 · F̄_k / ∑ F̄_j potomkov
    v každom druhu:
        rodičia ← najlepších 20 % členov
        ak má druh viac než 5 členov, jeho najlepšia sieť prejde bez zmeny
        každý ďalší potomok:
            s pravdepodobnosťou 0,75 kríženie dvoch rodičov, inak kópia jedného
            s pravdepodobnosťou 0,8 zmeň váhy (90 %: w ← w + N(0, 1), 10 %: nová náhodná)
            s pravdepodobnosťou 0,1 pridaj spoj
            s pravdepodobnosťou 0,03 pridaj neurón (rozdeľ náhodný zapnutý spoj)

6. NEAT na XOR

Náš zjednodušený NEAT má populáciu 150 sietí a najviac 100 generácií. V behu z obrázka vyriešil XOR v generácii 27 sieťou s jediným skrytým neurónom a siedmimi spojmi — čo je najmenšie možné riešenie:

f = ( 4 − ∑ |y − t| )2

∑ |y − t|
chyba — súčet odchýlok výstupu y od správnej hodnoty t cez všetky štyri vstupy; absolútna hodnota, aby sa chyby nahor a nadol navzájom nevyrušili
4
najväčšia možná chyba (štyri vstupy, každá odchýlka najviac 1) — odčítaním sa z chyby, ktorú chceme zmenšiť, stane zdatnosť, ktorú evolúcia zväčšuje, a tá je vždy nezáporná
2
umocnenie — zosilní rozdiely blízko riešenia: sieť s chybou 0,5 má zdatnosť 12,25, sieť s chybou 1 len 9, takže výber viac odmení posledných pár percent
Zdatnosť pre XOR podľa pôvodného článku NEAT (Stanley a Miikkulainen, 2002); najviac 16. Sieť, ktorá na všetko odpovie 0,5, má zdatnosť (4 − 2)2 = 4. Za riešenie sa sieť považuje, keď po zaokrúhlení výstupu odpovie správne na všetky štyri vstupy.
−1,4 −3,0 3,3 −3,4 −5,7 −3,7 0,9 x₁ x₂ 1 y h x₁x₂y 00 0,00 01 0,86 10 1,00 11 0,01
Sieť pre XOR, ktorú vypestoval NEAT; vpravo jej výstupy

Sieť sa dá prečítať. Skrytý neurón h sa rozsvieti len vtedy, keď sú oba vstupy 0 (oba majú veľkú zápornú váhu, prah je kladný). Priame spoje do výstupu by samy počítali „nie oba zároveň“ — výstup 1 pre všetko okrem (1, 1) —, ale silne záporná váha od h ho pre (0, 0) vypne. Výstupy 0,000; 0,855; 1,000 a 0,005 sú po zaokrúhlení presne XOR. Počet druhov medzitým vzrástol z jedného na zhruba dvadsať.

Príklad — výpočet siete pre všetky štyri vstupy

Váhy (zaokrúhlene): do h z x1, x2 a prahu −3,37; −3,67; 0,95; do y z x1, x2, prahu a h −1,42; −2,96; 3,32; −5,69. Aktivácia je σ(z) = 1/1 + e−4,9z. Najprv sa vypočíta h, potom y (tabuľka počíta s nezaokrúhlenými váhami, takže ručný prepočet sa môže líšiť v poslednej cifre):

(x1, x2)zhhzyy|y − t|
(0, 0)0,950,9903,32 − 5,69 · 0,990 = −2,320,0000,000
(0, 1)−2,720,000−2,96 + 3,32 = 0,360,8550,145
(1, 0)−2,430,000−1,42 + 3,32 = 1,891,0000,000
(1, 1)−6,090,000−1,42 − 2,96 + 3,32 = −1,060,0050,005

Chyba je 0,150 a zdatnosť f = (4 − 0,150)2 ≈ 14,82 zo 16 (farby podľa vzorca zdatnosti vyššie). Najhoršie sieť odpovedá pre (0, 1): výstup 0,855 je správne nad polovicou, ale nie pri jednotke — na riešenie to stačí, ďalšie ladenie váh by zdatnosť ešte zvýšilo.

Z päťdesiatich behov s rôznymi semienkami vyriešil NEAT XOR v 47, v priemere za 31 generácií, s 2,6 skrytého neurónu, ktoré naozaj niečo robia. Pôvodný článok uvádza 32 generácií a 2,35 skrytého neurónu — náš zjednodušený NEAT je teda blízko.

7. Na čom NEAT stojí

Rovnakých 50 behov s vypnutou časťou algoritmu:

VariantVyriešilo XORPriemerná generácia
NEAT47 z 5031,1
bez speciácie (jeden druh)1 z 50—
bez kríženia50 z 5047,3

Bez speciácie NEAT takmer nefunguje. Sieť so skrytým neurónom je po vzniku horšia než zavedené siete bez neho, pretože jej nové váhy sú náhodné — a v jednej spoločnej súťaži ju výber okamžite vyradí. Speciácia ju ochráni, kým nedozrie. Bez kríženia sa XOR vyrieši tiež, len pomalšie a s väčšími sieťami (3,1 aktívneho skrytého neurónu): kríženie pomáha skladať dohromady čiastkové objavy rôznych jedincov.

8. Nasledovníci NEATu

  • HyperNEAT (Stanley a kol., 2009) vyvíja evolúciou malú sieť, ktorá až vygeneruje váhy veľkej siete podľa geometrie úlohy — ako genóm, ktorý neopisuje každú bunku, ale pravidlá rastu.
  • Hľadanie novosti (Lehman a Stanley, 2011) neodmeňuje zdatnosť, ale nové správanie. V bludisku so zavádzajúcimi slepými uličkami našlo cieľ častejšie než hľadanie riadené zdatnosťou.
  • Hlboká neuroevolúcia. V roku 2017 ukázal tím Uber AI, že obyčajný genetický algoritmus dokáže trénovať siete s miliónmi váh na hrách Atari porovnateľne s učením posilňovaním.
  • Evolučné hľadanie architektúr. Sieť AmoebaNet (Google, 2019) vznikla evolúciou stavebných blokov a v rozpoznávaní obrázkov na ImageNete patrila v tom čase k najlepším. Dnes architektúry častejšie navrhujú ľudia alebo iné metódy, ale evolúcia zostáva jednou z možností.

9. Zhrnutie

  • Neuroevolúcia pestuje neurónové siete evolučnými algoritmami — hodí sa tam, kde sa gradient nedá vypočítať alebo kde odmena prichádza až na konci.
  • Evolúcia váh jedného neurónu udrží kyvadlo na vozíku 20 sekúnd po zhruba troch stovkách pokusov; náhodné váhy dajú v mediáne 9 krokov.
  • Na XOR nestačí jeden neurón — treba zmeniť štruktúru siete.
  • NEAT vyvíja váhy aj štruktúru: historické značky umožnia kríženie, speciácia chráni nové štruktúry a siete rastú od minima.
  • Bez speciácie vyriešil NEAT XOR v 1 z 50 behov, so speciáciou v 47 — a najlepšie riešenie malo jediný skrytý neurón.

Chcete si to vyskúšať na vlastnej koži? Nechajte AI agenta napísať kyvadlo na vozíku s evolúciou regulátora a potom skúste dve tyče rôznej dĺžky na jednom vozíku — slávnu ťažšiu verziu, v ktorej NEAT kedysi vynikal.

Máte na to iný názor? Napíšte na support@coden-app.com.

Agent na vašom počítači, ovládaný z telefónu