RNN: quand appliquer le BPTT et / ou mettre à jour les pondérations?

15

J'essaie de comprendre l'application de haut niveau des RNN à l'étiquetage des séquences via (entre autres) l'article de Graves de 2005 sur la classification des phonèmes.

Pour résumer le problème: nous avons un grand ensemble de formation composé de fichiers audio (d'entrée) de phrases simples et (de sortie) d'heures de début, d'heures d'arrêt et d'étiquettes pour des phonèmes individuels (y compris quelques phonèmes "spéciaux" tels que le silence, de sorte que chaque échantillon de chaque fichier audio soit étiqueté avec un symbole de phonème.)

Le but du papier est d'appliquer un RNN avec des cellules de mémoire LSTM dans la couche cachée à ce problème. (Il applique plusieurs variantes et plusieurs autres techniques à titre de comparaison. Je ne suis pour l'instant intéressé que par le LSTM unidirectionnel, pour garder les choses simples.)

Je crois comprendre l'architecture du réseau: une couche d'entrée correspondant à des fenêtres de 10 ms des fichiers audio, prétraitées de manière standard pour le travail audio; une couche cachée de cellules LSTM et une couche de sortie avec un codage à chaud de tous les 61 symboles téléphoniques possibles.

Je crois que je comprends les équations (complexes mais simples) de la passe avant et de la passe arrière à travers les unités LSTM. Ce ne sont que du calcul et la règle de la chaîne.

Ce que je ne comprends pas, après avoir lu cet article et plusieurs similaires plusieurs fois, c'est quand exactement appliquer l'algorithme de rétropropagation et quand exactement mettre à jour les différents poids dans les neurones.

Il existe deux méthodes plausibles:

1) Backprop et mise à jour du cadre

Load a sentence.  
Divide into frames/timesteps.  
For each frame:
- Apply forward step
- Determine error function
- Apply backpropagation to this frame's error
- Update weights accordingly
At end of sentence, reset memory
load another sentence and continue.

ou,

2) Backprop phrase et mise à jour:

Load a sentence.  
Divide into frames/timesteps.  
For each frame:
- Apply forward step
- Determine error function
At end of sentence:
- Apply backprop to average of sentence error function
- Update weights accordingly
- Reset memory
Load another sentence and continue.

Notez qu'il s'agit d'une question générale sur la formation des RNN en utilisant le document Graves comme exemple pointu (et personnellement pertinent): lors de la formation des RNN sur les séquences, la propulsion est-elle appliquée à chaque pas de temps? Les poids sont-ils ajustés à chaque pas de temps? Ou, dans une analogie lâche avec la formation par lots sur des architectures strictement à action directe, les erreurs sont-elles accumulées et moyennées sur une séquence particulière avant que les mises à jour du backprop et du poids ne soient appliquées?

Ou suis-je encore plus confus que je ne le pense?

Novak
la source

Réponses:

25

Je suppose que nous parlons de réseaux neuronaux récurrents (RNN) qui produisent une sortie à chaque pas de temps (si la sortie n'est disponible qu'à la fin de la séquence, il est logique d'exécuter backprop à la fin). Les RNN dans ce cadre sont souvent formés à l'aide de la rétropropagation tronquée dans le temps (BPTT), opérant séquentiellement sur des «morceaux» d'une séquence. La procédure ressemble à ceci:

  1. Passe avant: Parcourez les pas de temps suivants, calculant les états d'entrée, caché et de sortie.k1
  2. Calculez la perte, additionnée sur les pas de temps précédents (voir ci-dessous).
  3. k2
  4. Mettre à jour les paramètres (cela se produit une fois par bloc, pas de manière incrémentielle à chaque pas de temps).
  5. Si vous traitez plusieurs morceaux d'une séquence plus longue, stockez l'état caché au dernier pas de temps (sera utilisé pour initialiser l'état caché pour le début du morceau suivant). Si nous avons atteint la fin de la séquence, réinitialisez l'état mémoire / caché et passez au début de la séquence suivante (ou au début de la même séquence, s'il n'y en a qu'une).
  6. Répétez à partir de l'étape 1.

k1k2k1=k2k1=k2k2>k1

k1k1

k2k2k2pas de temps car les unités cachées peuvent stocker des informations au-delà de cette période (voir par exemple Mikolov 2012 et ce post ).

k1k2

k11k2k1k2k1k2sont possibles; Je vais énumérer quelques exemples ci-dessous.

Références décrivant le BPTT tronqué (procédure, motivation, problèmes pratiques):

  • Sutskever (2013) . Formation des réseaux de neurones récurrents.
  • Mikolov (2012) . Modèles de langage statistique basés sur les réseaux de neurones.
    • k1k2
    • k1
    • Il est préférable d'effectuer des mises à jour une fois par bloc plutôt qu'incrémentalement (ce qui peut être instable)
  • Williams et Peng (1990) . Un algorithme efficace basé sur un gradient pour la formation en ligne des trajectoires de réseau récurrentes.
    • Proposition originale (?) De l'algorithme
    • k1k2hhk2k1
    • k1=1

Autres exemples utilisant BPTT tronqué:

  • (Karpathy 2015). char-rnn.
  • Graves (2014) . Génération de séquences avec des réseaux de neurones récurrents.
    • k1=k2=10010,000
  • Sak et al. (2014) . Architectures de réseaux de neurones récurrents basés sur la mémoire à court terme pour une reconnaissance vocale de vocabulaire important.
    • k1=k2=20
  • Ollivier et al. (2015) . Formation des réseaux récurrents en ligne sans retour en arrière.
    • k1=k2=15
  • Hochreiter et Schmidhuber (1997) . Mémoire à court terme.
    • Ils décrivent une procédure modifiée pour les LSTM
user20160
la source
Il s'agit d'une réponse exceptionnelle, et j'aurais souhaité avoir la qualité pour ce forum de lui accorder une généreuse récompense. La discussion concrète de k1 vs k2 est particulièrement utile pour contextualiser mes deux cas par rapport à une utilisation plus générale, et des exemples numériques de ceux-ci.
Novak