STGCN解读(论文+代码)

一、引言

        引言部分不是论文的重点,主要讲述了交通预测的重要性以及一些传统方法的不足之处。进而推出了自己的模型——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
T-GCN(Temporal Graph Convolutional Network)是一种用于时间序列分类和预测的深度学习模型。它的核心思想是将时间序列数据表示成一个图结构,然后利用图卷积神经网络(GCN)对图进行卷积操作,从而实现时间序列数据的特征提取和预测。 以下是 T-GCN 模型的代码解读: ```python class TGCN(nn.Module): def __init__(self, num_nodes, in_channels, out_channels, K, p): super(TGCN, self).__init__() self.K = K self.p = p self.num_nodes = num_nodes self.conv1 = nn.ModuleList() self.conv2 = nn.ModuleList() self.conv3 = nn.ModuleList() self.conv4 = nn.ModuleList() self.conv5 = nn.ModuleList() self.conv6 = nn.ModuleList() for i in range(K): self.conv1.append(GCNConv(in_channels, 64)) self.conv2.append(GCNConv(64, 64)) self.conv3.append(GCNConv(64, 64)) self.conv4.append(GCNConv(64, 128)) self.conv5.append(GCNConv(128, 128)) self.conv6.append(GCNConv(128, out_channels)) def forward(self, x, A): x = x.reshape(self.num_nodes, self.p, -1) for i in range(self.K): x1 = self.conv1[i](x.view(self.num_nodes, -1), A) x1 = F.relu(x1) x2 = self.conv2[i](x1, A) x2 = F.relu(x2) x3 = self.conv3[i](x2, A) x3 = F.relu(x3) x4 = self.conv4[i](x3, A) x4 = F.relu(x4) x5 = self.conv5[i](x4, A) x5 = F.relu(x5) x6 = self.conv6[i](x5, A) if i == 0: res = x6 else: res += x6 x = torch.cat([x[:, 1:, :], x6.unsqueeze(1)], dim=1) return res ``` 这个模型的输入是一个形状为 `(num_nodes, p, in_channels)` 的张量 `x`,表示有 `num_nodes` 个节点、每个节点 `p` 个时间步、每个时间步 `in_channels` 个特征。`A` 是形状为 `(num_nodes, num_nodes)` 的邻接矩阵,表示节点之间的联系。 首先,模型将 `x` reshape 成 `(num_nodes, p, -1)` 的形状,其中 `-1` 表示特征维度。接着,模型利用 `nn.ModuleList` 定义了 6 层 GCN,每层 GCN 都包含了若干个 `GCNConv` 层。在每层 GCN 中,模型将输入 `x` 进行卷积,并利用 ReLU 激活函数进行非线性转换。最后一层 GCN 的输出作为该层的输出 `x6`。 在每个时刻 `i`,模型将 `x6` 加到之前的结果 `res` 中,并将 `x` 中除了第一个时间步以外的所有时间步和 `x6` 的第一个时间步拼接在一起,得到新的 `x`。这个过程会重复执行 `K` 次,最终模型的输出就是 `res`。 总体来说,T-GCN 模型是一个基于 GCN 的循环神经网络,可以对时间序列数据进行建模和预测。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值