/TrafficFlowForecast

利用TensorFlow框架构建LSTM模型做出城市流量的预测

Primary LanguagePython

基于城市网络的交通流量预测

实验背景

在拿到题目后我对基于城市网络的交通流量预测产生了极大地兴趣(真是在济南的经十路上给堵怕了)。在查阅了相关资料后,感觉这个题目一学期可以做完,于是就选择了这个课题进行实验。

交通流量预测任务是智慧交通中的重要组成部分,促进了智慧城市的建设与发展,同时具有极高的实际应用价值,例如高德、滴滴等应用。本课题的主要任务是根据历史的城市区域流量,预测下一个时间片段的城市交通流量网络,可进行短周期或者长周期的预测工作。

实验题目

将北京市地图划分为32x32的网格,每个网格中的数据表示当前时刻进入该区域的车辆流量,任务为预测下一个时刻的整个城市网络中的流量。数据说明:4周的数据,每个时刻组成一个32x32的矩阵,前3周为训练数据(1008),后1周为测试数据(336),测试结果输出每个时刻下测试数据的平均误差结果,误差计算使用RMSE和MAE两种评价指标。每个时刻的间隔为30min,即一天可划分为48个时间片段。

任务图:通过历史的流量数据训练,推测未来的交通流量数据:

![image-20210510214342211](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210510214342211.png)

评价指标:

RMSE均方根误差(RootMeanSquareError),观测值与真值偏差的平方和与观测次数m比值的平方根。

$RMSE(X,h)=\sqrt{\frac{1}{m}\sum_{i=1}^{m}{(h(x^{(t)})-y^{(t)})^2}}$

MAE平均绝对误差(MeanAbsoluteError),观测值与真实值的误差绝对值的平均值。

$MAE(X,h)=\frac{1}{m}\sum_{i=1}^{m}\lvert{h(x^{(t)})-y^{(t)}}\lvert$

1.查看mat中的数据

先查看老师给的数据集的结构,便于之后分析:

得到train和test的shape分别是:

(32, 32, 1008); (32, 32, 336)。

train是一个32x32x1008的数据集(21天的交通数据),

test是一个32x32x336的数据集(7天的交通数据)。

主要的逻辑代码

def readMat(url='/Users/yuanbao/Desktop/机器学习平台及其应用实践/实验!!60分/基于城市网络的交通流量预测/题目/data.mat'):
    """
    返回读取的mat文件为两个矩阵train和test
    :param url: 文件路径
    :return: train(32, 32, 1008)和test矩阵 (32, 32, 336)
    """
    dataFile = url
    data = scio.loadmat(dataFile)

    trainD = data['train']
    testD = data['test']

    return trainD, testD
  
if __name__ == '__main__':
    trainD, testD = readMat()
    print("train",trainD)
    print("test",testD)

2.构建模型(T-GCN)

通过大量查阅相关的论文,最后选择构建T-GCN(基于时空的时间卷积神经网络)模型,来进行预测城市网格的交通流量。

主要参考论文:

https://ieeexplore.ieee.org/abstract/document/8809901

https://ojs.aaai.org/index.php/AAAI/article/view/10735

2.1T-GCN基本概念

T-GCN(temporal graph convolutional network)是基于时空的时间卷积神经网络。由于城市路网拓扑结构的约束以及随时间动态变化的规律,即空间依赖性和时间依赖性,为了同时捕获空间和时间相关性,我们提出了一种基于神经网络的流量预测新方法,即时间图卷积网络(T-GCN)模型,该模型与graph convolutional network(GCN)和gated recurrent unit( GRU)。具体而言,GCN用于学习复杂的拓扑结构以捕获空间依赖性,而门控循环单元用于学习交通数据的动态变化以捕获时间依赖性。然后,将T-GCN模型用于基于城市道路网络的交通量预测。

2.2 需要的数据--数据结构化

为了使用模型,我们需要

一个N x N的邻接矩阵,它描述了N个区域之间的空间关系 一个D x N流量特征矩阵,它描述了N个区域D个连续时间段上的流量随时间的变化。

在这次实验中,由于提供的数据是32x32的区域的1344个时间段(单位半小时)的数据(包括训练数据和测试数据)。所以:

N=32*32=1024

D=1008+336=1344

2.2.1 写入邻接矩阵

写入NxN的位置矩阵

bj_adj:

将一个32x32的图用(1024x1024)的矩阵来表示邻接关系;

这里分为两种情况:

假设区域很小,没有发生堵车,运动的车辆都会离开本区域,那么区域的流量不可能流向自己,即邻接矩阵(i,i)=0.邻接矩阵记录在bj_adj.csv文件中。

假设区域很大,可能存在堵车导致有的运动的车辆未离开本区域,那么区域的流量可能流向自己,即邻接矩阵(i,i)=1.邻接矩阵记录在bj_adj_stay.csv文件中。

主要逻辑代码见write_adj.py

2.2.2 写入流量特征矩阵

bj_flow:

每一个区域在D个连续的时间段内的流量的变化。

将data.mat文件解析成1024个区域的1344个连续时间段内的流量变化写入到bj_flow.csv文件中

主要逻辑代码见write_flow.py

2.3 构建T-GCN模型的理论知识

T-GCN(temporal graph convolutional network)是基于时空的时间卷积神经网络。具体而言,T-GCN模型由两部分组成:图卷积网络(graph convolutional network)和门递归单元(the gated recurrent unit)。如下图所示,我们首先使用历史n个时间序列数据作为输入,利用图卷积网络捕捉城市道路网的拓扑结构,获取空间特征。其次,将得到的具有空间特征的时间序列输入到门递归单元模型中,通过单元间的信息传递,获取时间特征。最后,通过全连通层得到结果。

![image-20210523104304887](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210523104304887.png)

2.3.1 空间依赖性建模

城市道路网络不是二维网格,而是图的形式,这意味着卷积神经网络(CNN)模型不能反映城市道路网络复杂的拓扑结构因此不能准确地捕捉空间依赖关系。所以最终采用能够处理图结构的图卷积网络来捕捉区域之间的空间性特征。

图卷积神经网络(GCN)是图神经网络(参考:https://blog.csdn.net/qq_34911465/article/details/88524599)的一种,同时也是CNN在处理图结构数据方面的推广。

假设节点1是一个中心区域,蓝色节点表示与其邻接的区域,我们通过区域1和周围区域之间的拓扑关系来获取空间特征。具体捕捉过程如下图:

![image-20210523110747731](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210523110747731.png)

理论基础

给定邻接矩阵A和特征矩阵X,GCN模型会在傅立叶域中构造一个过滤器。 过滤器作用在图的节点上,通过其一阶邻域捕获节点之间的空间特征,然后可以通过堆叠多个卷积层来构建GCN模型,可以将其表示为:

$H^{l+1}=\sigma(\widetilde{D}^{-\frac{1}{2}}\widetilde{A}\widetilde{D}^{-\frac{1}{2}}H^{l}\theta^{l})$

其中$\widetilde{A}=A+I_{N}$是添加的自连接矩阵,$I_{N}$是单位矩阵,D是度矩阵,$\widetilde{D}=\sum_{j}A_{ij}$,$H^{l}$是$l$层的输出,$\theta^{l}$包含该层的参数,而$\sigma(.)$表示非线性模型的sigmoid激活函数。

在这项研究中,选择2层GCN模型以获得空间依赖性,可以将其表示为:

$f(X,A)=\sigma(\widehat{A}ReLU(\widehat{A}XW_{0})W_{1})$

$\widehat{A}=\widetilde{D}^{-\frac{1}{2}}\widetilde{A}\widetilde{D}^{-\frac{1}{2}}$其中表示预处理步骤,$W_{0}\in{R^{PXH}}$表示从输入层到隐藏层的权重矩阵,$P$是特征矩阵的长度,$H$是隐藏单元数,$W_{1}\in{R^{HXT}}$表示从隐藏层到输出层的权重矩阵。 $f(X,A)\in{R^{NXT}}$代表预测输出长度$T$.$ReLU()$代表精密线性单元,这是现代深度神经网络中经常使用的激活层。

2.3.2 时间依赖性建模

获取时间相关性是交通预测的另一个关键问题。目前,处理序列数据最常用的神经网络模型是递归神经网络(RNN)。然而,由于诸如梯度消失和梯度爆炸等缺陷,传统的递归神经网络在长期预测中存在局限性。LSTM模型和GRU模型是递归神经网络的变体,已经证明可以解决上述问题。LSTM和GRU的基本原理大致相同。它们都使用门控机制来记忆尽可能多的长期信息,对各种任务同样有效。但是,由于LSTM模型结构复杂,训练时间较长,而GRU模型结构相对简单,参数较少,训练速度较快。具体结构如下图:

LSTM结构图:

img

GRU结构图:

![image-20210523144324330](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210523144324330.png)

LSTM和GRU对比的阅读文章:https://zhuanlan.zhihu.com/p/32481747;https://www.cnblogs.com/zyly/p/9029591.html。因此,我们选择GRU模型来获取流量数据的时间相关性。

理论基础

如上图GRU结构图,$h_{t-1}$表示在时间$t-1$处的隐藏状态; $x_{t}$表示时间$t$的交通信息; $r_{t}$是复位门,用于控制前一时刻状态信息的忽略程度; $u_{t}$是更新门,用于控制前一次状态信息进入当前状态的程度; $c_{t}$是在时间$t$存储的存储内容; $h_{t}$是时间$t$的输出状态。 GRU以时刻$t-1$的隐藏状态和当前的交通信息作为输入获取时刻$t$的交通信息,虽然在当前时刻捕获交通信息,但模型仍保留了历史交通信息的变化趋势,并具有捕获时间依赖性的能力。

2.3.3 时间图卷积网络(T-GCN)建模

T-GCN的结构图:

![image-20210523145917481](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210523145917481.png)

上图所示,左侧是时空流量预测的过程,右侧是T-GCN单元的具体结构,$h_{t-1}$表示时间$t-1$的输出,GC是图卷积过程, $u_{t}$,$r_{t}$分别是在时间$t$处的更新门和复位门,而$h_{t}$表示在时间$t$处的输出。

理论基础

具体的计算过程如下所示。$f(A,X_{t})$表示图卷积过程,并在之前定义$f(X,A)=\sigma(\widehat{A}ReLU(\widehat{A}XW_{0})W_{1})$。$*$表示逐点乘法。$W$和$b$表示训练过程中的权重和偏差。

$u_{t}=\sigma(W_{u}[f(A,X_{t}),h_{t-1}]+b_u)$

$r_{t}=\sigma(W_{r}[f(A,X_{t},h_{t-1})]+b_{r})$

$c_{t}=tanh(W_{c}[f(A,X_{t}),(r_{t}*h_{t-1})]+b_{c})$

$h_{t}=u_{t}*h_{t-1}+(1-u_{t})*c_{t}$

2.3.4 损失函数

理论基础

在训练过程中,目标是使区域中实际流量与预测值之间的误差最小。 我们使用$Y_{t}$和$\widehat{Y}{t}$分别表示实际区域流量和预测区域流量。 T-GCN模型的损失函数如下。第一项用于最小化实际交通速度与预测之间的误差。 第二项$L{reg}$是有助于避免过度拟合问题的$L_{2}$正则化项,而$\lambda$是超参数。加入正则化项$L_{reg}$防止模型过拟合。

$loss=||Y_{t}-\widehat{Y}{t}||+\lambda L{reg}$

2.4 通过TensorFlow框架构建T-GCN模型并训练模型

主要通过TensorFlow框架进行构建GCN单元和GRU单元,最后组成T-GCN模型,进行训练。

依赖的框架和python包的版本:

python:3.7
tensorflow:1.15.0
tensorBoard:1.15.0
numpy:1.20.3
pandas:1.2.4
pip:21.0.1
scipy:1.6.3
matplotlib:3.4.2

2.4.1 数据预处理

导入数据集:

分为bj-区域不能自己连通自己;

bj2-区域可以自己连通自己。

划分训练数据和测试数据:

按百分比进行划分,因为1008/(1008+336)=0.75.那么train_rate训练数据比例占总数据的75%。

划分输入时间步长和预测时间步长(30min单位):

设置输入步长是11(5h30min),输出步长是1.

邻接矩阵的归一化

在calculate_laplacian中对邻接矩阵进行归一化。

代码见input_data.py和util.py

2.4.2 构建T-GCN模型

在tgcn.py中对T-GCN模型进行初始化,在TGCN函数中实现对T-GCN网络的构建。

tgcn.py中的_gc函数用于图卷积获取空间特征,call函数实现对gru的初始化和获取时间特征。

通过tensorboard展示最终模型的计算图(输出文件在logs目录下):

![image-20210527223015518](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210527223015518.png)

![image-20210527223030167](/Users/yuanbao/Library/Application Support/typora-user-images/image-20210527223030167.png)

逻辑代码见tgcn.py

2.4.3 训练模型

训练过程中将loss作为优化器,同时记录训练过程中的rmse值,mae值和在测试集上的rmse值,mae值。loss即上面理论基础的损失函数,训练过程中力求损失函数值的最小化。

在整个实验过程中分为200、500、1000和2000轮进行测试。

分别使用32个门单元,64个GRU门单元、100个GRU门单元和128个GRU门单元。

设置调节流量留在本区域的权重分别为1,2。

分别将每轮训练的结果写入out\result目录下的result.txt文件下,将最后test_rmse最小的数据进行可视化,并且写入tgcn目录下。

逻辑代码见main.py

2.4.4 训练结果及可视化

bj数据集

bj2数据集

逻辑代码详见visualization.py

3.实验感悟

通过这次实验深刻的理解了卷积神经网络、图卷积神经网络、递归神经网络和GRU在TensorFlow框架中的如何实现和如何使用它们去构建自己的深度网络模型。同时也锻炼了自己阅读英文论文和学习前沿算法的能力。

同时也看到了构建的T-GCN模型在时空流量预测方面的良好表现,如果继续优化该模型并获取到真实的城市流量数据,就可以将模型部署到高德地图等导航上面去,提醒人们避开流量大的区域,从而优化城市交通,这样能够方便我们的生活,这正是深度学习的魅力所在。

经过这学期课程理论的学习和动手构建自己的深度学习模型,从而对深度学习更感兴趣了。同时也看到深度学习算法确实在大数据的背景下有着强大的能力来改变我们的生活,总之收获颇丰,未来可期!