为 LSTM-RNN 训练填充时间序列子序列

Posted

技术标签:

【中文标题】为 LSTM-RNN 训练填充时间序列子序列【英文标题】:Padding time-series subsequences for LSTM-RNN training 【发布时间】:2017-10-23 05:22:50 【问题描述】:

我有一个时间序列数据集,我将其用作 LSTM-RNN 的输入以进行动作预测。时间序列包括 30 fps 的 5 秒时间(即 150 个数据点),数据表示面部特征的位置/移动。

我从我的数据集中抽取额外的较小长度的子序列,以便在数据集中添加冗余并减少过度拟合。在这种情况下,我知道子序列的开始和结束帧。

为了批量训练模型,所有时间序列需要具有相同的长度,并且根据文献中的许多论文,padding 不应影响网络的性能。

例子:

原序列:

 1 2 3 4 5 6 7 8 9 10

子序列:

4 5 6 7
8 9 10
2 3 4 5 6

考虑到我的网络正在尝试预期一个动作(这意味着只要 P(action) > 阈值,它从 t = 0 到 T = tmax,它就会预测那个动作)填充物去哪里重要吗?

选项 1:用零替换原始值

0 0 0 4 5 6 7 0 0 0
0 0 0 0 0 0 0 8 9 10
0 2 3 4 5 6 0 0 0 0

选项 2:最后全为零

4 5 6 7 0 0 0 0 0 0 
8 9 10 0 0 0 0 0 0 0
2 3 4 5 0 0 0 0 0 0

此外,一些时间序列丢失了一些帧,但不知道它们是哪些 - 这意味着如果我们只有 60 帧,我们不知道它们是否是从 0 到 2 秒,从 1 到 3 秒等。这些都需要在子序列被采用之前进行填充。在这种情况下,填充的最佳做法是什么?

提前谢谢你。

【问题讨论】:

【参考方案1】:

如果你有可变长度的序列,pytorch 提供了一个实用函数torch.nn.utils.rnn.pack_padded_sequence。使用此功能的一般工作流程是

from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
embedding = nn.Embedding(4, 5)
rnn = nn.GRU(5, 5)

sequences = torch.tensor([[1,2,0], [3,0,0], [2,1,3]])
lens = [2, 1, 3] # indicating the actual length of each sequence

embeddings = embedding(sequences)
packed_seq = pack_padded_sequence(embeddings, lens, batch_first=True, enforce_sorted=False)

e, hn = rnn(packed_seq)

可以收集每个token的嵌入

e = pad_packed_sequence(e, batch_first=True)

使用这个函数比自己填充要好,因为torch 将限制 RNN 只检查实际序列并在填充标记之前停止。

【讨论】:

【参考方案2】:

最好在一开始就填充零,正如本文所建议的Effects of padding on LSTMs and CNNs,

虽然 post padding 模型在 6 个 epoch 时效率达到顶峰,然后开始过度拟合,但它的准确性远低于 pre-padding。

查看表1,pre-padding(开头补零)的准确率在80%左右,而post-padding(最后补零)的准确率只有50%左右

【讨论】:

【参考方案3】:

一般来说,LSTM 和 RNN 最强大的属性是它们的参数在时间范围内共享(参数 recur 在时间范围内),但参数共享依赖于假设相同的参数可以用于不同的时间步,即前一个时间步和下一个时间步之间的关系依赖于 t,如 here in page 388, 2nd paragraph 解释的那样。

简而言之,在末尾填充零,理论上不应该改变模型的准确性。我使用了副词理论上,因为在每个时间步长 LSTM 的决定取决于它的细胞状态以及其他因素,而这种细胞状态是过去帧的简短总结。据我了解,您的情况可能缺少过去的帧。我认为你在这里需要做一些权衡。

我宁愿在最后填充零,因为它不会与 RNN 的基本假设完全冲突,并且更便于实现和跟踪。

在实现方面,我知道 tensorflow 会在您给它序列和每个样本的实际序列大小后计算损失函数(例如,对于 4 5 6 7 0 0 0 0 0 0,您还需要给它实际的size 此处为 4)假设您正在实施选项 2。不过,我不知道是否有选项 1 的实施。

【讨论】:

谢谢,很有帮助!

以上是关于为 LSTM-RNN 训练填充时间序列子序列的主要内容,如果未能解决你的问题,请参考以下文章

基于LSTM-RNN的深度学习网络的训练对比matlab仿真

2021-12-02:给定一个字符串str,和一个正数k。 返回长度为k的所有子序列中,字典序最大的子序列。 来自腾讯。

数据结构中已知前序序列和中序序列,怎么得出后序序列,谢谢回答!

51Nod1255 字典序最小的子序列

数列(NOIP17提高模拟训练11)

最长回文子序列