Keras LSTM: datos de secuencia de alimentación con el conjunto de datos Tensorflow API desde el generador

Estoy tratando de resolver cómo puedo enviar datos a mi modelo LSTM para la capacitación. (Simplificaré el problema en mi ejemplo a continuación). Tengo el siguiente formato de datos en archivos csv en mi conjunto de datos.

Timestep Feature1 Feature2 Feature3 Feature4 Output 1 1 2 3 4 a 2 5 6 7 8 b 3 9 10 11 12 c 4 13 14 15 16 d 5 17 18 19 20 e 6 21 22 23 24 f 7 25 26 27 28 g 8 29 30 31 32 h 9 33 34 35 36 i 10 37 38 39 40 j 

La tarea es estimar la Salida de cualquier paso de tiempo futuro en base a los datos de los últimos 3 pasos de tiempo. Algunos ejemplos de entrada-salida son los siguientes:

Ejemplo 1: Entrada:

 Timestep Feature1 Feature2 Feature3 Feature4 1 1 2 3 4 2 5 6 7 8 3 9 10 11 12 

Salida: c

Ejemplo 2: Entrada:

 Timestep Feature1 Feature2 Feature3 Feature4 2 5 6 7 8 3 9 10 11 12 4 13 14 15 16 

Salida: d

Ejemplo 3: Entrada:

 Timestep Feature1 Feature2 Feature3 Feature4 3 9 10 11 12 4 13 14 15 16 5 17 18 19 20 

Salida: e

Y cuando alimente los datos al modelo, me gustaría mezclar los datos de manera que no alimente secuencias consecutivas cuando entreno. En otras palabras, lo ideal sería alimentar las secuencias de datos como pasos de tiempo 3,4,5 en un paso, tal vez pasos de 5,6,7 en el siguiente paso, y tal vez 2,3,4 en el siguiente paso, y así en … Y, preferiblemente, no quiero alimentar los datos como 1,2,3 primero, luego 2,3,4 , luego 3,4,5 , y así sucesivamente …

Al entrenar mi red LSTM, estoy usando Keras con backend Tensorflow. Me gustaría usar un generador al fit_generator(...) mis datos a la función fit_generator(...) .

Mi deseo es usar la API de conjunto de datos de Tensorflow para obtener los datos de los archivos csv. Pero no pude averiguar cómo hacer que el generador devuelva lo que necesito. Si mezclo los datos con la API del conjunto de datos de Tensorflow, destruirá el orden de los pasos de tiempo. El generador también debe devolver lotes que incluyan múltiples ejemplos de secuencias. Por ejemplo, si el tamaño del lote es 2, es posible que deba devolver 2 secuencias, como los pasos de tiempo 2,3,4 y los pasos de tiempo 6,7,8.

Con la esperanza de que pudiera explicar mi problema … ¿Es posible usar la API del conjunto de datos de Tensorflow en una función de generador para este problema de secuencia, de modo que pueda alimentar lotes de secuencias como expliqué anteriormente? (El generador necesita devolver datos con la forma [batch_size, length_of_each_sequence, nr_inputs_in_each_timestep] , donde length_of_each_sequence=3 y nr_of_inputs_in_each_timestep=4 en mi ejemplo.) O es la mejor manera de hacer esto para escribir un generador en Python. Pandas ..?

ANEXO 1:

He hecho el siguiente experimento después de ver la respuesta de @kvish.

 import tensorflow as tf import numpy as np from tensorflow.contrib.data.python.ops import sliding sequence = np.array([ [[1]], [[2]], [[3]], [[4]], [[5]], [[6]], [[7]], [[8]], [[9]] ]) labels = [1,0,1,0,1,0,1,0,1] # create TensorFlow Dataset object data = tf.data.Dataset.from_tensor_slices((sequence, labels)) # sliding window batch window_size = 3 window_shift = 1 data = data.apply(sliding.sliding_window_batch(window_size=window_size, window_shift=window_shift)) data = data.shuffle(1000, reshuffle_each_iteration=False) data = data.batch(3) #iter = dataset.make_initializable_iterator() iter = tf.data.Iterator.from_structure(data.output_types, data.output_shapes) el = iter.get_next() # create initialization ops init_op = iter.make_initializer(data) NR_EPOCHS = 2 with tf.Session() as sess: for e in range (NR_EPOCHS): print("\nepoch: ", e, "\n") sess.run(init_op) print("1 ", sess.run(el)) print("2 ", sess.run(el)) print("3 ", sess.run(el)) 

Y aquí está la salida:

 epoch: 0 1 (array([[[[6]],[[7]],[[8]]], [[[1]],[[2]],[[3]]], [[[2]],[[3]],[[4]]]]), array([[0, 1, 0], [1, 0, 1], [0, 1, 0]], dtype=int32)) 2 (array([[[[7]],[[8]],[[9]]], [[[3]],[[4]],[[5]]], [[[4]],[[5]],[[6]]]]), array([[1, 0, 1], [1, 0, 1], [0, 1, 0]], dtype=int32)) 3 (array([[[[5]],[[6]],[[7]]]]), array([[1, 0, 1]], dtype=int32)) epoch: 1 1 (array([[[[2]],[[3]],[[4]]], [[[7]],[[8]],[[9]]], [[[1]],[[2]],[[3]]]]), array([[0, 1, 0], [1, 0, 1], [1, 0, 1]], dtype=int32)) 2 (array([[[[5]],[[6]],[[7]]], [[[3]],[[4]],[[5]]], [[[4]],[[5]],[[6]]]]), array([[1, 0, 1], [1, 0, 1], [0, 1, 0]], dtype=int32)) 3 (array([[[[6]],[[7]],[[8]]]]), array([[0, 1, 0]], dtype=int32)) 

No pude probarlo en la lectura de archivos csv todavía, pero creo que este enfoque debería estar funcionando bastante bien.

Pero como lo veo, el parámetro reshuffle_each_iteration está haciendo ninguna diferencia. ¿Es esto realmente necesario? Los resultados no son necesariamente idénticos cuando se establece en True o False . ¿Qué se supone que hace este parámetro reshuffle_each_iteration aquí?

¡Creo que esta respuesta podría estar cerca de lo que estás buscando!

Puede crear lotes deslizándose sobre las ventanas y luego barajar la entrada en su caso. La función de orden aleatorio de la api del conjunto de datos tiene un parámetro reshuffle_after_each_iteration, que probablemente querrá establecer en False si desea experimentar con establecer una semilla aleatoria y observar el orden de las salidas barajadas.