Recherche…


Exemple de base

Mise à jour: TensorFlow prend désormais en charge la convolution 1D depuis la version r0.11, en utilisant tf.nn.conv1d .


Prenons un exemple de base avec une entrée de longueur 10 et de dimension 16 . La taille du lot est de 32 . Nous avons donc un espace réservé avec une forme d'entrée [batch_size, 10, 16] .

batch_size = 32
x = tf.placeholder(tf.float32, [batch_size, 10, 16])

Nous créons ensuite un filtre de largeur 3, et nous prenons 16 canaux en entrée, et sortons également 16 canaux.

filter = tf.zeros([3, 16, 16])  # these should be real values, not 0

Enfin, nous appliquons tf.nn.conv1d avec une foulée et un remplissage:

  • stride : entier s
  • padding : cela fonctionne comme en 2D, vous pouvez choisir entre SAME et VALID . SAME affichera la même longueur d’entrée, alors que VALID n’ajoutera pas de remplissage nul.

Pour notre exemple, nous prenons une foulée de 2 et un remplissage valide.

output = tf.nn.conv1d(x, filter, stride=2, padding="VALID")

La forme de sortie doit être [batch_size, 4, 16] .
Avec padding="SAME" , nous aurions eu une forme de sortie de [batch_size, 5, 16] .


Pour les versions précédentes de TensorFlow, vous pouvez simplement utiliser des convolutions 2D tout en définissant la hauteur des entrées et des filtres sur 1 .

Math derrière la convolution 1D avec des exemples avancés en TF

`Pour calculer la convolution 1D à la main, vous faites glisser votre noyau sur l’entrée, calculez les multiplications élémentaires et les résumez.

Le moyen le plus simple est d'utiliser padding = 0, stride = 1

Donc, si votre input = [1, 0, 2, 3, 0, 1, 1] et le kernel = [2, 1, 3] le résultat de la convolution est [8, 11, 7, 9, 4] , ce qui est calculé de la manière suivante:

  • 8 = 1 * 2 + 0 * 1 + 2 * 3
  • 11 = 0 * 2 + 2 * 1 + 3 * 3
  • 7 = 2 * 2 + 3 * 1 + 0 * 3
  • 9 = 3 * 2 + 0 * 1 + 1 * 3
  • 4 = 0 * 2 + 1 * 1 + 1 * 3

La fonction conv1d de TF calcule les convolutions par lots. Pour ce faire, dans TF, nous devons fournir les données au bon format (doc explique que l'entrée doit être dans [batch, in_width, in_channels] , elle explique également l'aspect du noyau. comme). Alors

import tensorflow as tf
i = tf.constant([1, 0, 2, 3, 0, 1, 1], dtype=tf.float32, name='i')
k = tf.constant([2, 1, 3], dtype=tf.float32, name='k')

print i, '\n', k, '\n'

data   = tf.reshape(i, [1, int(i.shape[0]), 1], name='data')
kernel = tf.reshape(k, [int(k.shape[0]), 1, 1], name='kernel')

print data, '\n', kernel, '\n'

res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'VALID'))
with tf.Session() as sess:
    print sess.run(res)

ce qui vous donnera la même réponse que nous avons calculée précédemment: [ 8. 11. 7. 9. 4.]

Convolution avec rembourrage

Le rembourrage est simplement un moyen sophistiqué d’ajouter et d’ajouter une valeur à votre entrée. Dans la plupart des cas, cette valeur est 0, et c'est pourquoi la plupart du temps, les gens l'appellent «remplissage zéro». TF supporte 'VALID' et 'SAME', pour un remplissage arbitraire, vous devez utiliser tf.pad () . Remplissage 'VALID' signifie pas de remplissage, ce qui signifie que la sortie aura la même taille que l'entrée. Calculons la convolution avec padding=1 sur le même exemple (notez que pour notre noyau, il s'agit du padding 'SAME'). Pour ce faire, il suffit d'ajouter notre tableau avec 1 zéro au début / à la fin: input = [0, 1, 0, 2, 3, 0, 1, 1, 0] .

Ici, vous remarquerez que vous n'avez pas besoin de tout recalculer: tous les éléments restent les mêmes sauf ceux du premier / dernier:

  • 1 = 0 * 2 + 1 * 1 + 0 * 3
  • 3 = 1 * 2 + 1 * 1 + 0 * 3

Donc, le résultat est [1, 8, 11, 7, 9, 4, 3] qui est le même que celui calculé avec TF:

res = tf.squeeze(tf.nn.conv1d(data, kernel, 1, 'SAME'))
with tf.Session() as sess:
    print sess.run(res)

Convolution avec des foulées

Les foulées vous permettent de sauter des éléments en glissant. Dans tous les exemples précédents nous coulissé 1 élément, vous pouvez maintenant glisser s éléments à la fois. Comme nous allons utiliser un exemple précédent, il existe une astuce: le glissement par n éléments équivaut à un glissement de 1 élément et à la sélection de tous les n-èmes éléments.

Donc, si nous utilisons notre exemple précédent avec padding=1 et changez stride en 2, il vous suffit de prendre le résultat précédent [1, 8, 11, 7, 9, 4, 3] et de laisser chaque élément 2 [1, 11, 9, 3] . Vous pouvez le faire dans TF de la manière suivante:

res = tf.squeeze(tf.nn.conv1d(data, kernel, 2, 'SAME'))
with tf.Session() as sess:
    print sess.run(res)


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow