Keras LSTM-使用来自生成器的Tensorflow数据集API馈送序列数据

时间:2018-09-20 18:43:55

标签: python tensorflow keras lstm recurrent-neural-network

我正在尝试解决如何将数据馈送到LSTM模型进行培训的问题。 (在下面的示例中,我将简化此问题。)我的数据集中的csv文件中具有以下数据格式。

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

任务是根据最近3个时间步中的数据来估计任何将来时间步的输出。一些输入输出示例如下:

示例1: 输入:

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

输出:c

示例2: 输入:

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

输出:d

示例3: 输入:

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

输出:e

当将数据输入模型时,我希望以某种方式对数据进行混洗,以便在训练时不输入连续的序列。 换句话说,理想情况下,我希望一步一步地输入数据序列,例如时间步长3,4,5,在下一步可能步长5,6,7,在下一步可能步长2,3,4,等等上.. 而且我最好不要先以1,2,3,然后以2,3,4,然后是3,4,5等等的方式来填充数据……

在训练我的LSTM网络时,我将Keras与Tensorflow后端一起使用。将数据馈送到fit_generator(...)函数时,我想使用一个生成器。

我的愿望是使用Tensorflow的数据集API从csv文件中获取数据。但是我不知道如何使生成器返回我需要的东西。 如果我使用Tensorflow的数据集API随机整理数据,它将破坏时间步长的顺序。生成器还应返回包含多个序列示例的批次。例如,如果批次大小为2,则可能需要返回2个序列,例如时间步长2、3、4和时间步长6、7、8。

希望我能解释我的问题...是否可以在生成器函数中使用Tensorflow的数据集API来解决此类序列问题,以便如上所述地喂入一批序列? (生成器需要返回形状为[batch_size, length_of_each_sequence, nr_inputs_in_each_timestep]的数据,在我的示例中为length_of_each_sequence=3nr_of_inputs_in_each_timestep=4。)或者这是最好的方法,以仅用Python编写生成器,也许通过使用熊猫..?

附录1:

看到@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))

这是输出:

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

我还不能在csv文件读取中尝试它,但是我认为这种方法应该可以正常工作!

但是正如我所看到的,reshuffle_each_iteration参数没有什么区别。这真的需要吗?将其设置为TrueFalse时,结果不一定相同。这个reshuffle_each_iteration参数应该在这里做什么?

1 个答案:

答案 0 :(得分:2)

我认为this answer可能与您要寻找的东西接近!

您可以通过在窗口上滑动来创建批处理,然后根据情况改组输入。数据集api的shuffle函数具有reshuffle_after_each_iteration参数,如果您想尝试设置随机种子并查看随机输出的顺序,则可能需要将其设置为False。

相关问题