毕业论文——基于xxLSTM模型的移动对象位置预测
- 2020 年 3 月 3 日
- 筆記
本文简要概述一下我的毕业论文思路,完整可执行代码大概在5月左右开源在Github,主要是为了证明学术诚信,而且太早开源不好,等我快要答辩了再开源
我在一年前写过一篇论文——基于灰色Markov模型的移动对象位置预测研究
当时论文的侧重点主要是研究如何弥补Markov无法揭示整体数据的规律,所以使用了一个简单的回归模型。先用这个回归模型揭示数据的整体规律,然后用Markov对预测结果进行修正,因为Markov能挖掘出相邻时刻数据之间的关系
这次毕业论文本来是打算研究关于NLP的相关内容。但是和指导老师商量了下,他还是推荐我继续完善移动位置预测的问题,所以就继续做这个了
这次论文的大体思路还是不变,依旧采用回归+Markov,只不过把之前比较low的回归模型换成循环神经网络RNN的变种——LSTM
RNN存在的问题是不好训练,很容易产生梯度爆炸或者梯度弥散,具体原因我写在了这篇博客
而LSTM由于其内部独特的结构:遗忘门、输入门、输出门可以很好的避免训练困难的问题,而且由于有这些特殊门的存在,还可以很好的控制记住历史数据的能力。所以我的回归模型就选用的LSTM
我使用的数据集是微软开放的GeoLife,里面包含的字段有lat、lng、zero、alt、days、date、time,每个字段之间的值用逗号分隔,如下图所示

真正有用的只有lat和lng这两列的数据
由于Markov无法对二维数据进行操作,所以我将经度和纬度分开进行预测,然后分别用Markov修正
具体细节
细节实在是太多了,想到哪写到哪
首先,LSTM需要设定一个窗口大小step
,即每次送入几个数据,预测下一个数据。例如我现在有序列[1,2,3,4,5,6],设定窗口大小为3,那么整个输入数据就变为[[1,2,3],[2,3,4],[3,4,5],[4,5,6]],而且他们的输出分别需要接近y=[4,5,6]。使用的Loss Function是MSELoss
第一个问题就来了,窗口大小应该设为多少,按照很多论文里面所讲的,一般设置为2-6。我先试了一下2,出现了滞后的问题,即预测值比真实值从图上来看有些滞后。假设$t$时刻真实值是最大值,但是预测值在$t+1$时刻才是最大值,这就是滞后。具体情况见下图

然后我试了一下6,效果也不好,具体来说就是太平滑,似乎是因为窗口大小太大,导致预测出来的数据时效性变差了,被不相干的数据"平均"了。具体情况见下图

总结一下就是,窗口太小,会导致预测值比真实值滞后;窗口太大,网络很难学到细节。这个问题首先应该设定一个比较合适的窗口大小,但是你会发现还会出现一点滞后的问题。具体解决方案现在还不能说
其次,从数据上也能看出,基本上是相隔5秒采集一次经纬度点。5秒,一个人根本移动不了多远,所以也就导致经度和纬度整体变化并不大,最多也只是$10^{-5}$量级的大小。如果不处理一下直接让网络训练,Loss很难降下来,效果会很差
解决方法很简单,将数据做一个标准化即可,这样所有的值都能压缩到[0,1]区间内,放大了所有数据间的变化,避免模型不收敛的问题
最后一个细节,LSTM后面肯定要跟一个Fully Connected Layer,主要是做数据的维度变换,我们只需要一个输出值。那么问题来了,FC层到底应该怎么设置?几层隐藏层比较好?中间要不要Dropout?激活函数选什么?答案是,一层即可。经过我多次实验,我发现全连接层像一个"猪队友",层数越多问题越大,会导致LSTM的训练功亏一篑。本来LSTM已经把握好了整体数据的规律,最后一个全连接层就行了,你非要设置好几层的全连接层,给人一种本末倒置的感觉,到底是LSTM学到的规律重要,还是最后全连接层胡乱训练重要?
一些技巧
在LSTM中我设置了Dropout=0.1
,主要是为了防止在训练集上过拟合,毕竟LSTM还是很强大的
Linear层我使用何凯明初始化方法,初始化了其中的所有weight,主要是希望能够训练的更快,以及避免随机初始化的一些问题
Epoch=1000
,数据标准化之后,再加上前面的技巧,Loss降得很快,为了避免过拟合,所以Epoch设的比较小
使用了Learning Rate Decay,初始Learning Rate设为lr=1.2e-2
,每隔50个epoch,乘以gamma=0.9
。主要还是上面的原因,Loss降的很快,所以lr也应该慢慢变小,避免Loss出现大幅抖动。最后训练的Loss如下图

最终训练&测试的结果如下图

展望
其实我还有很多想法,但是由于5月就要答辩了,没有那么多时间一个一个做实验。我分享几个
- 利用CNN来做时间序列预测。把整个序列画在图上,把这张图作为输入,进行训练,训练出一个相似的图出来,这样也可以达到预测的效果。不过我想了一下,由于CNN具有平移不变性,可能"滞后"的问题会更加严重,不过如果卷积核的SIze设为1应该会好一些
- 利用EMD将时间序列进行分解,然后对分解的所有序列进行预测,再将这些序列进行叠加
- 修改Loss,使用MSELoss和KLDivLoss(KLDivergence)组合的Loss。MSELoss计算两个值之间的接近程度,KLDivergence计算两个曲线分布的接近程度