我有一个时间序列数据集,用于LSTM-RNN的动作预判输入。该时间序列包含5秒钟的数据,帧率为30 fps(即150个数据点),数据表示面部特征的位置/运动。
为了增加数据集的冗余性并减少过拟合,我从数据集中抽取了长度较小的子序列样本。在这种情况下,我知道子序列的起始和结束帧。
为了批量训练模型,所有时间序列需要具有相同的长度,根据文献中的许多论文,填充不应影响网络的性能。
示例:
原始序列:
1 2 3 4 5 6 7 8 9 10
子序列:
4 5 6 78 9 102 3 4 5 6
考虑到我的网络试图预判一个动作(这意味着当P(action) > 阈值时,从t = 0到T = tmax,它将预测该动作),填充的位置是否重要?
选项1:用零替代原始值
0 0 0 4 5 6 7 0 0 00 0 0 0 0 0 0 8 9 100 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 02 3 4 5 0 0 0 0 0 0
此外,一些时间序列缺少若干帧,但不知道是哪些帧 – 这意味着如果我们只有60帧,我们不知道它们是从0到2秒,从1到3秒等取的。这些在提取子序列之前需要填充。在这种情况下,填充的最佳实践是什么?
提前感谢您。
回答:
LSTM和RNN最强大的属性是它们的参数在时间框架上是共享的(参数在时间框架上重复),但参数共享依赖于这样一个假设:相同的参数可以用于不同的时间步,即前一个时间步与下一个时间步之间的关系不依赖于t,如此处第388页第2段所解释的。
简而言之,理论上在末尾填充零不应改变模型的准确性。我使用理论上这个副词是因为在每个时间步,LSTM的决策依赖于它的细胞状态和其他因素,而这个细胞状态是对过去帧的一种简短总结。据我所知,在你的情况下,这些过去的帧可能是缺失的。我认为你这里有一个小小的权衡。
我更倾向于在末尾填充零,因为这与RNN的基本假设不完全冲突,而且实现和跟踪起来更方便。
在实现方面,我知道TensorFlow在你给出序列和每个样本的实际序列大小后会计算损失函数(例如,对于4 5 6 7 0 0 0 0 0 0,你还需要给出实际大小,这里是4),假设你正在实现选项2。不过,我不知道是否有选项1的实现方法。