Recurrent Neural Network (RNN)
Un réseau neuronal récurrent (RNN) lit une séquence étape par étape en transmettant un état caché. Découvre sa récurrence, son entraînement, ses variantes et des exemples de code.
Un réseau neuronal récurrent (RNN) est un réseau neuronal qui traite une séquence élément par élément tout en transmettant un état caché d’une étape à la suivante ; sa sortie à chaque étape peut donc dépendre de tout ce qu’il a lu jusque-là. Les mêmes poids sont appliqués à chaque étape, ce qui permet à un réseau de traiter des séquences de toute longueur, d’une phrase à plusieurs heures de mesures de capteurs. Les RNN constituaient l’architecture principale du traitement automatique du langage naturel (NLP), de la reconnaissance vocale et de l’analyse de séries temporelles jusqu’à ce que les Transformers les remplacent pour la plupart des tâches linguistiques à la fin des années 2010. Leurs variantes à portes restent courantes dans les modèles de diffusion en continu et les modèles exécutés sur appareil, et la récurrence est revenue dans les modèles d’espace d’état (SSMs) comme Mamba.
Fonctionnement d’un RNN#
Un RNN simple, également appelé réseau d’Elman d’après l’article de Jeffrey Elman publié en 1990, met à jour son état caché selon hₜ = tanh(Wxₜ + Uhₜ₋₁ + b) et peut produire une sortie yₜ = Vhₜ + c à chaque étape. L’état caché est un vecteur de taille fixe qui résume la séquence jusque-là, et tanh maintient ses valeurs entre −1 et 1 lorsqu’il est réinjecté. Représentée avec une copie du réseau à chaque étape, la boucle se déroule en un réseau profond à propagation avant dont les couches partagent les mêmes poids :
L’extrait ci-dessous applique nn.RNN de PyTorch à une séquence et répète la même récurrence dans une simple boucle :
import torch
from torch import nn
torch.manual_seed(0)
rnn = nn.RNN(input_size=3, hidden_size=4, batch_first=True)
x = torch.randn(1, 6, 3) # one sequence: 6 time steps, 3 features each
# PyTorch runs the whole sequence; output holds the hidden state after every step
output, h_n = rnn(x)
# The same recurrence by hand, reusing one set of weights at every step
h = torch.zeros(1, 4)
for t in range(x.shape[1]):
h = torch.tanh(x[:, t] @ rnn.weight_ih_l0.T + rnn.bias_ih_l0 + h @ rnn.weight_hh_l0.T + rnn.bias_hh_l0)
print(f"Output shape: {tuple(output.shape)}, final state shape: {tuple(h_n.shape)}")
print(f"Hand-written loop matches nn.RNN: {torch.allclose(h, h_n[0], atol=1e-6)}")Il affiche Output shape: (1, 6, 4), final state shape: (1, 1, 4) et Hand-written loop matches nn.RNN: True. La sortie contient un état caché à 4 dimensions pour chaque pas de temps, et la boucle reproduit l’état final avec une seule matrice de poids pour l’entrée et une autre pour l’état précédent.
Tâches séquentielles#
La même récurrence convient à des tâches où les longueurs d’entrée et de sortie diffèrent :
- Plusieurs vers un : lire une séquence entière et la classer à partir de son état final, comme pour l’analyse des sentiments ou l’étiquetage d’une fenêtre de données de capteurs.
- Plusieurs vers plusieurs : produire une sortie à chaque étape, par exemple pour étiqueter chaque mot d’une phrase ou chaque trame audio.
- Séquence à séquence : un RNN encodeur lit l’entrée et un RNN décodeur génère une sortie de longueur différente ; cette architecture est à l’origine de la traduction automatique neuronale et d’autres modèles séquence à séquence.
- Un vers plusieurs : générer une séquence à partir d’une seule entrée, par exemple une légende à partir du vecteur de caractéristiques d’une image dans les premiers modèles de génération de légendes d’images.
Les RNN bidirectionnels ajoutent un second RNN qui lit la séquence à rebours et combinent les deux états à chaque étape, afin que chaque sortie prenne en compte le contexte passé et futur. Les RNN empilés transmettent les états cachés d’une couche à la suivante comme séquence d’entrée.
Entraînement par rétropropagation à travers le temps#
Les RNN sont entraînés par rétropropagation à travers le temps (BPTT) : le réseau est déroulé sur la séquence, la fonction de perte est sommée sur les étapes, puis la rétropropagation s’effectue dans le graphe déroulé. Le gradient qui parvient à l’étape t depuis l’étape T traverse T − t copies de la couche récurrente et est multiplié par U et par la dérivée de tanh à chaque fois. Lorsque ces facteurs sont généralement inférieurs à 1, le gradient diminue de façon géométrique : c’est le problème du gradient évanescent, analysé en 1994 par Yoshua Bengio, Patrice Simard et Paolo Frasconi. Lorsqu’ils sont supérieurs à 1, il augmente de façon géométrique : c’est le problème du gradient explosif. L’extrait ci-dessous mesure l’influence de chaque entrée d’une séquence de 50 étapes sur l’état caché final :
import torch
from torch import nn
torch.manual_seed(0)
rnn = nn.RNN(input_size=8, hidden_size=32, batch_first=True)
x = torch.randn(1, 50, 8, requires_grad=True) # one 50-step sequence
# Backpropagate from the final hidden state to the input at every step
output, h_n = rnn(x)
h_n.sum().backward()
grad_norms = x.grad[0].norm(dim=1)
for distance in [0, 10, 20, 30, 40]:
print(f"Input {distance:>2} steps before the end: gradient {grad_norms[-1 - distance]:.1e}")Il affiche les gradients de 1.6e+00, 3.4e-03, 6.2e-06, 1.2e-08 et 1.1e-11 pour les entrées 0, 10, 20, 30 et 40 étapes avant la fin. Tous les dix pas, leur amplitude diminue d’environ trois ordres de grandeur : pendant l’entraînement, les poids peuvent donc à peine s’ajuster pour exploiter une entrée datant de quelques dizaines de pas. L’écrêtage des gradients, analysé pour les RNN par Razvan Pascanu et ses collègues en 2013, plafonne les gradients explosifs, tandis que la rétropropagation tronquée dans le temps (BPTT) limite la rétropropagation à une fenêtre fixe afin de borner la mémoire. Les gradients évanescents nécessitent une modification de l’architecture, apportée par les portes du LSTM et du GRU.
RNN et architectures apparentées#
- LSTM et GRU : des RNN à portes dotés d’une mise à jour additive de l’état, qui permet aux informations et aux gradients de traverser de nombreux pas. En pratique, « RNN » désigne souvent aussi bien l’un de ces modèles que le RNN simple.
- Transformer : il porte directement son attention sur toutes les positions précédentes au lieu de compresser l’historique dans un seul état, et s’entraîne sur toutes les positions en parallèle. Le coût de son mécanisme d’attention augmente avec la longueur de la séquence, tandis qu’un RNN consacre les mêmes ressources de calcul et de mémoire à chaque nouveau pas.
- Réseau de neurones convolutif (CNN) : il combine les positions voisines au moyen de filtres de taille fixe, dans l’espace pour les images ou dans le temps avec des convolutions 1D, et son champ réceptif dépend de sa profondeur.
- Modèles d’espace d’état : les récurrences linéaires telles que Mamba s’entraînent en parallèle avec un balayage et s’exécutent pas à pas comme un RNN à l’inférence. Les réseaux de neurones liquides sont des RNN en temps continu dont les neurones suivent des équations différentielles.
Applications#
- Prédiction au clavier : le modèle de prédiction du mot suivant de Gboard était un LSTM à portes d’entrée et d’oubli couplées, une variante plus légère du LSTM. Il a été entraîné avec l’apprentissage fédéré sur les téléphones des utilisateurs, comme l’ont décrit des chercheurs de Google en 2018.
- Prévision de la demande : le modèle DeepAR d’Amazon entraîne un RNN autorégressif unique sur de nombreuses séries temporelles apparentées et produit une distribution de probabilité pour chaque valeur future.
- Audio en continu : les détecteurs de mots de réveil et les suppresseurs de bruit traitent l’audio trame par trame avec de petites couches récurrentes, ce qui maintient une mémoire et une latence constantes sur les téléphones et les écouteurs.
- Suivi d’objets : un traqueur conserve un état pour chaque objet d’une trame à l’autre, comme le fait l’état caché d’un RNN. Chaque traqueur intégré au mode de suivi de YOLO26, de ByteTrack et BoT-SORT jusqu’au TrackTrack par défaut, met à jour cet état avec un filtre de Kalman, une récurrence linéaire où des équations de vitesse constante définies manuellement remplacent les poids appris.










