J'ai du mal à interpréter la différence de codage Keras pour un étiquetage de séquence un à plusieurs (par exemple, classification d'images uniques) et plusieurs à plusieurs (par exemple, classification de séquences d'images). Je vois souvent deux types de codes différents:
Le type 1 est celui où aucun TimeDistributed appliqué comme ceci:
model=Sequential()
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1], border_mode="valid", input_shape=[1, 56,14]))
model.add(Activation("relu"))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Reshape((56*14,)))
model.add(Dropout(0.25))
model.add(LSTM(5))
model.add(Dense(50))
model.add(Dense(nb_classes))
model.add(Activation("softmax"))
Le type 2 est l'endroit où TimeDistributed est appliqué comme ceci:
model = Sequential()
model.add(InputLayer(input_shape=(5, 224, 224, 3)))
model.add(TimeDistributed(Convolution2D(64, (3, 3))))
model.add(TimeDistributed(MaxPooling2D((2,2), strides=(2,2))))
model.add(LSTM(10))
model.add(Dense(3))
Mes questions sont:
Mon hypothèse est-elle correcte que le type 1 est le type un-à-plusieurs et le type 2 est le type plusieurs-à-plusieurs? Ou
TimeDistributed
n'a aucun rapport avec cet aspect?Dans les deux cas, un à plusieurs ou plusieurs à plusieurs est la dernière couche dense censée avoir 1 nœud "long" (émettant une seule valeur à son tour) et
la couche récurrente précédente est responsable de déterminer combien de
1-long valeur à émettre? Ou la dernière couche dense est censée se composer de N nœuds oùN=max sequence length
? Dans l'affirmative, quel est l'intérêt d'
utiliser RNN ici lorsque nous pourrions produire une entrée similaire avec plusieurs
sorties avec N estimateurs "vanille" parallèles?Comment définir le nombre de pas de temps dans les RNN? Est-il en quelque sorte
corrélé avec la longueur de la séquence de sortie ou est-ce juste un
hyperparamètre à régler?Dans le cas de mon exemple de type 1 ci-dessus, quel est l'intérêt d'appliquer
LSTM lorsque le modèle n'émet qu'une seule prédiction de classe (possible
nb_classes
)? Et si on omet la couche LSTM?
Réponses:
Le point d'utiliser une couche récurrente est que la sortie soit le résultat non seulement d'un élément unique indépendant des autres éléments, mais plutôt d'une séquence d'éléments, de sorte que la sortie de l'opération de la couche sur un élément de la séquence soit le résultat de cet élément et de tout élément précédent dans la séquence. Le nombre de pas de temps définit la durée d'une telle séquence. C'est-à-dire le nombre d'éléments qui doivent être traités dans une séquence et affectent les résultats résultants les uns des autres.
Une couche LSTM fonctionne de telle manière qu'elle accepte les entrées sous la forme number_of_timesteps, dimensions_of_each_item. Si le paramètre return_sequences est défini sur False, ce qui est le cas par défaut, la couche "compose" les entrées de tous les pas de temps dans une seule sortie. Si vous considérez une séquence de, disons, 10 éléments, une couche LSTM avec return_sequences définie sur False produira à partir d'une telle séquence un seul élément de sortie, et les attributs de cet élément unique seront le résultat de tous les éléments (pas de temps) dans le séquence. C'est ce que vous voulez dans le cas d'une conception plusieurs-à-un.
Une couche LSTM avec return_sequences définie sur True sera pour chaque élément (timestep) dans une séquence d'entrée produire une sortie. Cela se fait de telle manière qu'à tout moment, la sortie dépendra non seulement de l'élément actuellement utilisé, mais également des éléments précédents de la séquence. C'est ce que vous voulez dans le cas d'une conception plusieurs-à-plusieurs.
Comme une couche LSTM prend une séquence d'éléments en entrée, toute couche avant une couche LSTM dans votre modèle devra produire une séquence en sortie. Dans le cas de votre modèle de type 1, les premières couches ne fonctionnent pas sur des séquences, mais plutôt sur un seul élément à la fois. Cela ne produit donc pas une séquence d'éléments sur lesquels opérer pour le LSTM.
L'utilisation de TimeDistributed permet de faire fonctionner une couche sur chaque élément d'une séquence sans que les éléments ne s'affectent les uns les autres. Les couches TimeDistributed opèrent donc sur des séquences d'éléments, mais il n'y a pas de récursivité.
Dans le cas de votre modèle de type 2, les premières couches produiront une séquence de 5 pas de temps et les opérations effectuées sur chacun des éléments de la séquence seront indépendantes les unes des autres, car les couches enveloppées dans TimeDistributed ne sont pas récurrentes. Comme la couche LSTM utilise les paramètres par défaut, return_sequences = False, la couche LSTM produira une sortie unique pour chacune de ces séquences de 5 éléments.
Le nombre final de nœuds de sortie dans votre modèle dépend entièrement du cas d'utilisation. Un nœud unique convient à quelque chose comme la classification binaire ou pour produire une sorte de partition.
la source
Je pense que vous pourriez utiliser mon travail précédent. Dans ce code, je crée des ondes sinusoïdales (de longueurs d'onde et de phases aléatoires) et j'entraîne un LSTM à une séquence de points à partir de ces ondes sinusoïdales et génère une séquence de 150 points complétant chaque onde sinusoïdale.
Voici le modèle:
Et voici le script entier:
la source