TimeDistributed 具有不同的输入/输出序列长度

数据挖掘 神经网络 lstm rnn
2022-02-25 05:19:41

我正在研究TimeDistributed在我的 LSTM 中使用它是否会提高我的模型的准确性。老实说,我仍然不能 100% 确定具体的用例是什么TimeDistributed,我只是想尝试一下,看看它是否能提高我的准确性。除了盲目的试验/错误,为什么有人会使用TimeDistributed

现在,我的下一个问题可能与我对具体用例的确切含义缺乏了解有关TimeDistributed,但我知道输出TimeDistributed是一个序列,并且该序列与输入序列的长度相同,因为您return_sequences=True在模型的最后一层(在我的例子中都是有状态的)。

在我的例子中,我输入了一个长度为 100 的序列,然后我从该输入序列中预测了一个长度为 3 的序列,但是我收到了这个错误:

检查目标时出错:预期 time_distributed_1 的形状为 (100, 3) 但数组的形状为 (3, 1)

我是否正确假设您只能TimeDistributed在输出序列与输入序列长度相同的情况下使用?

非常感谢

2个回答

我已经为这个问题寻找了很长一段时间的答案,但真的找不到明确的是/否答案。

据我了解, TimeDistributed 确实只适用于类似的输入/输出长度。根据 Jason Brownlee 在他的TimeDistributed 教程的评论部分中所写的内容,他会将不同的输入/输出长度视为 seq2seq/encoder-decoder 问题(他在此处描述)。

如果您找到更好的答案,或者找到一种方法让 TimeDistributed 使用不同的输出大小,请告诉我。


*更新(从下面复制我的评论,格式更好):

实际上,我找到了一个使用 TimeDistributed 的不同解决方案:您可以修剪从TimeDistributed使用Cropping1D层获得的输出序列。所以我的模型现在看起来像这样:

model.add(LSTM(hidden_size, return_sequences=True, input_shape=(num_input_timepoints, 1) ,dropout=0.05)
model.add(TimeDistributed(Dense(1))) 
model.add(Cropping1D(cropping=(num_input_timepoints - num_output_timepoints,0))) # cropping the end 

在您的情况下,它将修剪前 97 个时间点,并为您留下最后 3 个时间点。这将适合您的目标数据的形状。

链接这个.

我的理解(我仍在努力)是使用您的输入序列设置一个初始 LSTM 层并return_sequences设置为False. 然后添加一个RepeatVector层,它只是将上述 LSTM 层的最后一个时间步的输出重复 N 次。将其输入到另一个 LSTM 层return_sequences=True和最后TimeDistributed(Dense(1))一层。

像这样:

model = Sequential()
model.add(LSTM(units = UNITS , input_shape = (input_shape), return_sequences = False)) 
model.add(RepeatVector(N))  
model.add(LSTM(UNITS, return_sequences=True))
model.add(TimeDistributed(Dense(1)))

我从我提供的链接帖子中得到这个。这对我来说很直观,原因如下:

对于具有不同输出大小的“多对多”LSTM 模型,第一个 LSTM 层学习第timesteps一批样本的模式,并对最后一个时间步长进行预测;然后该RepeatVector层重复此输出 N 次。下一个 LSTM 层使用相同的输出预测作为第一个隐藏状态馈入我们试图预测的每个时间步长(我认为)。我真的很想对这部分做一些澄清。

最后,TimeDistributed(Dense(1)))将您想要预测的每个时间步传递到单个Dense节点中以进行最终预测。这将返回 的输出向量(timesteps, feature(s?))

注意:我认为这是一个特别棘手的问题,并且是 Keras 未明确支持的一类问题的解决方法。我会感谢更多在该领域更有经验的人的任何更正,因为我还在学习!