markdown
Konvolucni-site.md
markdown
# Konvoluční neuronové sítě (CNN) Obrázek `224×224` ve třech barevných kanálech má 150 528 čísel. Napoj ho na plně propojenou vrstvu o tisíci neuronech a máš **150 milionů vah** v jediné vrstvě. Nenatrénuješ to, nevejde se to do paměti a hlavně je to zbytečné - protože detektor svislé hrany je v levém horním rohu užitečný stejně jako v pravém dolním, a plně propojená vrstva se ho musí naučit pro každou pozici zvlášť. Konvoluční síť tenhle problém řeší jedním nápadem: **naučí se filtr jednou a posouvá ho po celém obrázku.** Z těch 150 milionů vah se stane pár set. Tahle stránka je o tom, jak se CNN skládá a proč každá vrstva existuje. Předpokládá to [MLP a backpropagation](MLP-a-backpropagation) - trénování je totiž úplně stejné - a [umělý neuron](Neuron-a-perceptron), zejména ReLU. ## Definice a odkud se to vzalo **Konvoluční síť** je specializovaná dopředná síť pro zpracování dat s **mřížkovou strukturou** - obrazy, zvuk, video. Inspirace je z biologie a je konkrétní: práce **Hubela a Wiesela z roku 1962** o primární zrakové kůře koček. Zjistili, že jednotlivé neurony reagují na podněty jen v malé části zorného pole (**receptivní pole**) a že různé neurony reagují na různě orientované hrany. Přesně tohle CNN kopíruje. **Milník: ImageNet 2012.** Alex Krizhevsky se sítí AlexNet snížil chybu klasifikace z **26 % na 15 %**. To odstartovalo nástup hlubokého učení - ne jako nová myšlenka, ale jako důkaz, že to funguje. Konvoluční sítě existovaly od osmdesátých let, chyběla jen data a grafické karty. ## Reprezentace obrazu Barevný obrázek `32×32` je **trojrozměrná matice `32×32×3`** - kanály R, G, B. Hodnoty pixelů jsou 0-255, případně normalizované na `[0, 1]`. Ta [normalizace](Metriky-a-vyhodnoceni#základní-typy-dat) není volitelná. Vstupy v rozsahu 0-255 nasytí aktivační funkce a síť se přestane učit hned v první vrstvě. ## Vrstvy CNN ### Konvoluční vrstva Jádrem je **filtr (kernel)** - malá matice vah, například `5×5×3` - která „klouže" po vstupním tenzoru. V každé pozici se spočítá **skalární součin vah filtru se vstupem** a výsledek se zapíše do **mapy příznaků** (feature map, activation map). **Receptivní pole** jednoho výstupního bodu odpovídá oblasti filtru na vstupu. Všimni si hloubky filtru. Filtr `5×5×3` má tu trojku, protože musí pokrýt všechny tři barevné kanály naráz. **Filtr je vždycky tak hluboký jako jeho vstup** a jeho výstup je jedna dvourozměrná mapa. **Víc filtrů znamená víc map příznaků.** Každý filtr se „učí" detekovat jinou nízkoúrovňovou vlastnost - hrany, barvy, textury. V hlubších vrstvách se z nich skládají složitější reprezentace: části objektů, celé objekty. **Tohle je nejdůležitější věta na celé stránce: CNN si příznaky navrhne sama.** Vrať se k [příznakovým metodám](Priznakove-metody), kde se LBP a histogramy musely vymyslet ručně. Tady se první vrstva naučí něco, co detektorům hran nápadně připomíná, a nikdo jí to neřekl. Vyplyne to z dat a z toho, že se to hodí pro minimalizaci chyby. Dvě vlastnosti, které z toho posouvání plynou a stojí za pojmenování: **Sdílení vah.** Tentýž filtr se používá na všech pozicích, takže se počet parametrů nezávisí na velikosti obrázku. Odtud ta úspora ze 150 milionů na pár set. **Ekvivariance vůči posunu.** Posuň objekt v obrázku a mapa příznaků se posune stejně. Detektor hrany funguje všude, protože je všude tentýž. ### Aktivace (ReLU) Po konvoluci následuje prvek-po-prvku aktivace, nejčastěji **ReLU**: `f(x) = max(0, x)`. **Vnáší do sítě nelinearitu** - bez ní by celá síť byla jedna lineární operace, viz [MLP](MLP-a-backpropagation#co-mlp-je) - **a současně urychluje trénování**, protože potlačuje problém mizejícího gradientu. Derivace ReLU je v kladné části přesně jedna, takže se gradient přes vrstvy neztrácí. ### Pooling **Redukuje prostorovou velikost map (downsampling).** Nejběžnější je **max-pooling s oknem `2×2` a krokem 2**: zmenší mapu na poloviční rozlišení a ponechá nejsilnější aktivaci v každém okně. Přínosy jsou dva: - **úspora paměti a výpočtu** - poloviční rozlišení znamená čtvrtinu bodů,- **robustnost vůči malým posunům** - když se hrana posune o pixel, maximum v okně `2×2` zůstane stejné. Ten druhý bod je ta zajímavější polovina. Konvoluce je vůči posunu **ekvivariantní** (výstup se posune), pooling přidává částečnou **invarianci** (výstup se nezmění). Skládáním konvoluce a poolingu tak síť postupně přestává řešit, kde přesně objekt je, a začíná řešit, jestli tam je. ### Plně propojená vrstva (FC) Poslední vrstvy jsou klasické „dense" vrstvy, které z vektoru vysokoúrovňových příznaků spočítají výsledný **klasifikační vektor**. Na závěr se aplikuje **softmax**, který normalizuje výstupy do pravděpodobnostního rozdělení přes třídy. **Rozdělení práce v CNN je tedy jasné: konvoluční část dělá extrakci příznaků, plně propojená část dělá klasifikaci.** Tohle je přesně to rozdělení, které u [příznakových metod](Priznakove-metody) dělal člověk a klasifikátor. CNN dělá obojí a učí to naráz. ## Typická architektura LeNet ```Input → Conv → ReLU → Conv → ReLU → Pool → Conv → ReLU → Pool → FC → Softmax``` Vzorec, který se opakuje: **konvoluce, aktivace, občas pooling** - a na konci plně propojené vrstvy se softmaxem. Sleduj, co se v tom sledu děje s rozměry. **Prostorové rozměry klesají** (pooling), zatímco **hloubka roste** (víc filtrů v hlubších vrstvách). Ze `32×32×3` se stane třeba `8×8×64`. Obrázek se mění z „velký a mělký" na „malý a hluboký" - z pixelů na příznaky. ## Trénování CNN Stejně jako u [MLP](MLP-a-backpropagation): dopředný průchod, výpočet ztráty, zpětný průchod a aktualizace vah. Ztrátová funkce bývá **křížová entropie**, případně střední kvadratická chyba: ```Etotal = ½ Σ (tk − yk)²``` Aktualizace vah gradientním sestupem: ```w = wi − η · ∂L/∂W``` Trénink probíhá **v mini-batchích na GPU** a obvykle zabere **desítky až stovky epoch**, kde epocha je jeden průchod celým trénovacím datasetem. **Backpropagation ve sdílených vahách funguje tak, že se gradienty ze všech pozic sečtou.** Filtr se objevuje na stovkách míst a každé z nich přispěje svým dílem chyby do téže sady vah. Nic dalšího se v algoritmu měnit nemusí - a to je důvod, proč se CNN daly trénovat hned, jak někoho napadly. ## Kde CNN přestávají platit **Potřebují hodně dat.** AlexNet se trénoval na 1,2 milionu obrázků. Na tisíci obrázcích se CNN od nuly nenatrénuje. Řeší se to **transfer learningem** - vezmeš síť předtrénovanou na ImageNetu, uřízneš poslední vrstvu a dotrénuješ jen ji. V praxi je to výchozí postup a **od nuly se dnes trénuje jen výjimečně**. **Nejsou invariantní vůči rotaci a měřítku.** Posun ano, otočení ne. Otočený objekt je pro CNN jiný objekt. Řeší se to [augmentací dat](MLP-a-backpropagation#problémy-při-trénování) - do trénovací množiny se přidají otočené a zvětšené varianty. **Nevidí prostorové vztahy dobře.** Obličej s prohozenýma očima a ústy může síť klidně klasifikovat jako obličej, protože všechny očekávané příznaky jsou přítomné. Pooling tu informaci o poloze zahodil úmyslně a tohle je cena za to. **Nefungují na tabulková data.** Konvoluce předpokládá, že sousední hodnoty spolu souvisejí. U sloupců v tabulce to neplatí - přeházej sloupce a nic se nezmění. Tam patří [rozhodovací stromy](Priznakove-metody#klasifikační-a-regresní-strom-cart) nebo MLP. **Nejsou to jediné dnešní řešení.** Od roku 2020 konkurují CNN **Vision Transformery**, které obrázek rozdělí na dlaždice a zpracují je pozorností. Na velkých datech je předčí, na malých ne. Pro většinu praktických úloh je předtrénovaná CNN pořád rozumná a levnější volba. ## Co se na tom nejčastěji rozbije | Příznak | Kde je problém ||---|---|| Síť se neučí vůbec | nenormalizované vstupy 0-255 || Trénovací chyba nízká, testovací vysoká | přeučení - augmentace dat, dropout ve FC vrstvách || Dojde paměť GPU | příliš velký batch nebo příliš velké mapy - přidej pooling dřív || Model funguje na rovných fotkách, na otočených ne | chybí augmentace rotací || Síť předpovídá pořád tutéž třídu | příliš velké `η`, nebo silně nevyvážená data || Na malém datasetu je výsledek náhodný | trénuješ od nuly - použij transfer learning || Rozměry nesedí mezi Conv a FC | zapomenuté zploštění (flatten) map příznaků | ## Co si odnést **Filtr se naučí jednou a použije všude.** To je celá úspora parametrů. **Konvoluce dělá extrakci příznaků, FC vrstvy klasifikaci.** CNN se učí obojí naráz. **Mělké vrstvy najdou hrany, hluboké objekty.** Hierarchie vznikne sama, nikdo ji nepředepisuje. **Pooling přidává invarianci vůči posunu a šetří paměť.** Zahodí za to informaci o přesné poloze. **Rozměry jdou z velkých a mělkých na malé a hluboké.** **Trénování je obyčejný backpropagation**, gradienty sdílených vah se jen sečtou přes pozice. **Bez hodně dat použij transfer learning.** Od nuly se dnes trénuje výjimečně. ## Kam dál - **[MLP a backpropagation](MLP-a-backpropagation)** - trénovací algoritmus, který CNN používá beze změny- **[Příznakové metody](Priznakove-metody)** - co CNN nahradila a proč se to dřív dělalo ručně- **[Rekurentní sítě a LSTM](Rekurentni-site-a-LSTM)** - druhá specializovaná architektura, tentokrát pro sekvence- **[Hry a herní strom](Hry-a-herni-strom)** - CNN jako náhrada ohodnocovací funkce v AlphaGo- **[Nástroje pro UI](Nastroje-pro-UI)** - PyTorch a Keras, ve kterých se to píše