web-dev-qa-db-fra.com

Comment créer des lots remplis dans Tensorflow pour les données tf.train.SequenceExample à l'aide de l'API DataSet?

Pour former un modèle LSTM dans Tensorflow, j'ai structuré mes données dans un format tf.train.SequenceExample et les ai stockées dans un fichier TFRecord. J'aimerais maintenant utiliser la nouvelle API DataSet pour générer des lots matelassés pour la formation. Dans la documentation , il existe un exemple d'utilisation de padded_batch, mais je ne peux pas déterminer la valeur de padded_shapes.

Pour lire le fichier TFrecord dans les lots, j'ai écrit le code Python suivant:

import math
import tensorflow as tf
import numpy as np
import struct
import sys
import array

if(len(sys.argv) != 2):
  print "Usage: createbatches.py [RFRecord file]"
  sys.exit(0)


vectorSize = 40
inFile = sys.argv[1]

def parse_function_dataset(example_proto):
  sequence_features = {
      'inputs': tf.FixedLenSequenceFeature(shape=[vectorSize],
                                           dtype=tf.float32),
      'labels': tf.FixedLenSequenceFeature(shape=[],
                                           dtype=tf.int64)}

  _, sequence = tf.parse_single_sequence_example(example_proto, sequence_features=sequence_features)

  length = tf.shape(sequence['inputs'])[0]
  return sequence['inputs'], sequence['labels']

sess = tf.InteractiveSession()

filenames = tf.placeholder(tf.string, shape=[None])
dataset = tf.contrib.data.TFRecordDataset(filenames)
dataset = dataset.map(parse_function_dataset)
# dataset = dataset.batch(1)
dataset = dataset.padded_batch(4, padded_shapes=[None])
iterator = dataset.make_initializable_iterator()

batch = iterator.get_next()

# Initialize `iterator` with training data.
training_filenames = [inFile]
sess.run(iterator.initializer, feed_dict={filenames: training_filenames})

print(sess.run(batch))

Le code fonctionne bien si j'utilise dataset = dataset.batch(1) (aucun remplissage requis dans ce cas), mais lorsque j'utilise la variante padded_batch, le message d'erreur suivant s'affiche:

TypeError: Si la structure peu profonde est une séquence, l'entrée doit également être un séquence. L'entrée a le type:.

Pouvez-vous m'aider à déterminer ce que je devrais passer pour le paramètre padded_shapes?

(Je sais qu'il existe de nombreux exemples de code utilisant des threads et des files d'attente pour cela, mais je préfère utiliser la nouvelle API DataSet pour ce projet.)

9
Marijn Huijbregts

Vous devez passer un tuple de formes ..__ Dans votre cas, vous devriez passer 

dataset = dataset.padded_batch(4, padded_shapes=([vectorSize],[None]))

ou essayer 

dataset = dataset.padded_batch(4, padded_shapes=([None],[None]))

Cochez cette code pour plus de détails. J'ai dû déboguer cette méthode pour comprendre pourquoi cela ne fonctionnait pas pour moi. 

8
Zaher Wanli

Si votre objet Dataset actuel contient un tuple, vous pouvez également spécifier la forme de chaque élément ajouté. 

Par exemple, j'ai un ensemble de données (same_sized_images, Labels) et chaque étiquette a une longueur différente mais le même rang. 

def process_label(resized_img, label):
    # Perfrom some tensor transformations
    # ......

    return resized_img, label

dataset = dataset.map(process_label)
dataset = dataset.padded_batch(batch_size, 
                               padded_shapes=([None, None, 3], 
                                              [None, None]))  # my label has rank 2
1
Dat Nguyen