2017-08-30 60 views
8

szkoleniowo modelu LSTM w Tensorflow, mam strukturę moich danych w formacie tf.train.SequenceExample i przechowywać go w TFRecord złożyć. Chciałbym teraz użyć nowego interfejsu DataSet API do generowania wyściełanych partii do szkolenia. W the documentation znajduje się przykład użycia padded_batch, ale dla moich danych nie mogę określić, jaka powinna być wartość padded_shapes.Jak utworzyć wyściełane partie w Tensorflow dla danych tf.train.SequenceExample przy użyciu DataSet API?

Do odczytu pliku TFrecord do partii, które napisałem następujący kod Python:

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)) 

Kod działa dobrze, jeśli mogę użyć dataset = dataset.batch(1) (nie potrzebne w tym przypadku dopełnienie), ale kiedy używam padded_batch wariant, pojawia się następujący błąd:

TypeError: If shallow structure is a sequence, input must also be a sequence. Input has type: .

możesz mi pomóc dowiedzieć się, co należy przejść do padded_shapes parametrów?

(wiem, że jest wiele przykładowy kod przy użyciu wątków i kolejki do tego, ale wolałbym użyć nowego DataSet API dla tego projektu)

+0

Dzięki Marijn! Twoje pytania bardzo mi pomogły! –

Odpowiedz

6

Trzeba zdać krotki kształtów. W twoim przypadku należy przekazać

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

lub spróbuj

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

Sprawdź to code więcej szczegółów. Musiałem debugować tę metodę, aby dowiedzieć się, dlaczego to nie działa dla mnie.

+0

Dzięki! To ma wiele sensu. Dla mojego przykładu działało: 'padded_shapes = ([None, vectorSize], [None])'. Pierwszy tensor to lista wektorów o wymiarach vectorSize, a druga to lista z etykietami całkowitymi. –

+0

Tak samo jak dopełnienie, "padded_shapes" jest wrażliwe na typ zagnieżdżonej struktury (jeśli zbiór danych zwraca krotkę, padded_shapes również powinna być krotką, a nie listą) – Conchylicultor

0

Jeśli bieżący obiekt Dataset zawiera krotkę, można również określić kształt każdego elementu wyściełanego.

Na przykład mam zbiór danych (same_sized_images, Labels), a każda etykieta ma inną długość, ale taką samą pozycję.

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