Skip to main content

Section 5.3 Réseaux récurrents et transformeur

TOOO DOO

Subsection 5.3.1 Réseaux récurrents pour les séries temporelles

Jusqu’à présent les réseaux permettant plus de traiter des problèmes de traitement du signal ou structurés en espace. Maintenant on va introduire les réseaux utilisés pour les problèmes temporels notamment pour la prédiction de la série de données temporelles.
Le problème qu’on regarde est le suivant: on a a notre disposition des données temporelles du type \((x_1,...,x_t)\) et l’ont souhaite construire la loi de probabilité suivante:
\begin{equation} \mathbb{P}(x_t\mid x_1,....,x_{t-1}), \quad \forall t>0, \quad \mbox{ ou } \quad \mathbb{E}(x_t\mid x_1,....,x_{t-1})\tag{5.8} \end{equation}
On se place donc dans cadre "non Markovien" ou on ne dépend pas que du temps précédent. On pourrait traiter cela avec un réseau classique type MPC. Dans ce cas on aurait un réseau \(f_{\theta}(x_1,...,x_{t-1})\) qui prédirait la valeur de \(x_t\text{.}\) Cependant ce réseau ne pourrait pas s’appliquer à tous les temps. En effet dans ce cas la taille de l’entrée est variable. Cette solution n’est donc pas adaptée en règle générale. Il existe plusieurs solutions pour éviter cela:
  • Le fenêtrage: on va supposer que le passé lointain compte peut et donc que notre réseau va estimer la probabilité \(\mathbb{P}(x_t\mid x_{t-1},...x_{t-m})\) dans ce cas l’entrée est fixe et on peut utiliser un réseau classique de type MPC.
  • Le modèle lalent: on va construire une variable supplémentaire qui va porté au cours du temps de l’information issue des états précédents. Si on nomme cet état caché: \(h_t\) on chercher a construire la loi \(\mathbb{P}(x_t\mid x_{t-1},h_{t-1})\text{.}\)
Il faut savoir qu’il existe un autre problème d’apprentissage sur les séquences. On peut aussi avoir envie d’estimer non pas la loi conditionnelle (5.8) mais la loi jointe:
\begin{equation} \mathbb{P}(x_1,....,x_{t},....,x_T)\tag{5.9} \end{equation}
Ce genre de probabilité peut être estimée à l’aide des probabilités conditionnelles comme le montre la formule:
\begin{equation*} P\left(x_1, \ldots, x_T\right)=P\left(x_1\right) \prod_{t=2}^T P\left(x_t \mid x_{t-1}, \ldots, x_1\right) \end{equation*}
Les réseaux classiques pour le problème (5.8) utilise l’approche de type latent.
Un réseau récurrent a pour but de transformer une séquence \((x_1,...,x_n)\) en une autre séquence \((y_1,...,y_n)\) en pouvant traiter de séquence de taille variable. Pour tenir compte du passé, on utilise en pratique les modèles latents.

Définition 5.46. Réseau récurrent.

On se donne des séquences d’entrée \((x_1,...,x_n)\) et de sortie \((y_1,...,y_n)\text{.}\) Un réseau récurrent est un réseau de neurones qui va approcher une fonction de la forme:
\begin{equation*} y_t = f_{\theta}(x_t,h_{t-1}) \end{equation*}
avec \(x_t\) un élément de notre série temporelle d’entrée, \(h_t\) un vecteur latent et \(y_t\) un élément de notre série de sortie.
Si vous voulez faire de la prédiction de série temporelle comme pour le problème (5.8) avec il suffit de prendre comme valeur de référence pour \(y_t\) l’élément suivant de la séquence \(x_{t+1}\text{.}\)

Définition 5.47. Réseau recurrent de Elman.

Soit une entrée \(x_t \in\mathbb{R}^{d_i}\) et une sortie \(y_t \in\mathbb{R}^{d_o}\text{.}\) Un réseau de Elman est un réseau récurrent à deux couches:
\begin{equation*} \begin{cases} h_t=\sigma_h\left(W_h x_t+U_h h_{t-1}+b_h\right) \\ y_t=\sigma_y\left(W_y h_t+b_y\right) \end{cases} \end{equation*}
avec \(d_h\) la dimension des états latents, avec des matrices de poids \(W_h \in\mathcal{M}_{d_h,d_i}\text{,}\) \(U_h \in\mathcal{M}_{d_h,d_h}\) et \(W_y \in\mathcal{M}_{d_o,d_h}\text{,}\) des biais \(b_h \in \mathbb{R}^{d_h},b_y \in \mathbb{R}^{d_o}\) et \(\sigma_h()\text{,}\) \(\sigma_y()\) des fonctions d’activations.

Définition 5.48. Réseau recurred de Jordan.

Soit une entrée \(x_t \in\mathbb{R}^{d_i}\) et une sortie \(y_t \in\mathbb{R}^{d_o}\text{.}\) Un réseau de Elman est un réseau récurrent à deux couches:
\begin{equation*} \begin{cases} h_t=\sigma_h\left(W_h x_t+U_h y_{t-1}+b_h\right) \\ y_t=\sigma_y\left(W_y h_t+b_y\right) \end{cases} \end{equation*}
avec \(d_h\) la dimension des états latents, avec des matrices de poids \(W_h \in\mathcal{M}_{d_h,d_i}\text{,}\) \(U_h \in\mathcal{M}_{d_h,d_h}\) et \(W_y \in\mathcal{M}_{d_o,d_h}\text{,}\) des biais \(b_h \in \mathbb{R}^{d_h},b_y \in \mathbb{R}^{d_o}\) et \(\sigma_h()\text{,}\) \(\sigma_y()\) des fonctions d’activations.
De la même façon que pour le perceptron il existe des résultats d’approximation universelle de ses réseaux. Des versions profondes des réseaux récurrents peuvent être proposées.

Définition 5.49.

Un réseau récurrent profond à \(K\) couche est réseau du type:
\begin{equation*} \begin{cases} h_t^1=f_{\theta_h}(x_t,h^1_{t-1})\\ \vdots\\ h_t^k=f_{\theta_h}(x_t,h^{k-1}_{t-1})\\ \hat{y}_t=g_{\theta}(h_t^k) \end{cases} \end{equation*}
avec \(f_{\theta_h}\) une couche du type Elman par exemple.
Sur la figure Figure 5.50 on voit des exemples de réseaux récurrents simple et profond.
Figure 5.50. Exemples de réseau RNN simple et profond (Google image). Les couches sur les états latents sont en noir et les sorties en gris.
En pratique on n’utilise pas des réseaux très profonds (3, 4 couches), car les problèmes de disparition gradient qui apparaissent très vite. Maintenant, va regarder comment entraîner ses réseaux à l’aide de la méthode de rétropropagation et comprendre les problèmes de gradient même dans le cas de réseau à une seule couche.

Définition 5.51.

La fonction de coût pour les réseaux récurrents est donnée par
\begin{equation*} L(\theta_h,\theta)=\frac{1}{T} \sum_{t=1}^T \underbrace{l\left(y_t, \hat{y}_t \right)}_{E_t} \end{equation*}
avec \(T\) la taille de la série.
Les fonctions de coût locales \(l\) utilisés sont les fonctions usuelles (coût quadratique, coût entropique, etc). Maintenant on va montrer comme pour les réseaux dits "feed forward" de type MPC ou CNN qu’on peut calculer efficacement le gradient de la fonction coût par rapport aux paramètres du réseau [1.17]. On cherche donc a calculer:
\begin{equation*} \begin{aligned} \frac{\partial E_t}{\partial \theta_h} = \sum_{i=0}^T \frac{\partial l\left(y_t, \hat{y}_t\right)}{\partial \hat{y}_t} \frac{\partial \hat{y}_t}{\partial h_t}\frac{\partial h_t}{\partial h_i} \frac{\partial h_i}{\partial \theta_h} . \end{aligned} \end{equation*}
avec \(\theta_h=(W_h,U_h,b_h)\text{.}\) En appliquant encore une fois la dérivée des fonctions composées:
\begin{equation*} \frac{\partial h_t}{\partial h_i}=\left(\prod_{j=i}^t \frac{\partial h_{j+1}}{\partial h_{j}}\right) \end{equation*}
Maintenant on peut expliciter \(\frac{\partial h_{j+1}}{\partial h_{j}}\text{,}\) par un calcul simple on obtient dans le cas d’un réseau d’Elman par exemple:
\begin{equation*} \frac{\partial h_{j+1}}{\partial h_{j}}= \sigma_h^{'}\left(W_h x_{j+1}+U_h h_{j}+b_h\right)U_h \end{equation*}
par conséquent dans le calcul de nos gradients globaux on va avoir le produit:
\begin{equation*} \prod_{j=i}^t\sigma_h^{'}\left(W_h x_{j+1}+U_h h_{j}+b_h\right)U_h \end{equation*}
Ce type de quantité peut facilement s’annuler pour \(t\) grand car il suffit que l’un des termes dans le produit s’annule. De plus on peut même montrer que cela finira toujours par tendre vers zéro ou l’infini quand la série en temps est longue. En effet, si la valeur propre dominante de \(U_h\) est plus grande que 1 cela finira par exploser et si la valeur propre dominante \(U_h\) est plus petite que 1 ça finira par disparaître. Cela s’explique par le fait que le terme \(\sigma_h^{'}\left(W_h x_{j+1}+U_h h_{j}+b_h\right)\) est toujours plus petit que 1 pour les fonctions d’activation type sigmoïde ou tanh.

Subsubsection 5.3.1.1 Réseau de type LSTM

Les réseaux LSTM pour "long short time memory" ont été proposés pour régler les problèmes de disparition de gradient. L’idée est de remplacer une couche simple de RNN (qui construit l’état latent en fonction du précédent et de l’élément courant de la la séquence) par une couche un peu plus compliquée qui va avoir une mémoire à court terme et une mémoire à long terme. Dans un réseau récurrent on a une porte d’entée qui effectue une combinaison linéaire de l’état latent et de l’entrée avant d’appliquer une fonction d’activation. Dans les réseaux LTSM on utilise trois portes d’entrées qui régule le flux d’information et deux types de sorties ou états.
Définition 5.52. Cellule LTSM.
Soit un état caché \(h_t \in[-1,1]^d\) et le vecteur d’état \(c_t\in[-1,1]^d \text{.}\) Une cellule LSTM:
\begin{equation*} \begin{aligned} f_t \amp=\sigma_g\left(W_f x_t+U_f h_{t-1}+b_f\right) \\ i_t \amp=\sigma_g\left(W_i x_t+U_i h_{t-1}+b_i\right) \\ o_t \amp=\sigma_g\left(W_o x_t+U_o h_{t-1}+b_o\right) \\ \tilde{c}_t \amp=\sigma_h\left(W_c x_t+U_c h_{t-1}+b_c\right) \\ c_t \amp=f_t \odot c_{t-1}+i_t \odot \tilde{c}_t \\ h_t \amp=o_t \odot \sigma_h\left(c_t\right) \end{aligned} \end{equation*}
avec \(W_f,W_i,W_o,W_c \in \mathcal{M}_{d,d}(\mathbb{R})\) les matrices de poids, \(b_f,b_i,b_o,b_c \in \mathcal{M}_{d,d}(\mathbb{R})\) les vecteurs de poids, \(\sigma_g\) la fonction sigmoïde et \(\sigma_h\) la fonction tangente hyperbolique.
La première porte qui donne \(f_t\) est appelé porte d’oublie. Sont rôle est déterminée l’information qui doit être gardée ou non. Si la fonction sigmoïde donne un réseau proche de zéro, l’information va disparaître sinon il faut la mémoriser pour la suite. La seconde porte qui revoit \(i_t \odot \tilde{c}_t \) s’appelle la porte d’entrée elle va extraire de l’information de la donnée courante. Pour cela on prend les données courantes et l’état caché et appliquer une sigmoïde qui va déterminer quelles données sont importantes (proche de un) ou pas (proche de zéro) et le multiplier par un état \(\tilde{c}_t\) qui va normaliser les données par la tangente hyperbolique. Le produit des deux permettra donc de ne garder que les informations importantes, les autres étant quasiment remplacées par \(0\text{.}\) A partir de la on construit l’état de la cellule par composition de la porte d’oublie et de la porte de sortie par le calcul \(c_t =f_t \odot c_{t-1}+i_t \odot \tilde{c}_t\text{.}\) Le premier terme permet d’oublier certaines informations de l’état précédent. Le second ajoute ce que la cellule à juger pertinent à partir de du résultat de la porte d’entrée. La dernière porte est celle de sortie. Elle produit le nouvel état caché à partir d’une normalisation de l’état de la cellule multiplier par \(o_t\) qui détermine quelles informations garder (à l’aide de la sigmoïde).
Figure 5.53. Comparaison entre un réseau LSTM et RNN profond (Google image).
La figure Figure 5.53 montre la différence entre un réseau LSTM profond et un réseau classique RNN. On calcul le gradient de la fonction coût par rapport aux paramètres
\begin{equation*} \begin{aligned} \frac{\partial E_t}{\partial \theta_h} = \sum_{i=0}^T \frac{\partial l\left(y_t, \hat{y}_t\right)}{\partial \hat{y}_t} \frac{\partial \hat{y}_t}{\partial h_t}\frac{\partial h_t}{\partial c_t}\frac{\partial c_t}{\partial c_i}\frac{\partial c_i}{\partial \theta_h} . \end{aligned} \end{equation*}
avec \(\theta=(\theta_h,\theta_c)=(W_{f,i,o,c},U_{f,i,o,c},b_{f,i,o,c})\text{.}\) Comme précédemment
\begin{equation*} \frac{\partial c_t}{\partial c_i}=\left(\prod_{j=i}^t \frac{\partial c_{j+1}}{\partial c_{j}}\right) \end{equation*}
Et donc l’enjeu va se retrouver dans le calcul \(\frac{\partial c_{j+1}}{\partial c_{j}}\text{.}\)
On a donc
\begin{equation*} \begin{aligned} \frac{\partial c_{j+1}}{\partial c_{j}} \amp=\frac{\partial C_{j+1}}{\partial f_{j+1}} \frac{\partial f_{j+1}}{\partial h_{j}} \frac{\partial h_{j}}{\partial c_{j}}+\frac{\partial c_{j+1}}{\partial i_{j}} \frac{\partial i_{j+1}}{\partial h_{j}} \frac{\partial h_{j}}{\partial c_{j}} \\ \amp+\frac{\partial C_{j+1}}{\partial \widetilde{c}_{j+1}} \frac{\partial \widetilde{c}_{j+1}}{\partial h_{j}} \frac{\partial h_{j}}{\partial c_{j}}+\frac{\partial c_{j+1}}{\partial x_{j}} \end{aligned} \end{equation*}
ce que donne
\begin{equation*} \begin{aligned} \frac{\partial c_{j+1}}{\partial c_{j}} \amp=c_{j} \sigma^{\prime}(\cdot) W_f * o_{j} \tanh ^{\prime}\left(c_{j}\right) \\ \amp+\widetilde{c}_{j+1} \sigma^{\prime}(\cdot) W_i * o_{j} \tanh ^{\prime}\left(c_{j}\right) \\ \amp+i_{j+1} \operatorname{tanh} ^{\prime}(\cdot) W_c * o_{j} \tanh ^{\prime}\left(c_{j}\right) \\ \amp+f_{j+1} \end{aligned} \end{equation*}
Deux mécanismes vont aider à ce que le produit des gradients \(\frac{\partial c_{j+1}}{\partial c_{j}}\) ne converge pas vers zéro. D’abord notre gradient est la somme de 4 termes par conséquent pour l’annuler il faut annuler les 4 termes ce qui est nettement plus difficile donc il est difficile d’annuler ce produit \(\left(\prod_{j=i}^t \frac{\partial c_{j+1}}{\partial c_{j}}\right)\) en annulant un des termes. Évidemment comme pour les RNN on pourrait aussi avoir ce produit qui temps vers zéro ou l’infini lorsque \(t\) grand. Si on commence à converger vers zéro, il est toujours possible d’ajuster la valeur de \(f_t\) (ou des autres portes) pour qu’elles soient plus élevées afin d’amener la valeur du gradient plus proche de 1, ce qui empêche les gradients de disparaître trop rapidement.
Les bonnes propriétés de stabilité des réseaux LTSM (on peut évidemment enchaîner les couches LSTM) comme pour les réseaux RNN font de ses réseaux parmi les plus utilisés.

Subsubsection 5.3.1.2 Réseau GRU

Il existe un autre type de réseau récurrent avec des bonnes prorpriétés de stabilité. On parle du réseau GRU qui se rapproche du cas LSTM.
Définition 5.54. Cellule GRU.
Soit un état caché \(h_t \in[-1,1]^d\text{.}\) Une cellule GRU est donnée par:
\begin{equation*} \begin{aligned} Z_t \amp=\sigma_g\left(W_z x_t+U_z h_{t-1}+b_z\right) \\ R_t \amp=\sigma_g\left(W_r x_t+U_r h_{t-1}+b_r\right) \\ h_t \amp=Z_t \odot h_{t-1} + (1-Z_t)\sigma_h\left(W_h x_t+U_r (R_r \odot h_{t-1})+b_h\right) \end{aligned} \end{equation*}
avec \(W_z,W_r,W_h\in \mathcal{M}_{d,d}(\mathbb{R})\) les matrices de poids, \(b_z,b_r,b_h \in \mathcal{M}_{d,d}(\mathbb{R})\) les vecteurs de poids, \(\sigma_g\) la fonction sigmoïde et \(\sigma_h\) la fonction tangente hyperbolique.
la première porte est appelée porte de mise à jour. Son rôle est le même que la porte d’entrée du LSTM. Elle décide de la quantité d’information à garder, la ou la seconde porte ( de réinitialisation) détermine la quantité d’information a ignoré. Le nouvel état caché candidat est ensuite calculé à partir de l’information ignorée dans l’état précédent et de la donnée d’entrée. Ensuite on fait une combinaison convexe avec \(Z_t\) entre l’ancien état latent et ce nouveau candidat. En effet plus \(Z_t\) est grand plus on veut garder de l’information issue de \(x_t\) et \(h_{t-1}\) donc on utilise \(Z_t h_{t-1}\text{.}\)
Le capacité et les propriétés de stabilité des réseaux GRU sont similaires à celle des réseaux de type LSTM.

Subsection 5.3.2 Réseaux de neurones et attention

Les "tansformers" sont un type de réseaux de neurones introduits en 2017 pour le traitement du langage naturel (traduction) puis étendus au problème de traitement du signal et donc des fonctions spatiales. Afin d’expliquer les idées centrales, on va se placer dans le cadre du traitement de langage pour introduire les outils.

Subsubsection 5.3.2.1 Mécanisme d’attention

La stratégie utilisée avant les transformer pour la traduction s’appelle le modèle SeqtoSeq. Il s’agit d’un modèle qui va transformer une séquence (par exemple une phrase en français) en une autre séquence (par exemple en anglais). Si on se donne comme séquence d’entrée \((x_1,...,x_n)\) et \((y_1,...,y_n)\) comme séquence de sortie alors l’objectif est de construire la loi de probabilité:
\begin{equation*} \mathbb{P}( (y_1,...,y_n) \mid (x_1,...,x_n)) \end{equation*}
On se donne deux réseaux: l’encodeur et le décodeur. Le rôle de l’encodeur :
\begin{equation*} E: (x_1, x_2, \dots, x_n) \to c \end{equation*}
est de transformer la séquence en un vecteur \(h\) de longueur fixe (appelé vecteur de contexte) et le rôle du décodeur
\begin{equation*} D: (c,y_1, y_2, \dots, y_{t-1}) \to y_t \end{equation*}
est de prédire la suite de la séquence de sortie en utilisant les éléments précédents de la séquence et du vecteur de contexte. Ce processus est détaillé sur l’image Figure 5.55.
Figure 5.55. Exemple de Lil’Log blog.
Après le décodeur on applique un réseau dense afin d’obtenir la loi de probabilité finale. Concrètement, pour chacun des \(1 \leq k \leq K\) valeurs que pourrait prendre \(y_i\text{,}\) le réseau dense va calculer
\begin{equation*} \prod_{t = 1}^{p} \mathbb{P}(y_t = k \; \vert \; h, y_1, y_2, \dots, y_{t-1}), \end{equation*}
en appliquant un softmax dont on apprendra les poids \((\mathbf{w}_j)_{1 \leq j \leq K}\text{:}\)
\begin{equation*} \mathbb{P}(y_i = k \; \vert \; \mathbf{v}) = \operatorname{Softmax}(\mathbf{v}\cdot \mathbf{w}_k)= \frac{e^{\mathbf{v} \cdot \mathbf{w}_k}}{\sum_{j=1}^{K}e^{\mathbf{v} \cdot \mathbf{w}_j}} \end{equation*}
Ensuite on maximise le maximum de vraisemblance et cela revient a minimiser l’entropie croisée classique en classification multi-classe.
Dans un premier temps, on a beaucoup utiliser pour l’encodeur et le décodeur des réseaux de type LSTM/GRU, etc. Un problème est que, si la séquence d’entrée est longue, le fait que le vecteur de contexte soit de taille fixe fait que les informations situées à la fin de la séquence vont avoir tendance à avoir un poids trop important dans le vecteur de contexte. Le \mécanisme d’attention à pour but de régler ce problème. Plutôt que de construire un vecteur de contexte unique à partir du résultat de l’encodeur, l’idée de l’attention consiste à créer des raccourcis entre le vecteur de contexte et tous les éléments de la séquence. Les poids associés aux raccourcis sont personnalisables pour chaque élément de sortie. Comme le vecteur de contexte a accès à l’ensemble de la séquence d’entrée, nous n’avons pas à nous soucier de l’oubli. Le première exemple d’attention a été proposé dans [1.18].
Pour l’encodeur on propose d’utiliser une version bi directionnelle d’un RNN. Pour cela on écrit deux RNN qui parcourent les données dans les deux sens
\begin{equation*} \begin{cases} \overrightarrow{h}_t=\sigma_h\left(W_{\overrightarrow{h}} x_t+U_{\overrightarrow{h}} \overrightarrow{h}_{t-1}+b_{\overrightarrow{h}}\right) \\ \overleftarrow{h}_t=\sigma_h\left(W_{\overleftarrow{h}} x_t+U_{\overleftarrow{h}} \overleftarrow{h}_{t+1}+b_{\overleftarrow{h}}\right) \\ \end{cases} \end{equation*}
Ensuite on définit un état lalent comme concaténation des deux états \(h_t=[\overrightarrow{h}_t, \overrightarrow{h}_t]\text{.}\) Si, on est état dans un bi-RNN classique on utilisera l’état latent pour calculer la sortie avec la formule:
\begin{equation*} y_t= \sigma_y\left(W_y h_t+b_y\right) \end{equation*}
Maintenant revenons à notre encodeur. L’idée de l’attention est de construire notre vecteur de contexte à partir de l’ensemble des états cachés de la séquence et pas juste le dernier. Avant d’introduire cette construction qui est le coeur des méthodes d’attention on va commencer par définir rapidement le décodeur. Donc le décodeur sera un réseau récurrent classique prenant en compte le vecteur de contexte. Il sera de la forme:
\begin{equation*} s_t= f_{\theta}(s_{t-1},y_{t-1},c_t) \end{equation*}
avec \(s_t\) les états cachés du décodeur. Maintenant passons au vecteur de contexte. Pour cela on va donc propose la définition suivant
\begin{equation*} c_t= \sum_{i=1}^n\alpha_{t,i}h_i \end{equation*}
Cela revient donc a dire que le vecteur de contexte est une combinaison linéaire des états cachés de l’encodeur. Reste à définir les coefficients \(\alpha_{t,i}\text{.}\) L’idée est de construire le coefficient \(\alpha_{t,i}\) de façon à ce qu’il mesure à quel point la sortie \(y_t\) et l’entrée \(x_i\) se correspondre bien ( on parle d’alignement). Pour cela on utilise les états cachés associés à \(y_t\) et \(x_i\)
\begin{equation*} \alpha_{ij}= \frac{score(s_{t-1,h_i})}{\sum_{k=1}^n score(s_{t-1,h_k})} \end{equation*}
et le score est donné par une couche simple:
\begin{equation*} score(s_{t-1,h_i})= v_{a}^t \tanh(W_a [s_{t-1},h_i]) \end{equation*}
avec \(v_{a}^t, W_a\) des paramètres entraînables. L’ensemble des coefficients \(\alpha_{ti}\) forment une matrice qui mesure l’alignement entre tous les états cachés du décodeur et encodeur et donc entre tous les éléments des séquences. On peut l’interpréter comme une matrice de corrélation entre les éléments des deux séquences.
Figure 5.56. Exemple de matrices ’alignement issus de [1.18]
Sur l’exemple Figure 5.56 on voit des exemples de corrélations. Pour le calcul du score, il existe plusieurs définitions possibles (dans le cas de celle introduite précédemment, on parle d’attention additive). En voici plusieurs autres:
  • l’attention au contenu: \(score(s_{t-1,h_i})= cosine([s_{t-1},h_i])\text{,}\)
  • l’attention basée sur le produit scalaire: \(score(s_{t-1,h_i})= \frac{s_{t-1}^t h_i}{\sqrt{n}}\text{,}\)
  • l’attention dite générale: \(score(s_{t-1,h_i})= s_{t-1}^t W_a h_i\text{,}\) avec \(W_a\) une matrice entraînable.
  • l’intra-attention que l’ont va détailler un peu par la suite.

Subsubsection 5.3.2.2 Intra-attention et "transformer"

On va maintenant parler de certains mécanisme d’attention particulière qui sont au coeur d’une architecture de réseau très utilisée appelée "transformer". Un mécanisme d’intra-attention est un mécanisme qui met en relation différentes positions d’une même séquence afin de calculer une représentation de cette même séquence. On va donc construire une matrice de corrélation entre les éléments de la séquence.
Définition 5.57. Auto - Attention.
On se donne une entrée \(X\in \mathbb{R}^{n,d}\text{.}\) Soit \(W_Q, W_K, W_V\in \mathbb{R}^{d,d}\) des matrices de poids entraînable. On définit trois quantités:
  • La requète: \(Q=W_q X \)
  • La clé: \(K=W_K X \)
  • La valeur: \(V=W_V X \)
L’intra-attention est donnée par
\begin{equation*} Att(Q,K,V)=\operatorname{Softmax}(\frac{Q K^t}{\sqrt{n}})V \end{equation*}
Ici \(Q\) représente l’information que l’on souhaite corréler avec les autres. On parle de requête, car on peut comparer cela a une information que l’ont souhaite chercher dans un dictionnaire. L’enjeu est d’aligner aux mieux (à l’aide d’un produit scalaire) avec des clés qui indexés les données de la séquence \(X\) (c’est comme si on cherchait la clé correspondante à notre requète dans un dictionnaire). L’applidation de sofmax transforme cela en loi de probabilité ou plus une clé est alignée à la requête plus la probabilité est grande. Ensuite on va multiplier ces probabilités par quelque chose qui représente les valeurs associées à la séquence. On va donc renvoyer une matrice qui privilégie au mieux les valeurs dont l’alignement avec une donnée cible est le meilleur . Cela ressemble a une matrice de corrélation entre une entrée \(Q\) et la séquence \(X\text{.}\) A partir de la on peut définir une opération plus générale qui consiste à appliquer plusieurs mécanismes d’attention.
Définition 5.58. Auto - Attention multi tête.
On se donne une entrée \(X\in \mathbb{R}^{n,d}\text{.}\) Soit \(W_Q^i, W_K^i, W_V^i\in \mathbb{R}^{d,d}, \quad \forall i \lt n\) des matrices de poids entraînable. La transformation d’attention multi tête (ici \(m\) tête) est donnée par
\begin{equation*} MTATT(X)=concat(ATT(Q_1,K_1,V_1),....,ATT(Q_m,K_m,V_m))W_0 \end{equation*}
avec \(W_0\) une matrice de poids entraînables.
Maintenant nous allons pouvoir définir un réseau de type Transformer. Les transformeurs reprennent la structure d’encodeur-décodeur utilisée par la transformation de séquence comme la traduction. Le principe va être ensuite de construire l’encodeur et le décodeur avec des mécanismes d’attention multi têtes.
L’encodeur transforme une séquence d’entrée dans une séquence abstraite qui contient toutes les informations apprises de cette entrée. Le décodeur prend ensuite cette représentation continue et génère étape par étape une sortie unique tout en étant également alimenté par la sortie précédente.
Figure 5.59. Principe général du transformer
L’encodeur d’un transformeur est composé de plusieurs blocs qui enchaînent deux sous blocs, un mécanisme d’attention multi tête et un réseau totalement connecté de type multi perceptron. Le décodeur prend la séquence de sortie, applique aussi une série de blocs qui enchaîne des mécanismes d’attention. Le premier sous-bloc d’attention est dit masqué, car elle utilise les données du fur de la séquence \((y_1,...y_n)\text{,}\) le second sous bloc utilise aussi les résultats de l’encodeur. Ensuite on finit par un sous bloc qui se base sur réseau totalement connecté. La sortie de la couche de type MPC passe par une couche linéaire qui agit comme un classificateur. Le classificateur est aussi grand que le nombre de classes que nous avons. Enfin, une couche softmax, qui produira une loi de probabilité sur les mots prédits. Le décodeur prend ensuite la sortie, l’ajoute à la liste des entrées du décodeur et continue à décoder.
Figure 5.60. Architecture d’un transformeur
Les séquences sont initialement transformées en vecteurs (embedding) numériques puis ajoute une phase ajout de l’information de position (position embedding) afin de transformer le vecteur de façon à ce que les mots proches dans la séquence soit des vecteurs qui sont proches.
Mathématiquement les blocs d’ un transformeurs s’écrivent sous la forme suivante.
Définition 5.61. Block d’un transformeur.
Soit \(\mathbf{x} \in \mathbb{R}^{n \times d}\) alors la transformation \(f_\theta(\mathbf{x})=\mathbf{z}\) est donnée par:
\begin{equation*} \begin{cases} \amp Q^{(h)}\left(\mathbf{x}_i\right)=W_{h, q}^T \mathbf{x}_i, \quad K^{(h)}\left(\mathbf{x}_i\right)=W_{h, k}^T \mathbf{x}_i, \quad V^{(h)}\left(\mathbf{x}_i\right)=W_{h, v}^T \mathbf{x}_i, \quad W_{h, q}, W_{h, k}, W_{h, v} \in \mathbb{R}^{d \times d}, \\ \amp \alpha_{i, j}^{(h)}=\operatorname{softmax}_j\left(\frac{\left\langle Q^{(h)}\left(\mathbf{x}_i\right), K^{(h)}\left(\mathbf{x}_j\right)\right\rangle}{\sqrt{n}}\right), \\ \amp \mathbf{u}_i^{\prime}=\sum_{h=1}^H W_{c, h}^T \sum_{j=1}^n \alpha_{i, j}^{(h)} V^{(h)}\left(\mathbf{x}_j\right), \quad W_{c, h} \in \mathbb{R}^{d \times d}, \\ \amp \mathbf{u}_i=\operatorname{LayerNorm}\left(\mathbf{x}_i+\mathbf{u}_i^{\prime} ; \gamma_1, \beta_1\right), \quad \gamma_1, \beta_1 \in \mathbb{R}^d, \\ \amp \mathbf{z}_i^{\prime}=W_2^T \sigma\left(W_1^T \mathbf{u}_i\right), \quad W_1 \in \mathbb{R}^{d \times m}, W_2 \in \mathbb{R}^{m \times d}, \\ \amp\mathbf{z}_i=\operatorname{LayerNorm}\left(\mathbf{u}_i+\mathbf{z}_i^{\prime} ; \gamma_2, \beta_2\right), \quad \gamma_2, \beta_2 \in \mathbb{R}^d . \\ \end{cases} \end{equation*}
Les étapes de normalisation par paquet sont définies par
\begin{equation*} \begin{cases} \amp \operatorname{LayerNorm}(\mathbf{z} ; \gamma, \beta)=\gamma \frac{\left(\mathbf{z}-\mu_{\mathbf{z}}\right)}{\sigma_{\mathbf{z}}}+\beta, \quad \gamma, \beta \in \mathbb{R}^k \text {. } \\ \amp\mu_{\mathbf{z}}=\frac{1}{k} \sum_{i=1}^k \mathbf{z}_i, \quad \sigma_{\mathbf{z}}=\sqrt{\frac{1}{k} \sum_{i=1}^k\left(\mathbf{z}_i-\mu_{\mathbf{z}}\right)^2} . \\ \end{cases} \end{equation*}