学习笔记:TPGNN

Multivariate Time-Series Forecasting with Temporal Polynomial Graph Neural Networks
利用时间多项式图神经网络的多时间序列预测
期刊:NIPS2022
作者:Yijing LiuQinxian LiuJian-Wei ZhangHaozhe FengZhongwei WangZihan ZhouWei Chen
论文:https://openreview.net/forum?id=pMumil2EJh
代码:https://github.com/zyplanet/TPGNN

!> 学长指出,这篇论文的实验结果并不好(虽然我是因为觉得实验结果好才看的这篇论文,看来还需要找找最先进的论文看看才行啊)

TPGNN模型图(感觉这图画得不怎么样)

复现

GPU: TITAN V
dataset: STSGCN中的PEMS数据集

数据集 节点数量 MAE RMSE MAPE epoch 时间消耗(h)
PEMS03 358 13.93 21.31 11.50 800 13h10min
PEMS04 307 19.26 30.12 12.13 1000 14h50min
PEMS07 883 21.23 33.18 8.64 600 28h
PEMS08 170 15.62 24.28 8.67 1000 7h50min

模型

问题定义

\[已知数据\quad \mathcal{G}^{(t)}=\{\mathcal{V},\mathcal{E}^{(t)},\mathbf{X}^{(t)},\mathbf{W}^{(t)}\} \]

\[模型目标\quad (\mathcal{G}^{(t)}, \mathcal{G}^{(t+1)}, \ldots, \mathcal{G}^{(t+T-1)}) \xrightarrow{F} \mathbf{X}^{(t+T)}, \mathbf{X}^{(t+T+1)}, \ldots,\mathbf{X}^{(t+T+T'-1)} \]

把相关性表示为时间多项式矩阵

有道路连接矩阵 \(W\in\mathbb R^{N\times N}\),和可学习的节点嵌入矩阵 \(E\in\mathbb R^{N\times c}\),利用这两个,我们可以得到一个基础矩阵\(A\in\mathbb R^{N\times N}\)

\[\mathbf{A}=\operatorname{SoftMax}(\operatorname{ReLU}(\mathbf{EE^T}))+\mathbf L \]

其中\(L\)是对称归一化拉普拉斯矩阵\(L=D^{-\frac{1}{2}}(I+W)D^{-\frac{1}{2}}\)。因此,\(A\)是具有一定学习能力,并且受道路连接情况作用的矩阵。利用它,我们这样定义\(t\)时刻的节点相关性:(这里就已经用到了图卷积的方法)

\[\mathbf{W}^{(t)}=\sum_{k=0}^Ka_k^{(t)}\mathbf{A}^k \]

时间序列太长,全部计算效率太低。考虑到交通数据的周期性,设周期为\(T_p\),我们用如下方式计算系数\(a\)(表示为\(\mathbf{\bar a}\in\mathbb R^K\)):(在代码中,\(T_p\)为一天的时间戳数量)

\[(\mathbf{a}^{(t)},\ldots,\mathbf{a}^{(t+T-1)})=(\mathbf{e}_{ts}^{(t\%T_p)},\ldots,\mathbf{e}_{ts}^{((t+T-1)\%T_p)})\mathbf{W}_c \]

\[\mathbf{\bar{a}}=(\bar{a}_0,\bar{a}_1,\ldots,\bar{a}_K)=(\mathbf{a}^{(t)},\ldots,\mathbf{a}^{(t+T-1)})\mathbf{W}_a \]

其中,时间戳嵌入为\((\mathbf{e}_{ts}^{(1)},\ldots,\mathbf{e}_{ts}^{(T_p)})\in\mathbb{R}^{D_e}\),另外两个可学习系数矩阵为\(\mathbf{W}_c\in\mathbb{R}^{D_e\times(K+1)}\)\(\mathbf{W}_a\in\mathbb{R}^{T\times1}\)。然后,通过以下方式计算\(t\)时刻的内在特征:

\[\mathbf{Z}^{(t)}=\Sigma_{k=0}^K\bar{a}_k\mathbf{A}^k\mathbf{X'}^{(t)}\frac{\mathbf{W}_k}{||\mathbf{W}_k||_F} \]

其中\(\mathbf{W}_k\)是可学习系数矩阵,为了避免太大而进行了归一化;\(\mathbf {X'}^{(t)}\in\mathbb R^{N\times D_e}\)是原始数据通过一些处理得到的,暂且表示为\(\mathbf {X'}=SrcProcess(\mathbf X)\),因为不是重点,之后再说。

利用解码器预测

依据上述流程,前\(T\)个时间戳的数据,可以表示为\(\mathbf{Z}^{(t:t+T-1)}\in\mathbb{R}^{T\times N\times D_e}\)。预测的过程参考了Transformer框架,使用了自注意力机制。先预测第一个时间戳的数据:

\[\begin{gathered}\mathbf{E}_X^{(t+T)}=\text{Decoder}(\mathbf{E}_{\mathbf{BOS}},\mathbf{Z}^{(t:t+T-1)}),\\\tilde{\mathbf{X}}^{(t+T)}=\mathbf{E}_X^{(t+T)}\mathbf{W}_{pred},\end{gathered} \]

之后,就利用已经预测出来的数据接着预测。假如说已经预测了\(k\)步,那么第\(k+1\)步就是这样获得的:

\[\begin{gathered}\mathbf{E}_X^{(t+T+k)}=\text{Decoder}((\mathbf{E}_X^{(t+T+k-L_{max})},\ldots,\mathbf{E}_X^{(t+T+k-1)}),\mathbf{Z}),\\\tilde{\mathbf{X}}^{(t+T+k)}=\mathbf{E}_X^{(t+T+k)}\mathbf{W}_{pred}.\end{gathered} \]

\(L_{max}\)是查询的长度(但我没找到相应代码)。

代码实现

一些函数的实现流程

预测的流程

  1. dec_input = trg_pro(E, Z)
  2. dec_output = decoder(dec_input, Z)
  3. dec_output = dec_rdu(dec_output)(一个卷积,作用是将Nxe变为Nx1)
  4. E[i]=dec_output[i]

decoder的实现
多个decoder层:

  • 一个(多头)自注意力,\(q=E, k=v=Z\)
  • 一个位置逐元素前馈(position-wise feed-forward)结构( #不解 这是什么东西)

src_pro的实现

  1. 将特征数(为1)映射成多个隐藏特征
  2. 加上空间嵌入
  3. 加上时间嵌入

trg_pro的实现

  1. 将Z的时间长度映射成1
  2. 将E的特征数(为1)映射成多个隐藏特征
  3. 加上空间嵌入
  4. 将Z和E合并
  5. 加上时间嵌入

位置逐元素前馈的实现

因为没见过,所以记录一下

class PositionwiseFeedForward(nn.Module):
    '''
    A two-feed-forward-layer module
    '''
    def __init__(self, d_in, d_hid, drop_prob=0):
        super().__init__()
        self.w_1 = nn.Linear(d_in, d_hid)  # position-wise
        self.w_2 = nn.Linear(d_hid, d_in)  # position-wise
        self.layer_norm = nn.LayerNorm(d_in, eps=1e-6)
        self.dropout = nn.Dropout(drop_prob)
    def forward(self, x):
        residual = x
        x = self.w_2(F.relu(self.w_1(x)))
        x = self.dropout(x)
        x += residual
        x = self.layer_norm(x)
        return x

小结

可以借鉴的地方:

  1. L+A的结构
  2. 周期的利用
posted @ 2023-10-15 11:00  white514  阅读(209)  评论(10编辑  收藏  举报