--- title: "DLIM: Reseaux neuronaux convolutifs" date: 2021-11-08 14:00 categories: [Image S9, TVID] tags: [Image, S9, TVID] math: true --- Lien de la [note Hackmd](https://hackmd.io/@lemasymasa/B1-YkiLwt) # Un reseau de neurones convolutif ![](https://i.imgur.com/Gusjhh3.png) ## Le but est d'extraire les caracteristiques ![](https://i.imgur.com/HXXmFvh.jpg) ## Les formules de convolution Continue 1D: $$ (f * g)(x) = \int_{-\infty}^{+\infty}f(x-t)g(t)dt = \int_{-\infty}^{+\infty} f(t)g(x-t)dt $$ Discrete 2D: $$ (f*\omega)(x,y) = \sum_{dx=-a}^a\sum_{dy=-b}^b\omega(a + dx, b + dy)f(x + dx, y+dy) $$ $f$ est l'aimeg, $\omega$ le noyau, son support est $[-a,a]\times[-b, b]$ Exemple de noyaux $\omega$ (WP Noyau_(traitement_d'image)): ![](https://i.imgur.com/X1325di.png) # Conv2D ```python x = kl.Conv2D(filters = 4, kernel_size=(5, 5))(x) ``` L'image d'entree a 3 canaux -> chaque filtre a $5\times5\times 3 + 1$ poids L'image de sortie a 4 canaux, elle pert 4 pixels dans chaque direction ## En details + stride + padding = 'same' ```python Conv2D(filters = 2, kernel_size = (3, 3), stride = (2, 2), padding = 'same') ``` ![](https://i.imgur.com/do3CIuS.gif) - Stride: une facon de reduire la taille d'une image - padding = 'same': la sortie a la meme taille ## Convolution a trous En anglais: *atrous convolution* ```python= Conv2D(32, kernel_size=3, dilatation_rate=(2, 2)) ``` ![](https://i.imgur.com/yDxMfxd.gif) :::success Couvre la meme surface qu'un noyau $5\times 5$, ou que $2$ convolutions $3\times 3$ a la suite, mais pour un cout moins cher (en poids) ::: Ne reduit pas la taille de l'image (padding = `same`) ## Convolution separee - **spatiale**: une conv $2D\to1$ conv. $1D$ - **profondeur**: $N$ conv $2D$ sur $M$ couches $\to$ $M$ conv $2D$ puis $N$ conv $1D$ **Convolution separeee spatiale** ![](https://i.imgur.com/CiDOpZd.png) En pratique on fait: ![](https://i.imgur.com/StH7rLK.png) **Conv separee en profondeur** ```python= kl.SeparableConv2D ``` Ici 3 couches: - $3$ conv $2D$ + $4$ conv $1D$ - $4$ couches en sortie Gain de calcul important perte de representation $\to$ utilise [MobileNet](https://arxiv.org/abs/1704.04861) ## La convolution transposee (ou deconvolution) :::info *Convolution*: **concentre** en un pixel un bloc de pixel (fois un noyau) ::: :::info *Conv transposee*: **distribue** un pixel (fois un noyau) a un bloc de pixel ::: ![](https://i.imgur.com/RBr2eiZ.png) Mathematiquement les deux sont des convolutions mais la conv. transposee a pour but de simuler l'operation inverse de la conv $$ \begin{aligned} \text{propagation conv transposee} &\leftrightarrow \text{retro-propagation conv}\\ \text{retro-propagation conv. transposee} &\leftrightarrow\text{propagation conv.} \end{aligned} $$ ## Trucs d'architecture :::danger **Pooling** ```python= kl.MaxPooling2d(pool_size = (2, 2)) ``` ![](https://i.imgur.com/jiVaceA.png) Si on veut augmenter le nombre de couches il faut diminuer la taille de l'image sinon BOOM On veut une vision multi-echelle il faut diminuer la taille de l'image + ponts. L'inverse du *pooling* est kl ::: :::danger **Ponts** La grande astuce de ResNet qui leur a permis de tout gagner ![](https://i.imgur.com/geGwGQT.png) ![](https://i.imgur.com/gsMUa9w.png) ![](https://i.imgur.com/0JZRffW.png) - vert $\to$ - rouge $\leftarrow$ Prog. et retro-prog. Lors de la retropropagation l'erreur prend le pont et les convolutions $\to$ les premieres couches sont corrigees ::: :::danger **Dropout ou BatchNormalization** Pas besoin de dropout si BatchNormalization ![](https://i.imgur.com/LKglSCh.png) Evite que les poids importants en bloquent d'autres ![](https://i.imgur.com/a6ZPQiZ.png) Apres convolution Avant fonction d'activation Reduit le besoin de normaliser les donnees ::: # Types de problemes en vision Semantic segmentation ![](https://i.imgur.com/T8Yjc0Z.png) ![](https://i.imgur.com/Fe8XbHm.jpg) - Classification - Classification + localisation - Object detection - Instance segmentation - Celle qu'on va faire ## U-net (2015) Separation semantique d'images medicales ![](https://i.imgur.com/TIXfKwb.png) Multi-echelle *Notre projet aujourd'hui !* Copy & crops: ce sont des PONTS - Ca sert a faire des concatenations # Fonctions d'erreur pour la segmentation Si chaque image de sortie represente les pixels appartenant a la classe $k$, alors on peut finir avec un `softmax`: $y+k = e^{z_k}/\sum_{i}e^{z_i}$ - Erreur quadratique `mse`: pente douce, pas d'information d'exclusion - Entropie croisee: $E=-\sum_kt\log y_k+(1-t_k)\log(1-y_k)$ - `binary_crossentropy` avec $t_k=0$ ou $1$ - `categorical_crossentropy` avec resultats sous la forme $[0,0,..,1,..,0]$ pour indiquer la classe $k$ - `sparse_categorical_crossentropy` avec les classes indiques par des entier ```python= y_true = [[1, 2], [0, 2]] #image 2x2 with 3 categories y_pred = [[0.05, 0.95, 0], [0.1, .01, 0.8], #proba for each category [0.7, 0.2, 0.1], [0.2, 0.2, 0.6]] #for each pixel loss = keras.losses.SparseCategoricalCrossentropy() loss(y_true, y_pred).numpy() ``` :::danger **Focal loss** $$ E_{FL} = -\sum_k t_k(1-y_k)^{\gamma}+(1-t_k)(1-y_k)^{\gamma}\log(1-y_k) $$ Comme la pente du log est forte, elle favorise les cas simples a detecter. On peut ecraser la courbe de $(1-\gamma_k)$ pour aider à trouver les cas difficiles. ![](https://i.imgur.com/L6XTOML.png) ::: # Augmenter le nombre de donnees Souvent c'est bien utile, en particulier lorsqu'on manque de donnees. ![](https://i.imgur.com/7dtm6dZ.png) Parfois ca rend la tache plus difficile et ca ne marche pas. ```python= ImageDataGenerator ```