---
# System prepended metadata

title: ML 5. AI ve zpracování obrazu
tags: [Specializace]

---

# ML 5. Umělá inteligence ve zpracování obrazu

Formování obrazu (PSF, OTF, vzorkování). Klasifikace obrazu (VGGNet, GoogLeNet, ResNet, SENet). Detekce objektů (R-CNN, Fast R-CNN, Faster R-CNN, YOLO). Segmentace obrazu (FCN, UNet, Mask R-CNN). Podmíněné a nepodmíněné generativní modely (autoregresivní modely, VAEs, GANs). Modely založené na konvolučních sítích a transformerech (attention, CNN vs. ViT)


## Formování obrazu

Obraz = funkce ze souřadnic do intenzit



* spojitý obraz: $ℝ^m → ℝ^c$
* diskrétní obraz: $ℤ^𝑚 → ℝ^c$
* digitální obraz: $ℤ^𝑚 → ℤ^c$

m je počet dimenzí, například 1 pro audio signál, 2 pro obrázek

c je počet kanálů, např. 3 pro RGB, 1 pro grayscale

Zobrazovací systém (mikroskop, kamera, rentgen, …) zachycuje scénu do digitálního obrazu

Prvně se scéna zobrazí na “Image plane”, poté se vzorkováním a kvantizací převede na digitální obraz


### PSF - Point Spread Function (Rozptylová funkce)

Rozptylová funkce popisuje, jak zobrazovací systém (kamera, …) zobrazí bodový zdroj světla na vstupu do obrazu na výstup (**impulse response**). Samotnou scénou se už nebudeme zabývat a zobrazovací systém budeme brát že bere na vstup obraz (tzn. funkci) a jiný obraz dává na výstup (jinou funkci).

Rozptylová funkce může být obecně komplikovaná, ale velké množství zobrazovacích systémů lze dostatečně přesně modelovat jako **linear shift-invariant system (LSI)**, tzn:


* rozptylová funkce nezávisí na poloze (shift invariant), tzn:
	$LSI(T(g)) = T(LSI(g))$
* rozptylová funkce je lineární, tzn:
    * kombinace dvou obrazů na vstupu a poté zobrazit je jako zobrazit každý zvlášť a pak je zkombinovat: \
$LSI(g1 + g2) = LSI(g1) + LSI(g2)$
    * zesílení signálu na vstupu zesílí signál na výstupu \
$LSI(n * g) = n * LSI(g)$

$g, g1, g2$ jsou obrazy, $n$ je skalár a $T$ je translation operátor (posunutí)

Pro LSI je rozptylová funkce jednodušší (protože odpadá hromada parametrů?) a celý zobrazovací systém lze vyjádřit jako **konvoluci**

Klasický příklad rozptylové funkce (PSF) je gaussovský noise (rozostření):


<table>
  <tr>
   <td>
       
   ![image36](https://hackmd.io/_uploads/BJVbUxoE0.png)

       
kernel pro gaussovské rozostření
   </td>
   <td>

   ![image20](https://hackmd.io/_uploads/Sk6fUgoV0.png)

příklad
   </td>
  </tr>
</table>


Ukázka ze slidů, kde zobrazovací systém každý bod na vstupu zobrazí na “šmouhu” ve tvaru PSF


![image37](https://hackmd.io/_uploads/HyJHUxoV0.png)




### Konvoluce, Vzájemná korelace (Cross-corelation)

není přímo v otázce, ale bez toho zbytek nepůjde :D

![image35](https://hackmd.io/_uploads/ry0D8gjVC.png)



Spojitá varianta je prakticky stejná, ale má tam integrály místo sum

Konvoluce je operátor:



* lineární
    * => zvýšení intenzity obrazu na vstupu přímo zvýší intenzitu na výstupu
    * => 2 obrazy můžeme sečíst a pak konvolutit, nebo prvně konvolutit a pak sečíst a dostaneme stejný výsledek
* ekvivariantní k posunu (translation equivariance)
    * => pokud posuneme něco na vstupu tak se posune zobrazení té věci na výstupu

Využití:



* hledání vzorů
* detekce hran, blobů, rohů, textur
* rozmázání, low-pass filter (denoising)
* CNN


### OTF - Optical Transfer Function

= Fourierova transformace rozptylové funkce (point spread funkce)

* charakterizuje frekvence, které se skrz zobrazovací systém přenesou
* ve skutečných zobrazovacích systémech je konečná
* nejvyšší přenesená frekvence se nazývá cut-off frekvence

 

Convolution theorem:



![image18](https://hackmd.io/_uploads/HJ5Y8giNA.png)




### Vzorkování

= diskretizace vstupního signálu (osa x pro 1D signál)

fundamentální teorie: **Nyquistův–Shannonův vzorkovací teorém**



* dává do spojitosti signály se spojitým časem a diskrétním časem
* v audiu mluvíme o diskretizaci na časové ose, v obrazu jde o 2 prostorové souřadnice x, y
* pro jednoduchost tu mluvíme o 1D signálu a časové ose

Pokud je spojitá funkce f(x) složená pouze z frekvencí nižších než B, potom je bezeztrátově a jednoznačně určena funkčními hodnotami vzorkovanými pravidelně v kratším intervalu než 1/(2B).

Pozorování:



* vysoké frekvence v signálu jsou obvykle šum a nemají význam
* senzory (příp. lidské ucho, atd.) mívají maximální frekvenci (cut-off frekvenci) a vyšší neumí rozlišit

Důsledky a význam **Nyquistova-Shannonova vzorkovacího teorému**:



* signál (audio, obraz,…) se spojitou časovou umíme “dokonale” zrekonstruovat pokud ho navzorkujeme dostatečně časo
* “dokonale” = do libovolné přesnosti, tzn. libovolně vysoké frekvence \
zejména do cut-off frekcence zobrazovacího systému (např. lidského ucha) \
nebo do frekvence, od které se dá všechno v signálu považovat za šum

Omezení:



* Nyquistův–Shannonův vzorkovací teorém mluví o diskretizaci časové osy, ne o amplitudě
* diskretizace amplitudy se nazývá kvantizace a podobný teorém nemá?


## Klasifikace obrazu



* dnes obvykle pomocí strojového učení
* hluboké neuronové sítě


### VGGNet


Hlavní nápad:


* několik po sobě jdoucích 3x3 konvolucí (a aktivačních fcí) má méně parametrů a více nelinearity než jedna velká konvoluce (např. 7x7) při stejném efektivním receptivním fieldu
* => nahradíme všechny konvoluce více 3x3 konvolucema

![image23](https://hackmd.io/_uploads/Syka8xjVC.png)


### GoogLeNet

Hlavní nápady:



* Zpochybnění toho, že 3x3 konvoluce jsou optimální, nebo že kterákoli jiná konkrétní velikost je optimální
* Můžeme nechat v neuronce víc velikostí naráz paralelně
    * => inception blok - obrázek níže
    * velké konvoluční filtry na hodně kanálech potřebují velké množství parametrů
        * můžeme redukovat počet vstupních kanálu pomocí 1x1 konvoluce
        * GoogLeNet 1x1 konvoluce zpopularizoval
* Odstraníme finální FC vrstvy na konci, protože mají velkou dimenzi:
    * (WxHxC) x FC_dim, například 7x7x512 x 4096 = 100M parametrů
    * většina parametrů je tam, což intuitivně nedává moc smysl
    * nahradíme je za globální avg pooling který srazí (WxHxC) -> (1x1xC)
* snaha o vyřešení vanishing gradientu
    * do třetiny a dvou třetin celé CNN přidáme pomocné vedlejší klasifikační hlavy
    * při tréningu počítáme loss na všech 3 klasifikačních hlavách
    * po tréningu pomocné hlavy odstřihneme

![image32](https://hackmd.io/_uploads/S1RcPgsNC.png)


žluté bloky jsou bottlenecky, které snižují dimenzi a tím snižují počet parametrů které jsou potřeba ve vrstvě která na ně navazuje

Celková architektura:


![image28](https://hackmd.io/_uploads/S1RUvls40.png)



### ResNet

Hlavní myšlenky:



* Hluboké sítě se nechtějí učit a jsou horší než mělké
    * kvůli vanishing gradientu
    * potřebujeme vyřešit
* řešení:
    * Residuální bloky jsou all you need!

![image9](https://hackmd.io/_uploads/ryDTves4R.png)


ResNet je potom jednoduchá architektura:



* za sebou naskládané residuální bloky s 3x3 konvolucí, ReLU
* buď se počet kanálů a velikost featur map nemění
* nebo se zdvojnásobí počet kanálů a redukuje výška a šířka na polovinu
* na konci global pooling a 1 FC vrstva pro klasifikaci
* basically gigachad v roce 2016


### SENet



* snaží se potlačit nepodstatné feature mapy a vyzdvihnout ty důležité
* kompatibilní s jinými architekturami
* stači do architektury vložit squeeze-and-excitation blok (SE blok):

![image29](https://hackmd.io/_uploads/rJMADgsEA.png)

- SENet dynamicky zesiluje/zeslabuje feature mapy 

## Detekce Objektů


### R-CNN



* historický a naivní přístup k detekci objektů
* algoritmicky generujeme kandidáty (region proposals) na vstupním obrázku
* CNN potom pro každý region proposal:
    * klasifikuje třídu - jaká třída nebo NIC
    * predikuje regresí t_x, t_y, t_h, t_w - korekce bounding boxu


![image30](https://hackmd.io/_uploads/Sysedei40.png)


Problém R-CNN je ve výpočetní náročnosti - pro 2k region proposalů potřebujeme 2k forward průchodů CNN


### Fast R-CNN


* zefektivnění R-CNN
* Používáme stejný region proposal algoritmus
* ale vyřezáváme regiony až na výstupu backbone CNN: 

![image10](https://hackmd.io/_uploads/Skx7_xsER.png)



Drobný problém:



* feature mapy mají nižší rozlišení než originální obraz
* takže proposal region je potřeba rozumně namapovat na feature mapy
* řešení:
    * ROI Pool - snap to closest pixels in feature maps
    * ROI Align - bilineární interpolací zarovnat
    * skrz obě operace se dá backpropagovat

<table>
  <tr>
   <td>
       
![image3](https://hackmd.io/_uploads/H14wOxoVA.png)

    ROI Pool
   </td>
   <td>
       
![image17](https://hackmd.io/_uploads/r1frdxiNR.png)
       
    ROI Align
   </td>
  </tr>
</table>



### Faster R-CNN

Motivace:

* hand-coded region proposal metody:
    * nejsou kvalitní
    * jsou pomalý (běží na CPU)
* chceme je naučit a mít součástí NN architektury

Architektura:


* na začátku je backbone steně jako Fast R-CNN
* potom následuje region proposal network (RPN)
* předdefinujeme si několik tvarů a velikostí (templaty) anchor boxů
* RPN predikuje pro každý pixel pro všech K templaty anchor boxů
    * odpovídá tento pixel středu a tento anchor boxem ohraničení nějakého objektu?
    = pro každá píxel K binárních klasifikací 
    * jak by se musel upravit anchor box template aby přesně ohraničil objekt? \
= pro každý pixel K regresí 4 floaty
    * pro HxWxC feature mapu a K anchor box template má výstup shape \
HxWx(K+4K)
* top kandidáti se potom pošlou do per-region CNN která je stejná jako v Fast R-CNN

![image12](https://hackmd.io/_uploads/SJzaOls4R.png)



### YOLO (You Only Look Once)

pozorování:



* region propsal network a per-region network působí duplicitně (říká se tomu two-stage detector)

řešení:



* zjednoduššíme architekturu
* spojíme region proposal network a per-region network (single stage detector)
* proženeme vstup skrz backbone a pak
* 1 CNN která pro každý pixel a K anchor box šablon predikuje:
    * odpovídá tento pixel středu a tento anchor boxem ohraničení nějakého objektu, a jakého?
    * jak se tento anchor box template musí upravit?
* vstupní dimenze po backbone:
    * HxWxC
* výstupní dimenze:
    * klasifikační hlava: H x W x K x (N+1)
    * regresní hlava: H x W x 4K x N


## Segmentace obrazu



* rozdělení obrazů do regionů odpovídající (sémantickým) třídám, jako obloha, pes, tráva
* lze přeformulovat jako klasifikace každého pixelu do N tříd
* přirozeně lze řešit konvolučníma sítěma


### FCN - Fully Convolutional Network



* naivní CNN architektura
* Konvoluční vrstvy které nemění spatial dimenze

![image31](https://hackmd.io/_uploads/Hyyktei4C.png)


Problém:



* výpočetně náročné pro jakékoli netriviální množství latentních feature map protože konvoluce na plném rozlišení jsou drahé

Zefektivnění:



* snižovat rozlišení se zvyšujícím počtem kanálů
* symetricky potom zrekonstruovat stejnou dimenzi jako originální input


![image25](https://hackmd.io/_uploads/SyX-tgo4C.png)



Potřebujeme způsob jak zvýšit spatial dimenzi feature map

Příklady upsampling vrstev bez učených parametrů:


<table>
  <tr>
   <td>
       
![image33](https://hackmd.io/_uploads/ByRzYgjNC.png)

   </td>
   <td>

![image11](https://hackmd.io/_uploads/HyFmFxsN0.png)

   </td>
  </tr>
  <tr>
   <td colspan="2" >
       
![image2](https://hackmd.io/_uploads/BJ5SYxjNR.png)

   </td>
  </tr>
</table>


Učenou verze upsamplingu lze naimplementovat pomocí transposed konvoluce

Intuitivní představa je že Transposed konvoluce “rozkopírovává” input pronásobený kernelem.

Nejlépe je to vidět na variantě kde stride = velikost kernelu:

![image24](https://hackmd.io/_uploads/r1dnteo4C.png)

transposed konvoluce s 2x2 maticí plnou jedniček a stridem 2 odpovídá nearest-neighbor upsamplingu


Takhle vypadá varianta se stridem 1:

![image7](https://hackmd.io/_uploads/BkmiFli4C.png)




### UNet

Problémy, které chceme vyřešit:



* FCN která zachovává spacial dimenzi je neefektivní
* FCN která má uprostřed malou spacial dimenzi má “informační bottleneck”
    * = hodně informace se může ztratit v prostřední reprezentaci

Řešení:



* přidáme skip connections mezi vrstvami se stejnou spatial dimenzí

![image34](https://hackmd.io/_uploads/S1IpFeiE0.png)



### Mask R-CNN

= adaptace Faster R-CNN pro instance segmentaci



* kromě bounding boxu chceme masky pro každý objekt
* úprava achitektury je jednoduchá
* kromě klasifikace třídy a regrese pro korekci bounding boxu se na konci per-region CNN predikuje i binární maska 

![image15](https://hackmd.io/_uploads/HyW19liVR.png)



## Podmíněné a nepodmíněné generativní modely

Intuitivně:



* X jsou komplikovaná data
* Y jsou primitivní data (labely)
* P(Y)		je prior na labelech (snadno aproximujeme z četností výskytu)
* P(Y | X)	aproximují diskriminativní modely (klasifikátory)
* P(X)		aproximují nepodmíněné generativní modely
* P(X | Y)	aproximují podmíněné generativní model

Bayes rule je dává do souvislosti:

![image6](https://hackmd.io/_uploads/Bk91cxi4A.png)



### Autoregresivní modely



* explicitně modelují hustotu p(x)
    * tzn model nám na vstup x umí vrátit skalár který odhaduje jak je x pravděpodobný
    * cíl je natrénovat model (odhadnout parametry w), který maximalizuje likelihood dat:

    ![image21](https://hackmd.io/_uploads/Hkvh5xsER.png)



Autoregrese:



* předpokládáme že x se skládá z “částí” x_i
* pomocí chain rule vyjádříme p(X) = p(X_1) * p(X_2 | X_1) * p(X_3 | X_1, X_2) * …
* autoregresivní model potom modeluje p(X_i | X_0 … X_i-1)
* při generování x postupujeme od x_1 po x_n
    * každý predikovaný prvek x_i strčíme zpět do modelu a predikujeme následující

Pixel RNN:


* u grayscale by části x_i byly jednotlivé pixely
* u RGB má máme tři části pro každý pixel
* generování každého pixelu je podmíněné všemi pixely nalevo a nahoře pomocí hidden statu RNN
* predikce pixelu je natřikrát, pro každý kanál softmax 0 - 256 
    ![image26](https://hackmd.io/_uploads/HJ9RqxsN0.png)

Pixel CNN:



* podobné Pixel RNN, ale používá konvoluce na lokálním okolí místo RNN hidden stavu, který se musí počítat při tréningu úplně sekvenčně
* generování je pořád extrémně pomalé

    
![image1](https://hackmd.io/_uploads/rJ2Jsei4A.png)



### VAE - Variational Autoencoder

klasické autoencoder:



* 2 části, encoder a decoder
* trénujeme:
    * z = enc(x)
    * x’ = dec(z)
    * minimize loss(x, x’)
    * **z** se nazývá latentní vektor
        * dim z &lt; dim x, jinak by se encoder mohl naučit prostě kopírovat **x** do **x’**
* jak generovat?
    * a pak vyrobit nová data jako:  x’ = dec(random z)
    * ale my nevíme nic o tom jakou distribuci má **z** 
    * takže jsme namydlení

Variační autoencoder:



* snaží se vynutit konkrétní distribuci na **z**
* potom z ní můžeme samplovat a generovat nová data pomocí decoderu
* enc(x) nově predikuje distribuci p(z | x)
    * rodinu distribucí si vybereme předem
    * a encoder predikuje pouze parametry
    * obvyklá volba je gausián s diagonální kovarianční maticí
        * pak encoder predikuje pouze n průměrů a n rozptylů (nebo std)
    * z se potom nasampluje z téhle distribuce z ~ enc(x)
* analogicky, decoder predikuje distribuci p(x’ | z)
    * ale někde se používá i deterministický encoder, který přímo predikuje jedno konkrétní x’
    * obvyklá volba je opět gausián s diagonální kovarianční maticí

Loss funkce pro VAE:



* skládá se ze 2 částí: reconstruction loss - regularizace
* reconstruction loss:
    * snaží se o aby VAE přiřazoval velkou pravděpodobnost examplum z datasetu
* regularizace:
    * snaží se vynutit, aby encoder predikoval distribuce pro z blízké **prior distribuci**
    * pro gaussiány s kovarianční maticí bude prior, že průměry = 1 a rozptyly = 1
    * díky tomu můžeme pak generovat nová data:
        * samplovat z ~ prior
        * nová data x’ ~ dec(z)

Formálně:

* enc(x)      … predikovaná distribuce přes **z**
* dec(z)      … predikovaná distribuce přes **x’**
* dec(x | z) … predikovaná pravděpodobnost x za podmínky **z**
* Celková loss:

$$ \mathbb{E}_{x \sim D, z \sim \text{enc}(x)} \log \text{dec}(x \mid z) - \mathbb{E}_{x \sim D} \text{KL} \left( \text{enc}(x) \parallel Z_{\text{prior}} \right) $$

* první části taky říkáme Variational Lower Bound (ELBO)
    * není to přímo pravděpodobnost kterou autoencoder přiřazuje x protože místo toho abychom integrovali (sumovali) přes všechny možný z, prostě náhodně samplujeme
    * jenže integrovat přes všechny **z** je drahé, samplovat ze **z** je levné
    * probabilita **x** given jedno **z** je je nižší než suma probabilit pro **x** given z přes všechny **z**
    * => to je ta “lower bound”
    * předpoklad je, že když maximalizujeme lower bound funkce F, tak tím nakonec maximalizujeme i funkci F, protože jí “zespodu vytláčíme” :D

V případě, že omezujeme Z~enc(x) a X’~dec(x) na gausiány s kovarianční maticí, tak:



* KL(z || Z_prior) má closed-form řešení (vzoreček)
* dec(x | z) je dosazení **x** do hustoty gausiánu, kterou decoder predikuje: dec(z)

Repametrizační trik



* my samplujeme latentní vektory **z** uprostřed forward průchodu VAE
* potřebujeme zajistit aby skrz samplování šlo backpropagovat
* → reperametrizační trik:
* přeformulujeme jak vzniká latentní vektor z
    * místo originálního:
        * z ~ enc(x)
    * použijeme:
        * means, variances := enc(x)
        * eps ~ N(0, 1)
        * z = means + variances * eps
    * díky tomu je **z** diferencovatelné vzhledem k **means** a **variances**, a tím k params encoderu


![image16](https://hackmd.io/_uploads/HkNVixiVR.png)


### GAN - Generativní Adversariální Síť

![image4](https://hackmd.io/_uploads/SyiIsljNC.png)




* GAN modeluje p(x) implicitně
    * můžeme samplovat z aproximace datové distribuce 
    * ale neodhadujeme p(x)
    * D(x) není aproximace p(x) !!!
        * D(x) nemodeluje hustotu (nebo pravděpodobnost) x
        * a rozhodně se neitegruje (nesčítá) do 1 přes všechny možné vstupy
* G a D hrají adversariální hru
    * D se snaží rozpoznat fake data
    * G se snaží oblafnout D
    * Účelová funkce je založená na binární cross-entropii
        * vysvětlení z formely: [Binary Cross-entropy](https://www.notion.so/GAN-formela-7bbfd09528a343dcb429a8f150dce7e0?pvs=4#10c2504b25fe46e899b5014d064ef83a)

GAN účelová funkce:

![image13](https://hackmd.io/_uploads/H1GdjljNC.png)



Řešení hry:



* (předpokládáme bezmeznou expresivní sílu D i G)
* pro fixní G, existuje unikátní globálně optimální D
* za předpokladu, že D bude optimální protihráč, existuje globálně optimální G
* → tzn, existuje globální a unikátní Nashovo ekvilibrium
* v ekvilibriu:
    * G dokonale modeluje datovou distribuci
    * D neumí rozpoznat fakes a reaálné data
    * ani jeden si sám nemůže přilepšit (z definice ekvilibria)

tréning konverguje do ekvilibria, za divokých teorietických předpokladů



* NNs mají nekonečnou expresivní sílu
* máme nekonečně dat
* po každým updatu G, děláme nekonečně mnoho updatů pro D
* …

Praktické problémy:



* nedostatečné gradienty
    * pro D je snadné poznat fakes, takže posílá do G malý grady
    * (= G neumí žádnou malou změnou rozumě ovlivnit výstup D)
* Mode collapse:
    * G najde slabinu v D and exploituje ho
    * ⇒ G produkuje nediverzní popřípadě degenerovaný samply 
* oscilace:
    * tréning mode-collapsne
    * D se naučí rozpoznávat fakes z toho kolapsu, ale zapomene něco z dřívějšího tréningu
        * G najde novou slabinu → nový mode collapse → opakuje se dokola


## Transformer


### Self-Attention

parametry:



* query matice W_Q:		D x D_q
* key matice W_K:		D x D_q
* value matice W_V:		D x D_v

vstup = posloupnost vektorů



* coby matice X:		N x D
* může být třeba:
    * posloupnost slov 
    * patche obrázku

výstup = posloupnost vektorů:



* coby matice Y: 		N x D_v

Výpočet:



* Q = X @ W_Q			
shape N x D_q
* K = X @ W_K			
shape N x D_q	
* V = X @ W_V			
shape N x D_v
* E = Q @ K.T / sqrt(D_q)	
shape N x N
* A = softmax(E, row-wise)	
shape N x N,  každý řádek se sčítá do jedné
* Y = A @ V			
shape N x D_v

Y jsou nové reprezentace vstupu X, ve kterém se jednotlivé vektory “vzájemně obohatili” o kontext

Vizualizace výpočtu (ale nesedí tu pořadí řádky/sloupce s formální notací)

![image5](https://hackmd.io/_uploads/Bk6KoxiNC.png)



### Cross-Attention

= rozšíření self-attention

Nově máme 2 vstupy:



* jeden, který obohacujeme - Src
* druhý, pomocí kterého obohacujeme - Tgt
* Src a Tgt mohou mít různé dimenze, matice W_* nám to “zarovnají”

Změny:



* queries se počítají ze Src
* keys a values se počítají z Tgt
* Y jsou na konci výpočtu nové reprezentace pro Tgt

Využití:



* flexibilní varianta attention
* umožňuje kombinovat více vstupů nebo dokonce modalit
* příklady:
    * similarita textu a obrázku
    * popisování obrázku
    * audio transkript
    * strojový překlad
    * …


### Multi-Head Attention

= zapojení několika paralelních attention vrstev vedle sebe

Výstupy se concatenují a pak pomocí jedné učené lineární vrstvy zobrazí na požadovanou dimenzi


### Poziční kódování

Není součástí otázky explicitně, ale byla by asi chyba o něm nic nevědet, když je v otázce transformer

Pozorování:



* attention vrstva je “permutation equivariant”
* tzn, pokud přemícháme pořadí vektorů na vstupu:
    * přemíchá se pořadí vektorů na výstupu
    * ale jejich obsah bude stejný
* → attention vrstvy nemají (a teedy ani nepoužívají) informaci o tom:
    * kde ve vstupu se vektor nachází
    * jak jsou od sebe ve vstupu daleko
* to je důležité protože na pořadí a relativních vzdálenostech ve vstupu záleží
    * například pořadí slov ve větě mění význam
    * pokud máme patch v obrázku obsahující červené kalhoty, patch nad ním má modré tričko a patch 10 bloků daleko obsahuje zelené triko, lze usoudit že osoba s červenými kalhotami má modré tričko a patch se zeleným je irelevantní

Poziční kódování přidává do vstupu informaci o tom, kde se jednotlivé části vstupu nachází

Populární typy:



* naučené
    * máme učitelnou embedding matici E dimenze (N x D_model)
    * k i-té části vstupu se přičte (popř. concatenuje) poziční kódování E[i]
    * parametry E se trénují souběžně s ostatními parametry modelu
* relativní
    * nemění reprezentace vektorů
    * ovlivňuje pouze výpočet attention
    * předpokládá že je důležitá relativní vzdálenost částí a ne jejich absolutní pozice ve vstupu
        ![image27](https://hackmd.io/_uploads/Hy7hsxoEC.png)


* sinusoidní
    * používá stejnou matici E jako naučené, ale nemá trénovatelné parametry
    * má dobré vlastnosti, například:
        * attention hlava se může naučit attendovat o n pozic dopředu a dozadu
    * matice E vypadá asi takhle:
    
        ![image22](https://hackmd.io/_uploads/BJxaogiE0.png)


    


### Transformer Encoder

= model, který využívá:



* poziční kódování
* Bloky složené z:
    * attention
    * MLP
    * residuálních spojení
    * normalizace

![image19](https://hackmd.io/_uploads/H1oPqxiE0.png)



### Vision Transformer



![image14](https://hackmd.io/_uploads/SybU9xjN0.png)



Lineární vrstvy v transformer MLP části lze chápat jako konvoluce se kernelem velikost 1:



* protože jde o lineární vrstvu, která se aplikuje na každou pozici samostatně