web-dev-qa-db-fra.com

dimensions d'entrée dans un réseau unidimensionnel convolutionnel en keras

vraiment du mal à comprendre les dimensions d'entrée de la convolution 1d couche en keras:

Forme d'entrée

Tenseur 3D avec forme: (échantillons, pas, input_dim).

Forme de sortie

Tenseur 3D avec forme: (échantillons, new_steps, nb_filter). la valeur des étapes peut avoir changé en raison du remplissage.

Je veux que mon réseau prenne une série chronologique de prix (101, dans l'ordre) et produise 4 probabilités. Mon réseau non convolutionnel actuel qui fait cela assez bien (avec un ensemble de formation de 28000) ressemble à ceci:

standardModel = Sequential()
standardModel.add(Dense(input_dim=101, output_dim=100, W_regularizer=l2(0.5), activation='sigmoid'))
standardModel.add(Dense(4, W_regularizer=l2(0.7), activation='softmax'))

Pour améliorer cela, je veux faire une carte d'entités à partir de la couche d'entrée qui a un champ récepteur local de longueur 10. (et a donc 10 poids partagés et 1 biais partagé). Je veux ensuite utiliser la mise en commun maximale et l'injecter dans une couche cachée de 40 neurones environ, puis la produire avec 4 neurones avec softmax dans la couche externe.

image (c'est assez affreux désolé!)

Donc, idéalement, la couche convolutionnelle prendrait un tenseur 2D de dimensions:

(minibatch_size, 101)

et produire un tenseur 3D de dimensions

(minibatch_size, 91, no_of_featuremaps)

Cependant, la couche de kéros semble nécessiter une dimension dans l'entrée appelée étape. J'ai essayé de comprendre cela et je ne comprends toujours pas. Dans mon cas, le pas devrait-il être 1 car chaque pas dans le vecteur est une augmentation du temps de 1? Aussi, qu'est-ce que new_step?

De plus, comment transformer la sortie des couches de regroupement (un tenseur 3D) en entrée appropriée pour la couche cachée standard (c'est-à-dire une couche de kéros dense) sous la forme d'un tenseur 2D?

Mise à jour: Après les suggestions très utiles données, j'ai essayé de créer un réseau convolutionnel comme ceci:

conv = Sequential()
conv.add(Convolution1D(64, 10, input_shape=(1,101)))
conv.add(Activation('relu'))
conv.add(MaxPooling1D(2))
conv.add(Flatten())
conv.add(Dense(10))
conv.add(Activation('tanh'))
conv.add(Dense(4))
conv.add(Activation('softmax'))

La ligne conv.Add (Flatten ()) renvoie une plage dépassant l'erreur des limites valides. Fait intéressant, cette erreur n'est pas levée pour ce code uniquement:

conv = Sequential()
conv.add(Convolution1D(64, 10, input_shape=(1,101)))
conv.add(Activation('relu'))
conv.add(MaxPooling1D(2))
conv.add(Flatten())

faire

print conv.input_shape
print conv.output_shape

résulte en

(None, 1, 101
(None, -256)

être retourné

Mise à jour 2:

Modifié

conv.add(Convolution1D(64, 10, input_shape=(1,101)))

à

conv.add(Convolution1D(10, 10, input_shape=(101,1))

et il a commencé à fonctionner. Cependant, y a-t-il une différence importante entre l'entrée (Aucune, 101, 1) dans une couche conv 1d ou (Aucune, 1, 101) que je devrais connaître? Pourquoi (Aucun, 1, 101) ne fonctionne pas?

22
Nick

La raison pour laquelle cela ressemble à ceci est que le concepteur Keras avait l'intention de faire un cadre convolutionnel à 1 dimension à interpréter comme un cadre pour traiter les séquences. Pour bien comprendre la différence - essayez d'imaginer que vous avez une séquence de plusieurs vecteurs de caractéristiques. Ensuite, votre sortie sera au moins en deux dimensions - où la première dimension est liée au temps et les autres dimensions sont liées aux fonctionnalités. Le cadre convolutionnel unidimensionnel a été conçu pour mettre en évidence cette dimension temporelle d'une manière ou d'une autre et essayer de trouver les modèles de réapparition dans les données - plutôt que d'effectuer une transformation convolutionnelle multidimensionnelle classique.

Dans votre cas, vous devez simplement remodeler vos données pour qu'elles prennent forme (dataset_size, 101, 1) - car vous n'avez qu'une seule entité. Cela pourrait être fait facilement en utilisant numpy.reshape une fonction. Pour comprendre ce que signifie une nouvelle étape - vous devez comprendre que vous effectuez la convolution dans le temps - afin de modifier la structure temporelle de vos données - ce qui conduit à une nouvelle structure liée au temps. Pour obtenir vos données dans un format adapté aux couches denses/statiques, utilisez keras.layers.flatten couche - la même que dans le cas convolutionnel classique.

MISE À JOUR: Comme je l'ai mentionné précédemment - la première dimension de l'entrée est liée au temps. Donc, la différence entre (1, 101) et (101, 1) réside dans le fait que dans le premier cas, vous avez un pas de temps avec 101 fonctions et dans le second - 101 pas de temps avec 1 fonction. Le problème que vous avez mentionné après votre premier changement a son origine dans la mise en commun avec la taille 2 sur une telle entrée. Avoir un seul pas de temps - vous ne pouvez pas regrouper de valeur sur une fenêtre de temps de taille 2 - simplement parce qu'il n'y a pas assez de pas de temps pour le faire.

16
Marcin Możejko