web-dev-qa-db-fra.com

Comment entrer une liste de listes de différentes tailles dans tf.data.Dataset

J'ai une longue liste de listes d'entiers (représentant des phrases de tailles différentes) que je veux alimenter à l'aide de la bibliothèque tf.data. Chaque liste (des listes de listes) a une longueur différente, et j'obtiens une erreur, que je peux reproduire ici:

t = [[4,2], [3,4,5]]
dataset = tf.data.Dataset.from_tensor_slices(t)

L'erreur que je reçois est:

ValueError: Argument must be a dense tensor: [[4, 2], [3, 4, 5]] - got shape [2], but wanted [2, 2].

Y a-t-il un moyen de faire cela?

EDIT 1: Soyons clairs: je ne veux pas ajouter de liste à la liste de saisie (c’est une liste de phrases contenant plus d’un million d’éléments, de longueurs variables). Je souhaite utiliser la bibliothèque tf.data pour alimenter manière appropriée, une liste de listes de longueur variable.

9
Escachator

Vous pouvez utiliser tf.data.Dataset.from_generator() pour convertir n’importe quel objet Python itératif (comme une liste de listes) en une Dataset:

t = [[4, 2], [3, 4, 5]]

dataset = tf.data.Dataset.from_generator(lambda: t, tf.int32, output_shapes=[None])

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

with tf.Session() as sess:
  print(sess.run(next_element))  # ==> '[4, 2]'
  print(sess.run(next_element))  # ==> '[3, 4, 5]'
10
mrry

En plus de la réponse de @ mrry, le code suivant est également possible si vous souhaitez créer une paire (images, étiquettes):

import itertools
data = tf.data.Dataset.from_generator(lambda: itertools.izip_longest(images, labels),
                                      output_types=(tf.float32, tf.float32),
                                      output_shapes=(tf.TensorShape([None, None, 3]), 
                                                     tf.TensorShape([None])))

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

with tf.Session() as sess:
    image, label = sess.run(next_element)  # ==> shape: [320, 420, 3], [20]
    image, label = sess.run(next_element)  # ==> shape: [1280, 720, 3], [40]
0
Dat Nguyen

Je ne pense pas que tensorflow supporte des tenseurs avec un nombre variable d'éléments le long d'une dimension donnée.

Cependant, une solution simple consiste à compléter les listes imbriquées par des zéros à la fin (si nécessaire):

t = [[4,2], [3,4,5]]
max_length = max(len(lst) for lst in t)
t_pad = [lst + [0] * (max_length - len(lst)) for lst in t]
print(t_pad)
dataset = tf.data.Dataset.from_tensor_slices(t_pad)
print(dataset)

Les sorties:

[[4, 2, 0], [3, 4, 5]]
<TensorSliceDataset shapes: (3,), types: tf.int32>

Les zéros ne devraient pas être un gros problème pour le modèle: sémantiquement, ce sont juste des phrases supplémentaires de taille zéro à la fin de chaque liste de phrases réelles.

0
scrpy