Technologie

Réseaux de neurones récurrents (RNN) – Vers la science des données

Réseaux de neurones récurrents (RNN) - Vers la science des données

Implémentation d'un RNN à partir de rien en Python.

L'objectif principal de cet article est de mettre en œuvre un RNN à partir de rien et de fournir une explication simple, ainsi que de le rendre utile aux lecteurs. La mise en œuvre de tout réseau de neurones au moins une fois est un exercice précieux. Cela vous aide à comprendre le fonctionnement des réseaux de neurones et nous mettons en place un RNN qui a sa propre complexité et qui nous offre ainsi une bonne occasion de perfectionner nos compétences.

La source

Il existe divers tutoriels qui fournissent des informations très détaillées sur les composants internes d'un RNN. Vous trouverez certaines des références très utiles à la fin de cet article. Je pouvais comprendre le fonctionnement d'un RNN assez rapidement, mais ce qui m'a le plus troublé, ce sont les calculs du BPTT et leur mise en œuvre. J'ai dû passer du temps à comprendre et enfin à tout mettre en place. Sans perdre plus de temps, passons rapidement en revue les bases d’un RNN.

Qu'est-ce qu'un RNN?

Un réseau de neurones récurrent est un réseau de neurones spécialisé dans le traitement d’une séquence de données. x (t) = x (1),. . . , x (τ) avec l'index de pas de temps t allant de 1 à τ. Pour les tâches comportant des entrées séquentielles, telles que la parole et le langage, il est souvent préférable d'utiliser des RNN. Dans un problème de PNL, si vous voulez prédire le mot suivant dans une phrase, il est important de connaître les mots qui le précèdent. Les RNN s'appellent récurrent parce qu'ils effectuent la même tâche pour chaque élément d'une séquence, la sortie étant dépendante des calculs précédents. Une autre façon de penser aux RNN est qu’ils ont une «mémoire» qui capture des informations sur ce qui a été calculé jusqu’à présent.

Architecture : Passons brièvement en revue un réseau de base RNN.

Référence

Le côté gauche du diagramme ci-dessus montre une notation de RNN et à droite un RNN déroulé (ou déplié) dans un réseau complet. En déroulant, nous entendons écrire le réseau pour la séquence complète. Par exemple, si la séquence qui nous importe est une phrase de 3 mots, le réseau serait déroulé dans un réseau de neurones à 3 couches, une couche pour chaque mot.

Contribution: x (t)Est pris comme entrée sur le réseau au pas de temps t. Par exemple, x1,pourrait être un vecteur one-hot correspondant à un mot d'une phrase.

État caché: h (t)Représente un état caché à l'instant t et agit comme une «mémoire» du réseau. h (t)Est calculé en fonction de l’entrée actuelle et de l’état caché du pas de temps précédent: h (t)= F(U x (t)+ W h (t-1)). La fonction F est considéré comme une transformation non linéaire telle que Tanh, ReLU.

Poids: Le RNN a des entrées dans des connexions masquées paramétrées par une matrice de pondération U, des connexions récurrentes masquées à masquées paramétrées par une matrice de pondération W et des connexions masquées vers une sortie paramétrées par une matrice de pondération V et toutes ces pondérations (U,V,W) sont partagés dans le temps.

Sortie: o (t)Illustre la sortie du réseau. Dans la figure, je viens de mettre une flèche après o (t) qui est également souvent soumis à la non-linéarité, en particulier lorsque le réseau contient d'autres couches en aval.

Passe avant

La figure ne spécifie pas le choix de la fonction d'activation pour les unités cachées. Avant de procéder, nous formulons peu d’hypothèses: 1) nous assumons la fonction d’activation de la tangente hyperbolique pour la couche cachée. 2) Nous supposons que la sortie est discrète, comme si le RNN était utilisé pour prédire des mots ou des caractères. Une façon naturelle de représenter des variables discrètes est de considérer la sortie o comme donnant les probabilités de journal non normalisées de chaque valeur possible de la variable discrète. Nous pouvons ensuite appliquer l’opération softmax en post-traitement pour obtenir un vecteur ŷdes probabilités normalisées sur la sortie.

Le passage avant RNN peut donc être représenté par l'ensemble d'équations ci-dessous.

Voici un exemple de réseau récurrent qui mappe une séquence d'entrée sur une séquence de sortie de même longueur. La perte totale pour une séquence donnée de X des valeurs associées à une séquence de y les valeurs ne seraient alors que la somme des pertes sur tous les pas de temps. Nous supposons que les sorties o (t)sont utilisés comme argument de la fonction softmax pour obtenir le vecteur ŷ des probabilités sur la sortie. Nous supposons également que la perte L est la log-vraisemblance négative de la vraie cible y (t)compte tenu de l'entrée jusqu'à présent.

Pass arrière

Le calcul du gradient implique d'effectuer une passe de propagation vers l'avant se déplaçant de gauche à droite dans le graphique, suivie d'une passe de propagation vers l'arrière se déplaçant de droite à gauche dans le graphique. Le temps d'exécution est O (τ) et ne peut pas être réduit par la parallélisation car le graphe de propagation directe est intrinsèquement séquentiel; chaque pas de temps ne peut être calculé qu'après le précédent. Les états calculés dans le passage en aval doivent être stockés jusqu'à ce qu'ils soient réutilisés lors du passage en arrière, de sorte que le coût en mémoire est également égal à O (τ). L'algorithme de rétro-propagation appliqué au graphe déroulé avec un coût de O (τ) est appelé rétro-propagation dans le temps (BPTT). Les paramètres étant partagés par tous les pas de temps du réseau, le gradient de chaque sortie dépend non seulement des calculs du pas de temps actuel, mais également des pas de temps précédents.

Gradients informatiques

Compte tenu de notre fonction de perte L, nous devons calculer les gradients pour nos trois matrices de poids U, V, W et termes de partialité avant JC et les mettre à jour avec un taux d'apprentissage α. Similaire à la rétro-propagation normale, le gradient nous donne une idée de l'évolution de la perte en fonction de chaque paramètre de poids. Nous mettons à jour les poids W pour minimiser les pertes avec l'équation suivante:

1*S7N55YQK2xgH jGWT0qL w - Réseaux de neurones récurrents (RNN) - Vers la science des données

La même chose doit être faite pour les autres poids U, V, b, c également.

Calculons maintenant les gradients par BPTT pour les équations RNN ci-dessus. Les nœuds de notre graphe de calcul incluent les paramètres U, V, W, b et c ainsi que la séquence de nœuds indexés par t pour x (t), h (t), o (t) et L (t). Pour chaque noeud n nous devons calculer le gradient ∇nL récursivement, en fonction du gradient calculé aux nœuds qui le suivent dans le graphique.

Gradient par rapport à la sortie o (t) est calculé en supposant que les o (t) sont utilisés comme arguments de la fonction softmax pour obtenir le vecteur ŷ des probabilités sur la sortie. Nous supposons également que la perte est la log-vraisemblance négative de la vraie cible y (t).

1*geEKJSbo6iOciOREkwuTuA - Réseaux de neurones récurrents (RNN) - Vers la science des données

Veuillez vous référer ici pour dériver la solution élégante ci-dessus.

Voyons maintenant comment le gradient passe par l’état caché h (t). Le diagramme ci-dessous montre clairement que, à l'instant t, l'état caché h (t) a un gradient qui s'écoule à la fois de la sortie en cours et du prochain état caché.

La flèche rouge indique le flux de gradient

Nous travaillons en arrière, à partir de la fin de la séquence. Au dernier pas tau, h (τ) n'a que descendant o (τ), son gradient est donc simple:

1*RTD0T0IP uzGNLp9NpjEJA - Réseaux de neurones récurrents (RNN) - Vers la science des données

On peut ensuite parcourir le temps dans le temps pour reculer les gradients dans le temps, de t = τ −1 à t = 1, en notant que h (t) (pour t <τ) a pour descendants à la fois o (t) et h ( t + 1). Sa pente est donc donnée par:

Une fois que les gradients sur les nœuds internes du graphe de calcul sont obtenus, nous pouvons obtenir les gradients sur les nœuds de paramètre. Les calculs de gradient utilisant la règle de chaîne pour tous les paramètres sont les suivants:

Nous ne souhaitons pas déduire ces équations ici, mais plutôt les mettre en œuvre. Il y a de très bons articles ici et ici fournissant une dérivation détaillée de ces équations.

la mise en oeuvre

Nous allons implémenter un réseau de neurones récurrents complet à partir de zéro en utilisant Python. Nous allons essayer de construire un modèle de génération de texte en utilisant un RNN. Nous formons notre modèle pour prédire la probabilité d'un mot à partir des mots précédents. C'est un modèle génératif. Étant donné une séquence de caractères existante, nous échantillonnons un prochain caractère parmi les probabilités prédites et répétons le processus jusqu'à obtenir une phrase complète. Cette mise en œuvre est d’Andrej Karparthy, grand poste qui construit un personnage de niveau RNN. Ici, nous allons discuter des détails de la mise en œuvre, étape par étape.

Étapes générales à suivre:

  1. Initialiser les matrices de poids U, V, W de distribution aléatoire et biais b, c avec zéros
  2. Propagation en avant pour calculer les prédictions
  3. Calculer la perte
  4. Back-propagation pour calculer les gradients
  5. Mettre à jour les poids en fonction des gradients
  6. Répétez les étapes 2 à 5

Étape 1: initialiser

Pour commencer avec la mise en œuvre de la cellule RNN de base, définissons d’abord les dimensions des différents paramètres U, V, W, b, c.

Dimensions: Supposons que nous choisissions une taille de vocabulaire vocab_size = 8000 et une taille de couche cachée hidden_dim = 100. Ensuite nous avons:

La taille de vocabulaire peut être le nombre de caractères uniques pour un modèle basé sur les caractères ou le nombre de mots uniques pour un modèle basé sur des mots.

Avec nos quelques hyper-paramètres et d’autres paramètres de modèle, commençons par définir notre cellule RNN.

Une initialisation appropriée des poids semble avoir un impact sur les résultats de la formation. De nombreuses recherches ont été menées dans ce domaine. Il s'avère que la meilleure initialisation dépend de la fonction d'activation (tanh dans notre cas) et une approche recommandée consiste à initialiser les poids aléatoirement dans l'intervalle entre[ -1/sqrt(n), 1/sqrt(n)]n est le nombre de connexions entrantes de la couche précédente.

Étape 2: Pass avant

D’après nos équations, pour chaque horodatage t, nous calculons l’état caché hs

Show More

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Related Articles

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Close
Close