一、引言
引言部分不是论文的重点,主要讲述了交通预测的重要性以及一些传统方法的不足之处。进而推出了自己的模型——STGCN。
二、交通预测与图卷积
第二部分讲述了交通预测中路图和图卷积的概念。
首先理解道路图,交通预测被定义为典型的时间序列预测问题,即根据历史数据预测未来的交通情况。在该工作中,交通网络被建模为图结构,节点表示监控站,边表示监控站之间的连接。
其次是图卷积,由于传统的卷积操作无法应用于图数据,作者介绍了两种扩展卷积到图数据的方法,即扩展卷积的空间定义、谱图卷积。这里需要着重注意谱图卷积,因为STGCN就是采用了傅里叶变换的方法,这里的公式后面也要提到。
三、STGCN结构与原理(重点)
先看整体网络结构:
1. 空域卷积块(图卷积块)
1.1 论文
这里提到了两种方法,即切比雪夫多项式和一阶近似。对应于代码中的 ChebGraphConv 和 GraphConv。
为什么要用切比雪夫多项式计算?因为传统的拉普拉斯计算起来非常复杂,使用了切比雪夫多项式以后,通过使用多项式来表示卷积核,图卷积操作可以在局部化的节点邻域内进行,从而避免了全图的计算。
一阶近似进一步简化了图卷积的计算,将图拉普拉斯算子(公式中的L)的高阶近似简化为一阶。这使得图卷积操作只依赖于当前节点及其直接相邻节点,计算复杂度大幅降低。
1.2 代码(GraphConvLayer)
这里有我加了注释的代码:OracleRay/STGCN_pytorch: The PyTorch implementation of STGCN. (github.com)
时空卷积块和输出层的定义都在 layers.py 中。
ChebGraphConv 类的前向传播方法:
def forward(self, x):
# bs, c_in, ts, n_vertex = x.shape
x = torch.permute(x, (0, 2, 3, 1)) # 将时序维度和顶点维度排列到一起,方便后续的图卷积计算
if self.Ks - 1 < 0:
raise ValueError(
f'ERROR: the graph convolution kernel size Ks has to be a positive integer, but received {self.Ks}.')
elif self.Ks - 1 == 0:
x_0 = x
x_list = [x_0] # 只使用第 0 阶,即不考虑邻居节点的影响,直接使用输入特征
elif self.Ks - 1 == 1:
x_0 = x
# hi 是邻接矩阵的索引,btij 是输入张量 x 的索引,bthj为更新后的特征表示
x_1 = torch.einsum('hi,btij->bthj', self.gso, x) # 邻接矩阵gso和输入特征x进行相乘
x_list = [x_0, x_1] # 使用第 0 阶和第 1 阶的节点信息
elif self.Ks - 1 >= 2:
x_0 = x
x_1 = torch.einsum('hi,btij->bthj', self.gso, x)
x_li