web-dev-qa-db-fra.com

doutes sur la taille des lots et les pas de temps dans RNN

Dans le didacticiel RNN de Tensorflow: https://www.tensorflow.org/tutorials/recurrent . Il mentionne deux paramètres: la taille du lot et les pas de temps. Je suis confus par les concepts. À mon avis, RNN introduit batch, c'est parce que la séquence de train-train peut être très longue, de sorte que la rétropropagation ne peut pas être aussi longue (gradients explosifs/nuls). Nous divisons donc la séquence longue de formation en séquences plus courtes, chacune étant un mini-lot et dont la taille est appelée "taille du lot". Est-ce que je suis juste ici?

En ce qui concerne les pas de temps, RNN consiste uniquement en une cellule (cellule LSTM ou GRU ou autre cellule) et cette cellule est séquentielle. Nous pouvons comprendre le concept séquentiel en le déroulant. Mais dérouler une cellule séquentielle est un concept, pas réel ce qui signifie que nous ne l’implémentons pas de manière déroulante. Supposons que la séquence à former est un corpus de texte. Ensuite, nous transmettons un mot à chaque fois à la cellule RNN, puis nous mettons à jour les poids. Alors pourquoi avons-nous des pas de temps ici? En combinant ma compréhension de la "taille du lot" ci-dessus, je suis encore plus confus. Devons-nous alimenter la cellule d'un mot ou de plusieurs mots (taille du lot)?

8
derek

La taille du lot correspond au nombre d'échantillons d'apprentissage à prendre en compte à la fois pour la mise à jour des poids de votre réseau. Ainsi, dans un réseau à feedforward, supposons que vous souhaitiez mettre à jour les pondérations de votre réseau en fonction du calcul de vos dégradés à partir d'un mot à la fois, votre batch_size = 1 . c'est très peu coûteux en calcul. D'autre part, c'est aussi une formation très erratique.

Pour comprendre ce qui se passe lors de la formation d’un tel réseau à anticipation, Je vous renvoie à ce très bel exemple visuel de single_batch versus mini_batch pour single_sample training .

Cependant, vous voulez comprendre ce qui se passe avec votre variable num_steps. Ce n'est pas la même chose que votre batch_size. Comme vous l'avez peut-être remarqué, j'ai jusqu'à présent fait référence aux réseaux à anticipation. Dans un réseau à intégration directe, la sortie est déterminée à partir des entrées du réseau et la relation entrée-sortie est mappée par les relations de réseau apprises:

hidden_activations (t) = f(input(t))

sortie (t) = g (activations_ cachées (t)) = g(f(input(t)))

Après une passe de formation de taille batch_size, le gradient de votre fonction de perte par rapport à chacun des paramètres de réseau est calculé et vos poids sont mis à jour.

Dans un réseau de neurones récurrent (RNN), cependant, votre réseau fonctionne différemment:

hidden_activations (t) = f (entrée (t), hidden_activations (t-1))

sortie (t) = g (activations cachées (t)) = g (f (entrée (t), activations cachées (t-1)))

= g (f (entrée (t), f (entrée (t-1), activations masquées (t-2))))) = g (f (inp (t), f (inp (t-1),.) .., f (inp (t = 0), état caché_initial))))

Comme vous l'avez peut-être supposé du point de vue de la dénomination, le réseau conserve une mémoire de son état précédent, et les activations de neurones dépendent désormais également de l'état du réseau précédent et, par extension, de tous les états dans lesquels le réseau s'est trouvé. utilisez un facteur d’oubli pour attacher plus d’importance aux états de réseau les plus récents, mais c’est là le but de votre question.

Ensuite, comme vous pouvez en déduire que le calcul des gradients de la fonction de perte en fonction des paramètres de réseau est très très coûteux en calcul si vous devez prendre en compte la rétropropagation à travers tous les états depuis la création de votre réseau, accélérez vos calculs: approximez vos gradients avec un sous-ensemble d'états de réseau historiques num_steps.

Si cette discussion conceptuelle n’est pas assez claire, vous pouvez également jeter un œil à un description plus mathématique de ce qui précède }.

8
Uvar

J'ai trouvé ce diagramme qui m'a aidé à visualiser la structure de données.

Data Structure

Dans l'image, "taille du lot" correspond au nombre d'exemples d'une séquence avec laquelle vous souhaitez entraîner votre RNN pour ce lot. "Les valeurs par pas de temps" sont vos entrées. " (dans mon cas, mon RNN prend 6 entrées) et enfin, vos pas de temps sont la "longueur", pour ainsi dire, de la séquence que vous entraînez

Je découvre également des réseaux de neurones récurrents et comment préparer des lots pour l'un de mes projets (et suis tombé sur ce fil pour essayer de le comprendre).

La mise en lot pour les réseaux à répétition directe et les réseaux récurrents est légèrement différente et lorsqu’on regarde différents forums, la terminologie utilisée pour les deux réseaux est très complexe et il devient très confus; il est donc extrêmement utile de la visualiser.

J'espère que cela t'aides.

3
Nate Smith
  1. La "taille du lot" de RNN est destinée à accélérer le calcul (car il y a plusieurs lignes dans des unités de calcul parallèles); ce n'est pas un mini-lot pour la rétropropagation. Un moyen facile de prouver cela consiste à jouer avec différentes valeurs de taille de lot. Une cellule RNN avec une taille de lot = 4 peut être environ 4 fois plus rapide que celle d'une taille de lot = 1 et leur perte est généralement très proche.

  2. En ce qui concerne les "pas de temps" de RNN, examinons les extraits de code suivants de rnn.py . static_rnn () appelle la cellule pour chaque entrée_ à la fois et BasicRNNCell :: call () implémente sa logique de partie avant. Dans un cas de prédiction de texte, par exemple taille de lot = 8, nous pouvons penser que input_ contient 8 mots de phrases différentes de ou dans un grand corpus de texte, et non 8 mots consécutifs dans une phrase. D'après mon expérience, nous déterminons la valeur des pas de temps en fonction de la profondeur que nous souhaitons modéliser en "temps" ou en "dépendance séquentielle". De nouveau, pour prédire le prochain mot dans un corpus de texte avec BasicRNNCell, de petits pas de temps peuvent fonctionner. Un pas de temps important, en revanche, peut présenter un problème d’explosion de gradient.

    def static_rnn(cell,
           inputs,
           initial_state=None,
           dtype=None,
           sequence_length=None,
           scope=None):
    """Creates a recurrent neural network specified by RNNCell `cell`.
       The simplest form of RNN network generated is:
    
       state = cell.zero_state(...)
       outputs = []
       for input_ in inputs:
           output, state = cell(input_, state)
       outputs.append(output)
       return (outputs, state)
    """
    
    class BasicRNNCell(_LayerRNNCell):
    def call(self, inputs, state):
    """Most basic RNN: output = new_state = 
       act(W * input + U * state + B).
    """
        gate_inputs = math_ops.matmul(
            array_ops.concat([inputs, state], 1), self._kernel)
        gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)
        output = self._activation(gate_inputs)
        return output, output
    
  3. Pour voir comment ces deux paramètres sont liés au jeu de données et aux pondérations, l'article d'Erik Hallström mérite d'être lu. À partir de ce diagramme et des extraits de code ci-dessus, il est évident que la "taille du lot" de RNN n'affectera pas les poids (wa, wb et b), mais les "pas de temps". Ainsi, on pourrait décider des "pas de temps" de RNN en fonction de son problème et de son modèle de réseau et de la "taille du lot" de RNN en fonction de la plate-forme de calcul et du jeu de données.

1
rcnjko