对可变长度序列进行训练和预测

Shl*_*rtz 7 python lstm keras tensorflow

分散在我网站上的传感器(相同类型)正在不定期地向我的后端手动报告。在报告之间,传感器聚合事件并将它们作为批处理报告。

以下数据集是序列事件数据的集合,批量收集。例如传感器 1 报告了 2 次。在第一批 2 个事件和第二批 3 个事件上,而传感器 2 报告了 1 次,有 3 个事件。

我想将此数据用作我的火车数据X

sensor_id 批号 时间戳 特征_1 特征_n
1 1 2020-12-21T00:00:00+00:00 0.54 0.33
1 1 2020-12-21T01:00:00+00:00 0.23 0.14
1 2 2020-12-21T03:00:00+00:00 0.51 0.13
1 2 2020-12-21T04:00:00+00:00 0.23 0.24
1 2 2020-12-21T05:00:00+00:00 0.33 0.44
2 1 2020-12-21T00:00:00+00:00 0.54 0.33
2 1 2020-12-21T01:00:00+00:00 0.23 0.14
2 1 2020-12-21T03:00:00+00:00 0.51 0.13

我的目标y是根据传感器收集的所有事件计算得出的分数:
IEsocre_sensor_1 = f([[batch1...],[batch2...]])

sensor_id final_score
1 0.8
2 0.6

我想在每次收集批次时预测y,IE 2 对具有 2 个报告的传感器的预测。


LSTM 模型:
我从 LSTM 模型开始,因为我试图预测事件的时间序列。我的第一个想法是选择一个固定大小的输入,并在收集的事件数量小于输入大小时对输入进行零填充。然后屏蔽填充值:

model.add(Masking(mask_value=0., input_shape=(num_samples, num_features)))
Run Code Online (Sandbox Code Playgroud)

例如:

sensor_id 批号 时间戳 特征_1 特征_n
1 1 2020-12-21T00:00:00+00:00 0.54 0.33
1 1 2020-12-21T01:00:00+00:00 0.23 0.14

如果选择的长度为 5,将产生以下输入:

[
 [0.54, 0.33],
 [0.23, 0.14],
 [0,0],
 [0,0],
 [0,0]
]
Run Code Online (Sandbox Code Playgroud)

但是,我的训练数据中每个传感器报告的事件数量差异很大,一个报告可以收集 1000 个事件,而另一个可以收集 10 个。因此,如果我选择平均大小(假设为 200),一些输入会有很多填充,而其他将被截断,数据将丢失。

我听说过ragged tensors,但我不确定它是否适合我的用例。如何解决这样的问题?

Yoa*_*.Sc 1

我不知道你的模型的具体情况,但 LSTM 的 TF 实现通常期望(batch, seq, features)作为输入。

现在不要假设这是您的batch_id 之一:

data = np.zeros((15,5))

array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
Run Code Online (Sandbox Code Playgroud)

您可以使用(1, 15, 5) 重塑它并将其提供给模型,但是只要您的batch_id长度发生变化,您的序列长度也会发生变化,并且您的模型需要固定序列。

相反,您可以在训练之前重塑数据,以便将batch_id长度作为批量大小传递:

data = data[:,np.newaxis,:] 

array([[[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]],

       [[0., 0., 0., 0., 0.]]])
Run Code Online (Sandbox Code Playgroud)

相同的数据,形状为 (15, 1, 5),但您的模型现在将查看固定长度,1并且样本数量会有所不同。

确保label也重塑你的形象。

据我所知,RNN 和 LSTM 应用于每个时间步骤,并且状态在两次之间重置,但这不会影响模型行为。