1
votes

Comment créer un remplissage à des longueurs de séquence maximales en batch avec l'API du jeu de données Tensorflow?

J'ai par exemple

data = tf.data.Dataset.from_tensor_slices((X, y))
data = data.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=len(y)))
data = data.batch(batch_size, drop_remainder=False)
data = data.prefetch(2)

Il est facile de faire un remplissage global comme celui-ci

00123
01234
12345

Mais je veux un remplissage dans chaque généré par lot d'API de l'ensemble de données. Par exemple, avec la taille de lot 3, il faut 3 échantillons aléatoires

123
1234
12345

Et le remplir comme ceci

0000000123
0000001234
0000012345
0001234556
1234567890

Je peux le faire dans numpy par exemple, mais voici comment les lots construits dans tf api:

123
1234
12345
1234556
1234567890


0 commentaires

3 Réponses :


0
votes

Si j'ai bien compris, vous pouvez faire:

00123
01234
12345

Sortie:

import os

data = """123
1234
12345"""

lines = data.splitlines()
max_len = max((len(i) for i in lines))

lines = (i.rjust(max_len, '0') for i in lines)
data = os.linesep.join(lines)

print(data)


1 commentaires

Eh bien oui, je peux le faire numpy par exemple, mais je n'ai aucune idée de comment le faire dans tensorflow. Ajout du code du jeu de données tensorflow à la question. Lot construit sur la deuxième ligne, c'est un objet tenseur.



3
votes

Vous pouvez utiliser la méthode padded_batch.

import tensorflow as tf
import numpy as np

def gen():
    yield (np.array([1,2,3]), np.array(1))
    yield (np.array([1,2,3,4]), np.array(0))

data = tf.data.Dataset.from_generator(gen, output_types=(tf.int32, tf.int32))
data = data.apply(tf.contrib.data.shuffle_and_repeat(buffer_size=2))
data = data.padded_batch(10, padded_shapes=([None], []))
iterator = tf.data.Iterator.from_structure(data.output_types, data.output_shapes)
batch = iterator.get_next()
init_op = iterator.make_initializer(data)

with tf.Session() as sess:
    sess.run(init_op)
    batch_out = sess.run(batch)
    print(batch_out)


où max_shape est la taille du tenseur complété que vous voulez.

Je pense que cela ajoutera des zéros de fin au lieu de zéros de tête, mais cela convient probablement toujours à votre objectif.

MODIFIER

Exemple de travail complet:

data.padded_batch(batch_size, padded_shapes=max_shape)


4 commentaires

Je l'ai essayé comme ceci data = data.padded_batch (batch_size, padded_shapes = ([None, None], [None]), drop_remainder = True) mais j'ai obtenu une erreur TypeError: Chaîne binaire ou unicode attendue, tableau obtenu ([[- 264. ], ...


Je ne sais pas si votre erreur est liée. J'ai mis à jour ma réponse pour fournir un exemple fonctionnel complet. Vous devrez peut-être ajuster en fonction de la forme de vos données réelles.


Peut-être est-ce en quelque sorte lié à from_tensor_slices Je crée un notebook avec votre code et votre erreur colab.research.google.com/ conduire /…


From_tensor_slices ne fonctionnera pas pour le ndarray à dimension variable.



0
votes

Si je comprends bien, vous pouvez utiliser keras pad_sequences:

sequence = np.array([[1,2], [1, 2, 3, 4], [1, 2, 3,4, 5, 6]])  

tf.keras.preprocessing.sequence.pad_sequences(sequence, padding='pre', value=0)  

array([[0, 0, 0, 0, 1, 2],  
       [0, 0, 1, 2, 3, 4],  
       [1, 2, 3, 4, 5, 6]])


0 commentaires