Přestože je v létě obyčejně horko, mozek stále mozkuje. Mozkuje dokonce i v zimě. A to je dobře. Jeho činnost je důležitá při malování obrázků a dalších důležitých operacích během takového běžného dne, nebo dokonce i během náročného dne. Někdo třeba ale maluje jen tehdy, když má deprese. Jenomže deprese způsobují chemické změny v mozku, takže na tom ve finále vlastně nezáleží. Při malování je mozek zkrátka potřeba. Proto ho chtějí zomby sníst.
Žijeme v děsivé době, kdy je téměř nemožné si nevšimnout všech okolních trendů, ačkoliv se i tak dají celkem slušně při troše cviku ignorovat. Letošním hitem, kdy všechny děti mají ajfouny od rodičů, se kromě lovu pokémonů vysávajících portály Ingressu stala jednoznačně Prisma. Nějaká další aplikace na obrázky, řeklo by se. Vtip je v tom, že oproti všem ostatním neaplikuje na fotografie žádné trapné statické lokální filtry nebo overlay obrázky, ale od základů je celé překresluje s použitím dle výběru dostupných malířských stylů. Už to bude nějaký rok nebo dva zpátky, kdy kdosi experimentoval s rekonstrukcí předložených obrazových dat podle vzorů nějakých digitálních fotoreprodukcí obrazů slavných mistrů. A tehdy k tomu poprvé použili neuronové sítě. Jak je vidět, v jakkoliv dobré míře to Prisma myslela, marketing dal opět technologie do rukou idiotům.
Neuronová síť (neural network, tedy nervový netvor) je biologií inspirovaný výpočetní model z kategorie umělé inteligence. Jejím úkolem, jak napovídá název, je vytvořit síť syntetických neuronů podobných těm, co jsou ve skutečném mozku, a použít je jejich přirozených způsobem pro zpracování předložených signálů. Biologická nervová buňka má sama o sobě kolem svého jádra několik stromových špiček, kterými mohou signály z vesmíru vnímat a na druhé straně zase vysílat. Rychlost skutečné myšlenky doslova závisí na jejich stavu. Matematická představa podobného útvaru může vypadat jako jednoduchý sčítač několika různých a různě silných vstupů následovaný obecným komparátorem schopným poslat v závislosti na svém stavu něco na výstup. Zřejmě by to šlo popsat jako
$$y_k\,=\,\varphi\left(\sum_{j=0}^{m}\,w_{kj}x_{j}\right),$$
kde yk představuje výstupní hodnotu signálu neuronu z aktivační funkce φ(x), která pracuje s lineární w-váženou kombinací celkových m vstupů x. Pro konkrétní modelování něčeho takového se úplně nabízí operační zesilovač, nebo prostě analogový počítač, pro který jsou takové vstupy dostatečně přirozené. Aktivační funkce reprezentující komparátor může být v závislosti na celkovém účelu různá, přičemž bývá obohacena o hlídání nějakého prahu Θ, případně je pro nějaký celek důležitý průběh její derivace.
Tvorba neuronových sítí není zrovna něco, co by běžně na hodinách počítačů dělaly holky z obchodky, takže není úplně snadné někomu nezasvěcenému vyprávět o jejich tvorbě. Jednotlivé neurony taky zkrátka mají nějaké to sociální sítění, takže cílem neuronové sítě je vytvořit jejich určité topologické vztahy podobné skutečným nervovým strukturám v mozku a poskytnout základní pravidla aktivační dynamiky a rychlosti jejího sebeučení. Protože nejenom cibule mají vrstvy, nejobvyklejší je jejich spojení do pomyslných vrstev, jak je to zjednodušeno na následujícím diagramu.
Schopnost stroje učit se za pochodu je jedním z aspektů umělé inteligence v tom smyslu, že takováto struktura umí více rozeškálovat vstupní data předaná do první vrstvy a opakovat to dokola do té doby, dokud jí to nebude stačit pro konkrétní výsledek - tedy podobně jako v genetických algoritmech dojde k nějakému odhadu, který může, i když nemusí, odpovídat neznámu, složitému zápisu formální logiky. Učení získané touto zpětnou propagací se prakticky snaží minimalizovat chyby vzniklé předchozími odhady správným určováním všech dílčích prahů θ, přičemž chybou se dá myslet třeba čtverec rozdílu dílčího výsledku a a výsledku t očekávaného v daném bodě k:
$$E\,=\,\dfrac{1}{2}\,\sum_{k{\in}K}\left(a_{k}-t_{k}\right)^{2},$$
čehož se dá dosáhnout výpočtem gradientu klesání, tedy
$$\dfrac{∂{E}}{∂{w_{ik}}}\,=\,\dfrac{1}{2}\,\sum_{k{\in}K}\left(a_{k}-t_{k}\right)^{2}$$
pro poslední vrstvu a dost obdobně a zbytečně složitě pro všechny skryté vnitřní vrstvy. Jde zkrátka o to, že učící se neuronová síť není úplně určená pro nečiperníky. Co se týče ještě pokročilejších zákeřností, konvoluční neuronové sítě jsou v současné době největší špičkou v optickém rozpoznávání věcí. Prakticky rozmlátí vstupní vizuální data pomocí konvolučních masek s malinkými jádry a poskládají je na sebe, čímž získají vážně široké pole pro vnímání při relativně malém množství parametrů nutných k sebeučení. Takovou věc konkrétně na Oxfordu vytvořili v 19 vrstvách a získali s ní velmi slušné výsledky. Výcvik této velmi hluboké sítě jim zabral několik týdnů na čtyřech kartách nVidia Titan X. A svůj model, VGG-19, nakonec šikovně zveřejnili.
No, jako vždycky, višjak. Když je k dispozici nějaká technologie, sněz ji. Taková možnost přímo vybízí k vyzkoušení, protože se prostě jen naskytla příležitost i pro obyčejné smrtelníky, a to bez marketingových lstí kolem dokola. Samotný model je k dispozici ve formátu caffe, frameworku z Berkeley. Prisma samotná někde na začátku využívá tohoto modelu, ale měli možnost si ho usměrnit, upravit a maximálně vycvičit. Otázkou je, jestli by se dalo neurálně malovat i doma.
Jak už asi vyplývá z matematických základů, není úplně triviální použít poskytovaný několiksetmegabajtový model samostaně, bylo by prima mít k dispozici nějakou abstraktnější vrstvu, která není náročná na ovládání a disponuje optimalizovanými metodami přímo určenými pro strojové učení a tenzorové počty. Jak se zdá, optimální je k tomu Torch běžící pod LuaJITem, navíc podpůrné matematické knihovny mohou být zaměňovány nebo sestaveny přímo pro konkrétní hardware bez zbytečných ochechulí.
Základem je celkem pochopitelně Linux. Tady si asi někdo něco pomyslí, ale přestože mám v hlavě švihnutí Debianem, zvolil jsem hned z několika důvodů Fedoru (rychlé FAQ - proč ne Ubuntu? Jak už je v úvodu, pokémoni mě zrovna nezajímají). Možná po několika útrapách. Kdo ví.
S cílem dopřát si akcelerované výpočty na GPU, konkrétně tedy prostřednictvím nVidia CUDA, je ponejprv nutné systém upravit k takovýmto radovánkám. Toolkit pro CUDA vyžaduje v první řadě binární modul ovladače stažitelný přímo z webu nVidia ve verzi pro konkrétní kartu. Je nutné se podívat, jaká maximální verze CUDA je pak schopná na té verzi ovladače běžet. Pro nahrazení dnes již celkem běžného svobodného nouveau bude potřeba udělat pár věcí navíc, v první řadě ho blacklistovat v dostupných modulech (echo "blacklist nouveau" >> /etc/modprobe.d/kokos.conf), blacklisotvat ho i v zavaděči (odpovídající parametr rd.driver.blacklist=nouveau pro GRUB a nezapomenout promítnout úpravu pomocí grub2-mkconfig) a smazat odpovídající balíček, je-li ještě stále v systému (něco jako yum remove xorg-x11-drv-nouveau). A pak je tady ta přítulná fedoří magie, totiž dracut. Nestačí totiž jen zakázat modul, on by měl být taky hlavně odstraněn z initrd, a to je tady po zablacklistování celkem legrace - s aktuálním jádrem prostě dracut /boot/intirams-$(uname -r).img $(uname -r) a je to. Po rebootu by mělo být vše čisté, tmavé a .run instalátor od nVidie by neměl zahlásit žádnou chybu. Pakliže ne, můžeme jeho modul načíst.
Další sranda je CUDA. I v tomto případě je místo balíčkovací verze asi stokrát lepší stáhnout celý .run instalátor a odpálit ho s -no-opengl-libs -samples -toolkit -silent. Je důležité si uvědomit, že záleží na jeho verzi, takže například CUDA 6.5 vyžaduje gcc-4.6 a nikoliv novější. Statečné duše se mohou v případě vyšší verze pokusit po prvním neúspěchu o překročení bezpečnosti pomocí -override. Když to nevyjde, dá se prostě gcc-4.6 stáhnout a přeložit ručně, ovšem existuje tu určitá možnost, že se to pokazí, zvlášť při pokusu překládat na amd64 pomocí gcc-4.8 a vyššího. Je to kvůli kompatibilitě, mělo by ovšem postačit upravit jednu hlavičku a jede se dál.
136c136 < struct siginfo *pinfo; --- > siginfo_t *pinfo; 138c138 < struct siginfo info; --- > siginfo_t info;
Jestli a pokud běží CUDA, je velmi vhodné překompilovat a vyzkoušet přiložené ukázky (samples) a hlavně přidat si natrvalo do profilu cestu k toolkitu (typicky bude nějakým linkem pod /usr/local/cuda) a cestu ke knihovnám (tamtéž, v lib64), source ~./bashrc.
Samotná příprava pro Torch vyžaduje nějaké balíky navíc, kromě běžných vývojářských nástrojů CZMQ knihovny, stejně tak vývojový balík Qt, FFTW 3 a taky Node.js. Potom bude i přes jiné možnosti nejspíš potřeba OpenBLAS a kompilátor pro Protocol Buffers od Google. Pro Torch existují předpřipravené samostatné distribuce, třeba předpřipravené distro-cl, které sice podle názvu operuje hlavně s OpenCL, ale CUDA je stejně jen volitelný backend pro spuštěnou síť. Balík sám vytvoří i cestu v profilu, takže se pak s ním dá globálně operovat pouhým voláním th. A nakonec to nejlepší. Pro opravdu snadné používání a automatické stažení a načtení modelu pracujícím v Torch je malý, několikařádkový skript neural-style, který nabízí celkem dost možností, jak věci zpracovávat.
Výsledky používání jsou vskutku kouzelné, i když hodně záleží na vhodně zvolené míře a výřezu stylu, který má být na fotku aplikován. Na tomto místě děkuji Sisi za umožnění provádět pokusy na jejím obrázku, tedy jejich přemalování odpovídajícími mistry. Zatímco obrázek Fridy Kahlo vypadá velmi přirozeně, Munchův Výkřik výborně zpracoval hladklé plochy a z nějakého důvodu se rozhodl zamatlat tvář. A to nejspíš proto, že ji v původní předloze v námi očekávaném tvaru prostě nenašel :). U van Gogha zase není zcela vyvážená práce s prázdným místem.
Provoz samostatné neuronové sítě je ale dle očekávání strašlivě náročný na paměť. Zatímco se člověk musí soustředit při malování jen na jedno místo a vše ostatní tuší intuitivně, počítačem uchovávaná síťka musí mít v paměti kompletní obraz, podle kterého rekonstruuje. A ten je velký. Vlastně není, je zatraceně velký. Mířím tím tak trochu k paradoxu, že sebevýkonnější GPU je k ničemu, pokud už od návrhu nepočítá s ne-úplně grafickým využitím. Obrázky s delší stranou okolo 800 px si při rekonstrukci na tisíci průchodech vyžádaly téměř 14 GB operační paměti, čímž žádná mně dostupná karta nedisponuje. Nezbylo na skutečně jasné obrázky než použít velmi pomalý CPU o pouhých čtyřech jádrech.
Dalším perkem CPU je téměř nekonečná doba na dokončení, která v součtu všech paralelních jader klidně mohla dosahovat osmi hodinám na Core i5. Mít vyloženě reálné použitelné pastelky by stalo přibližně kolem půl milionu, pokud budeme za takové pastelky považovat třeba Tesly s Kepler K80, ty mají dokonce 24 GB VRAM. Prisma to dělá ke svému vlastnímu štěstí úplně jinak. Mobilní zařízení zdrojový JPEG odlehčí, odešle vzduchem na jejich grafické cloudy, kde jejich optimalizované a velmi vycvičené postupy na omezeném množství předloh vykonají svou práci, a výsledek pošle uživateli zpět dost možná zase s nějakými metainformacemi k rekonstrukci umožňující snížit celkový objem dat i pro relativně velké - přes 1000 px velké - obrázky. Jsou to zkrátka čipery, ale kromě dinosaura nemají ještě jinou věc. Předlohy tvořené neznámými autory, resp. amatéry nebo našimi blízkými či vzdálenými přáteli, jako je třeba Sisi nebo Týna. Ty taky doma potajmu malují.
-
Krno
-
Kočička
-
iMac G3
-
Noční Sisikjů
-
Nějaká kresba
-
Týnky pták
-
Noční Sisi-Krno
-
Překreslená kočička
-
Týny iMac
Je pravda, že je třeba dlouho hledat specifické podobnosti v předloze a cílovém obrázku, aby z toho vzniklo něco relativně přirozeného, na druhou stranu mají celkem velký úspěch rekonstrukce získané z víceméně abstraktních předloh. Přestože je to celé velmi náročný proces, neurální malování má rozhodně velký potenciál a každý by si to měl vyzkoušet. Vždyť bylo věnováno obrovské úsilí na poli výpočetní techniky k fotorealistickému zpracování obrazu. Výsledek snažení, dnešní umělá inteligence, dosahuje velmi přesvědčivě pravého opaku - jakýkoliv obraz teď může vypadat jako patlanica a lidé zatleskají. A to vždy. Je vidět, že se máme ještě hodně co učit.