ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STGCN解析:图卷积与门控卷积如何实现交通时空预测

STGCN解析:图卷积与门控卷积如何实现交通时空预测 读时空序列预测方向的论文Graph Convolutional Networks 这一支是绕不开的。今天这篇笔记的主角是 STGCN——Spatio-Temporal Graph Convolutional Networks: A Deep Learning Framework for Traffic Forecasting发在 AAAI 2018作者是 Bing Yu、Haoteng Yin、Zhanxing Zhu。论文解决的是交通预测里的短期流量/速度预测问题路网上散布着大量传感器每个传感器每 5 分钟上报一次数据任务是利用过去 1 小时的历史观测预测未来 15 到 60 分钟的路况。这个任务表面看着像时间序列预测但难就难在传感器之间不是孤立的一条路堵了会波及相邻几条路。STGCN 的核心做法是把路网建成一张图、传感器当节点、历史数据当节点上的时序信号用图卷积抓空间依赖、用门控因果卷积抓时间依赖整个过程不碰 RNN。这篇笔记我从任务定义、模型结构、实现细节、实验结果到复现踩坑完整过了一遍适合刚接触图神经网络和时空预测的读者也适合想拿 STGCN 当基线模型做对比的研究者。1. 这篇论文要解决的交通预测问题1.1 交通预测的任务定义输入什么、输出什么先把这个任务说清楚。假设路网里有 N 个传感器每个传感器在 t 时刻上报一个值最常见的是平均车速也有流量、占有率。把 t 时刻所有传感器的值拼成一个向量 x_t ∈ R^N那么一段时间的数据就是一堆向量按时间排起来。论文里的设定是用过去 M 个时刻的数据 X (x_1, x_2, ..., x_M) 预测未来 H 个时刻的 Y (x_{M1}, ..., x_{MH})。在实验里 M 取 12对应 5 分钟采样率下的一小时H 最大也取 12评估时分别看第 3、6、9、12 步也就是 15、30、45、60 分钟的预测误差。这个任务最麻烦的地方是时空耦合。空间上相邻路段的交通状态会互相影响——一段高速堵了车流会排队回溢到上游匝道这种影响不是瞬时的而是带延迟、带衰减地传播。时间上交通有清晰的日内周期和早晚高峰但突发事故、天气变化又会让序列出现剧烈的非平稳波动。更麻烦的是空间影响本身也会随时间变早高峰时进城方向拥挤晚高峰时出城方向拥挤同一个路段对邻居的影响方向是动态的。STGCN 要同时抓住这两条线而不是把它们拆开单独建模。1.2 之前的做法为什么不够用在 STGCN 之前交通预测的主流方案大致分几类各有各的死穴。传统时序方法如 ARIMA、VAR、卡尔曼滤波本质都是线性模型交通数据里的非线性关系和突发变化它们基本接不住而且预测时域拉长之后误差累积很快。SVR、kNN 这类机器学习方法需要手工设计特征输入维度稍高就撑不住扩展性很差。到了深度学习时代早期的做法分两路一路用 RNN/LSTM 对每个传感器单独建模比如 FC-LSTM它把每个传感器当成独立时间序列完全没利用传感器之间的空间关系另一路把路网当成规则的二维网格直接套 2D CNN这等于硬把一个任意拓扑的路网掰成图片既浪费参数又扭曲了真实的相邻关系。问题的根源在于表示方式。高速路网是典型的图结构传感器是节点路段是边节点之间的连接关系是不规则的、稀疏的。把图数据硬塞给为规则网格设计的卷积神经网络必然丢信息。所以很自然的想法是能不能直接在图上做卷积让每个传感器的特征沿着真实的道路连接传播这正是图神经网络GNN在交通预测上最核心的切入点。1.3 STGCN 的核心切入点和它带来的改变STGCN 给出的答案是全卷积的时空图卷积框架。空间维度用图卷积GCN建模基于谱方法加 Chebyshev 多项式近似每个节点聚合 K 阶邻居的信息时间维度用带门控线性单元GLU的一维因果卷积替代当时流行的 RNN。这两部分组合成一个叫 ST-Conv 的卷积块堆叠两个块之后再接一个 1×1 卷积输出层就完成了从“过去 1 小时”到“未来 1 小时”的直接映射。全卷积设计带来几个实际好处。第一训练可以完全并行不用像 RNN 那样按时间步展开训练速度和显存占用都友好得多。第二梯度传播路径短不存在 RNN 里常见的梯度消失/爆炸问题模型更容易训稳。第三输出是一次性生成未来 12 步不是自回归逐步预测推理速度快、也没有误差累积。论文在两个真实数据集上的实验表明STGCN 在不同预测时域上都明显优于当时的各类基线。这篇论文后来影响很大“图卷积处理空间 门控卷积处理时间”的组合方式成了很多时空预测模型的标配。2. 模型结构拆解空间图卷积 时间门控卷积2.1 空间依赖怎么建模谱图卷积与 Chebyshev 近似要理解 STGCN 的空间建模得先明白图上怎么做卷积。假设图信号是 x ∈ R^N也就是 N 个节点各有一个值。图拉普拉斯矩阵 L I - D^{-1/2} A D^{-1/2}其中 A 是邻接矩阵、D 是度矩阵。拉普拉斯矩阵可以特征分解 L UΛU^T这里的 U 相当于图上的一组基图傅里叶变换就是把信号投影到这组基上x̂ U^T x。图卷积的定义是两个信号在谱域相乘再变换回来即 x * g U (U^T x ⊙ U^T g)。把滤波器 g 写成谱域可学习的参数形式 g_θ就得到 x * g_θ U g_θ U^T x。但直接学 g_θ 有个问题它是定义在谱域的全局滤波器每个输出节点都要和所有节点相关计算代价高而且没有局部性。Defferrard 等人提出用 Chebyshev 多项式去近似 g_θx * g_θ ≈ Σ_{k0}^{K-1} θ_k T_k(L̃) x其中 L̃ 2L / λ_max - IT_k 是 Chebyshev 多项式递推关系为 T_0(x)1T_1(x)xT_k(x)2x T_{k-1}(x) - T_{k-2}(x)。这个近似的厉害之处在于L̃ 是局部算子的多项式K 阶多项式的计算只涉及每个节点的 K 阶邻域天然带局部性而且不需要做特征分解直接稀疏矩阵乘法就能算。STGCN 里图卷积的 K 取 3意思是一次图卷积操作节点最多能聚合 3 跳范围内的邻居信息。这和普通 CNN 的感受野是同一套逻辑只是把规则网格换成了任意图结构。实际实现里要注意 L̃ 的计算λ_max 一般用幂迭代法估计不需要精确求特征值。2.2 时间依赖怎么建模门控一维因果卷积时间维度的建模STGCN 没有用 LSTM/GRU而是用一维卷积。但这里有个细节必须用因果卷积causal convolution也就是输出时刻 t 的卷积结果只能依赖 t 时刻及之前的数据不能偷看未来。STGCN 里的时间卷积层用的是标准一维卷积加因果 padding卷积核沿时间轴滑动每个时间点的输出由它之前 K_t 个点的输入计算得到天然满足时序上的因果性。光有因果卷积还不够论文在时间卷积上加了门控线性单元GLU。具体做法是卷积输出被拆成等长的两部分 P 和 Q最终输出是 P ⊙ σ(Q)其中 σ 是 sigmoid 函数。这个门的含义很直观Q 经过 sigmoid 变成一个 0 到 1 之间的“开关”控制 P 里的信息有多少能继续往下传。它和 LSTM 里的门机制是同一个思路只是套在卷积上。论文里对比过带 GLU 的时间卷积比单纯用 ReLU 的时间卷积效果好因为门控给信息流动加了一个可学习的“阀门”梯度也能顺着门传得更远。为什么用卷积不用 RNN除了并行训练效率之外一个很实际的原因是感受野可控。RNN 的依赖距离是隐式的要靠门控机制去学“记住多久”卷积则不同堆叠几层卷积、卷积核多大感受野就是确定的这给模型设计带来很强的可控性。后面很多工作沿用了这个设计比如预测 1 小时前的数据时间卷积层数和核宽只要算一下感受野是否覆盖 12 步就够了。2.3 ST-Conv 块三明治结构的思路把空间卷积和时间卷积组合成基本模块是这篇论文里最值得琢磨的地方。STGCN 没有简单地把两个卷积层前后串联而是采用了“时间卷积 → 图卷积 → 时间卷积”的三明治结构。单个 ST-Conv 块的计算可以写成v^{l1} Γ_1^l *_τ ReLU( Θ^l *_G ( Γ_0^l *_τ v^l ) )其中 Γ_0、Γ_1 是时间卷积核Θ 是图卷积核_τ 表示时间卷积_G 表示图卷积。也就是一个块内先做一次时间卷积把每个节点上的历史信息“压缩”一下再做图卷积让压缩后的节点特征沿着图的边传播最后再做一次时间卷积把传播后的结果进一步整合。为什么是这个顺序而不是“图卷积 → 时间卷积 → 图卷积”这是我的理解也是论文里强调的直觉原始传感器信号里噪声不小直接在这个信号上做空间卷积等于把噪声也传播给了邻居节点。先做一次时间卷积相当于先对每个传感器做局部平滑和特征提取让进入空间传播的信息更“干净”图卷积在这个基础上做邻居聚合效果更稳。最后一个时间卷积则是把空间传播后的特征再次沿时间轴整合调节输出的时间依赖。这个设计和信号处理里的“先滤波、再传播、再滤波”思路一脉相承。每个 ST-Conv 块还带残差连接、批归一化和 ReLU 激活堆叠两个块后接输出层模型深度虽然不深但每个块内做了很充分的时空特征交互。3. 实现细节与训练配置从公式到可跑的代码3.1 图的构建邻接矩阵、距离阈值与拉普拉斯归一化模型里最前置的一步是把路网抽象成图。STGCN 构建邻接矩阵的做法是两个传感器之间的边权重由它们的距离决定采用带阈值的高斯核形式 A_ij exp(-d_ij² / σ²)只有距离小于某个阈值的传感器对之间才保留边。d_ij 是传感器 i 和 j 的距离可以是经纬度算的球面距离也可以是路网路径距离σ 是高斯核宽度。这个 σ 非常关键σ 太小邻接矩阵几乎退化为单位阵图卷积退化成逐点操作σ 太大所有节点都连成一片图卷积没有局部性。我实际复现时习惯先算所有传感器两两距离然后以距离的一个分位数比如中位数附近来设定 σ再配合阈值做稀疏化比拍脑袋定 σ 靠谱。拿到邻接矩阵 A 之后还要构造归一化拉普拉斯 L I - D^{-1/2} A D^{-1/2}其中 D 是度矩阵。这里注意两件事一是度矩阵计算时要把 A 的对角线清零避免节点把自身又算了一遍二是有些实现用 D^{-1} A 做行归一化效果差异不小STGCN 用的是对称归一化 D^{-1/2} A D^{-1/2}它保留了图的对称性更稳定。构造完 L 之后把它缩放到 [-1, 1] 区间得到 L̃这一步对训练稳定性很重要没归一化的 L 特征值范围可能很大直接做多项式运算容易数值爆炸。λ_max 一般用幂迭代法估算不用精确求特征值。3.2 数据切片、输入输出格式与标准化数据层面的准备第一步是洗数据。传感器原始数据常有缺失值和异常值一般用前向填充加线性插值补上再做一次去重。METR-LA 和 PEMS-SF 这两份公开数据集是很多人复现 STGCN 的首选数据质量和时间粒度都比较规范。第二步是滑窗切样本。输入是连续 12 个时刻的数据输出是紧接着的 12 个时刻窗口步长取 1这样数据量足够大。一个值得注意的实践细节模型的张量排布要设计好。PyTorch 实现里STGCN 的中间特征一般排成 (batch, channels, time, nodes) 这种形状因为时间卷积是沿 time 维度做的 2D 卷积图卷积是沿 nodes 维度做的矩阵乘法这个排布能让两种卷积都很顺手。如果一开始就按 (batch, time, nodes, channels) 排后面转置操作会非常多容易出 bug。第三步是标准化。论文的做法是 z-score 标准化而且是对每个传感器单独计算均值和方差因为不同路段的平均车速差异很大不做标准化的话图卷积会被数值大的节点带偏。这里有个特别容易踩的坑标准化参数只能用训练集计算不能拿到全数据集上算否则验证集和测试集的信息就提前泄漏到训练过程里了。后面我会专门说这个问题。3.3 超参数、损失函数与训练技巧论文里的训练配置我复现时基本沿用Adam 优化器初始学习率 0.001batch size 50训练轮数设个上限然后用早停控制。损失函数是 MAE 加 L2 权重正则。为什么要用 MAE 而不是 MSE交通数据里有不少由事故、管制造成的尖峰异常值MSE 对这种大误差的惩罚是平方级的会让模型拼命去拟合那几个异常点反而把正常模式学歪MAE 对异常值更稳健训练出来的预测曲线更贴合真实交通流的整体趋势。另外几个提升稳定性的细节图卷积输出之后接 ReLU时间卷积内部用 GLU每个 ST-Conv 块都有残差连接和批归一化。批归一化在训练初期特别重要能明显加速收敛、减少对学习率的敏感度。学习率调度上我习惯在验证 loss 停滞时把学习率乘以 0.1配合 early stopping 的 patience 取 10 左右。还有一个容易被忽略的点STGCN 是直接一次性输出未来 12 步而不是像 seq2seq 那样逐步生成这意味着推理阶段没有任何循环依赖单次前向计算就能拿到全部预测结果这也是它速度快的另一个原因。4. 实验设计与结果解读4.1 两个数据集和评估指标的挑选逻辑论文用了两份真实的交通数据集。METR-LA 来自洛杉矶高速路网的 207 个传感器时间跨度约 4 个月2012 年 3 月到 6 月PEMS-SF 来自旧金山湾区的 267 个传感器时间跨度约半年。两份数据都是 5 分钟采样原始数据经过清洗后按时间顺序切分成训练集、验证集和测试集比例大致是 70%、10%、20%。选这两个数据集的好处是规模适中、传感器数量在百级别既不至于让图卷积算不动又足够体现出空间结构对预测的增益。评估指标是 MAE、MAPE、RMSE 三个分别在 15、30、45、60 分钟四个预测时域上报告。这三个指标各有侧重MAE 是平均绝对误差直观好懂MAPE 是相对百分比误差会放大低数值路段的小误差对交通这种几十公里时速的量级来说比较严苛RMSE 对大误差的惩罚更重能反映模型在极端情况下的表现。只看一个指标容易误判比如某个模型 MAE 很低但 RMSE 很高说明它平时预测准但遇到突发拥堵时偏差巨大这在交通场景里是不能接受的。4.2 主要结果全面领先基线怎么看论文对比的基线包括历史平均HA、ARIMA、VAR、SVR、前馈神经网络FFNN、FC-LSTM 和基于图卷积的 GCGRU。结论很明确STGCN 在两组数据集、四个预测时域上MAE、MAPE、RMSE 三个指标全部大幅领先。下面这组数值是我从论文表格里摘出来整理的大致量级我自己复现时数值略有浮动以论文原表为准。模型15 分钟 MAE30 分钟 MAE60 分钟 MAEHA约 5.0约 6.1约 7.1ARIMA约 4.7约 5.8约 7.0SVR约 5.2约 5.6约 6.4FFNN约 3.8约 4.2约 4.8FC-LSTM约 3.7约 4.0约 4.5GCGRU约 3.3约 3.7约 4.3STGCN约 2.88约 3.47约 4.26值得注意的一点是预测时域越长STGCN 的优势越明显。15 分钟预测时STGCN 和 FC-LSTM 差距还不到 1 个 MAE到了 60 分钟差距已经拉开到 0.3 到 0.6 左右。这个现象说明短期预测里时间序列自身的信息就足够空间结构带来的增益有限但预测范围拉长以后路段之间的空间传播信息变成了关键STGCN 正是靠图卷积把这种空间依赖抓住了。反过来也能看出传统方法HA、ARIMA在长时域上掉得很快因为它们既没有非线性建模能力也没法利用路网结构。4.3 消融与结构验证组件真的都必要吗论文里做了不少结构对比验证了各个设计组件的必要性。首先是时间卷积里的 GLU 门控对比不带门控的普通卷积门控版本的误差明显更低——这和我复现时的体感一致GLU 给时间建模加上了“选择性遗忘”在突发变化多的路段上差异尤其明显。其次是三明治结构的顺序“时间-图-时间”比“图-时间-图”更稳这和前面讲的信号先平滑再传播的逻辑吻合。我自己还额外试过把两个 ST-Conv 块换成一个更宽的块结果不如两个窄块堆叠——深度带来的多尺度时空特征提取能力确实无法用宽度补回来。另一个值得验证的点是图卷积阶数 K。K3 是论文实验里比较均衡的选择K1 什么都学不到等价于没有邻居聚合K 太大虽然感受野广但会把很远路段的信息也混进来反而引入噪声。我自己试 K4 的时候长时域误差没有明显下降训练时间却涨了。这说明 K 的选择和路网的实际拓扑有关不能盲目加大。5. 复现过程中的踩坑记录5.1 邻接矩阵相关的坑邻接矩阵是整个模型的数据底座这里出的问题最难排查。第一个坑是距离单位不一致。有的代码里传感器坐标是以米为单位有的以公里为单位算出来的 d_ij 差三个数量级如果还沿用同一套 σ邻接矩阵要么全 1 要么全 0。我自己的经验是无论原始单位是什么先把距离矩阵归一化到均值附近再算权重或者直接按距离分位数定 σ这样至少在数据集更换时不用反复调 σ。第二个坑是图不连通。传感器之间的距离阈值设得太小某些偏远的检测器周围没有邻居它就成了孤立节点。孤立节点在 K 阶图卷积里只能更新到自己空间信息根本传不进去预测效果会明显比周围节点差一截。建议构建完图之后检查一遍每个节点的度发现孤立节点就调大阈值或者改用 KNN 方式建图。第三个坑是 λ_max 和拉普拉斯缩放的数值稳定性。有些复现直接拿未缩放的 L 去做 Chebyshev 展开训练到一半 loss 直接变 NaN。标准做法是 L̃ 2L/λ_max - Iλ_max 用幂迭代法估计后还要带一个 eps 防止除零。这个细节看起来小但出问题时会让你怀疑整个模型设计有问题白折腾一天。5.2 数据划分与归一化的坑这个部分全是“看起来没问题、细想全是问题”的坑。第一z-score 标准化的均值和方差必须在训练集上算测试时要沿用训练集的参数。很多快速复现为了方便直接在整个数据集上算均值和方差这在 CV 里有时影响不大但在交通预测里会显著高估模型性能因为测试集的分布信息已经被模型“看到”了。第二训练/验证/测试切分必须按时间顺序不能全局随机打乱。交通数据有强时间相关性随机打乱会让训练集里的样本和测试集样本时间上相邻模型等于提前看到了答案。正确的做法是按时间切块先在前 70% 上训中间 10% 选超参最后 20% 做终极评估。第三滑窗重叠带来的评估乐观。步长为 1 的滑窗让相邻样本之间共享了大量时间点训练集和测试集如果切分不当窗口边界会贴着泄漏。解决方法是切分时保证训练集最后一个窗口和验证集第一个窗口之间至少间隔 12 个时间点这样输入区间不会跨越数据段边界。第四特征选择要统一口径。有的复现只用速度单特征有的把速度、流量都塞进去还有把时间编码星期几、几点也拼进去的。这些都会影响最终数字对比实验时务必明确说明自己用了哪几个通道否则和论文数字对不上时根本定位不到原因。5.3 训练不稳定与性能问题的排查我复现时碰到的训练问题大致有三类。第一类是 loss 一开始就很大而且不下降。这种情况先检查输出层STGCN 输出层的两个 1×1 卷积要把特征投影到 H 个预测时刻如果 H 和特征通道数不匹配维度错了不会报错但梯度会非常混乱。其次是检查批归一化是否加在了合适的位置——图卷积之后不加 BN网络基本训不动。第二类是 loss 中途爆炸或变成 NaN。常见原因包括学习率太大、图卷积的数值范围失去控制、或者梯度爆炸。排查顺序是先降学习率到 1e-4 看是否缓解再检查 L̃ 是否归一化到 [-1,1]最后给优化器加梯度裁剪一般 max_norm 设 5.0 以内就能压住。还有一个容易被忽略的点Chebyshev 展开中会把 L̃ 乘上输入如果输入的特征值超过 1多次多项式运算会指数放大所以输入标准化比你想的还要重要。第三类是效果看起来还行但总是“慢半拍”。这类问题最隐蔽MAE 数字不算差但你画出预测曲线发现预测值基本上是历史值的滞后平移。这说明模型主要学到了时间上的“延续”没有真正学到空间传播关系。我遇到这种情况时的处理是把时间卷积核从 Kt3 调大到 Kt5或者把预测目标从“直接回归绝对值”改成“回归相对变化量”后者在长时域预测里能明显减少滞后感。6. 延伸思考STGCN 的位置与后续演进6.1 为什么这篇论文影响这么大STGCN 之所以成为经典我觉得不只是因为它在两个数据集上刷了新数字而是它把“用图结构表达领域知识 用卷积框架做时空建模”这条路完整地走通并开源了出来。在这之前时空预测里用 RNN/LSTM 几乎是默认选项STGCN 证明全卷积结构在交通预测上不仅可行而且训练更快、效果更好。这个结论给后来者省了大量选型时间。之后几年里Graph WaveNet、STSGCN、ASTGCN 等大量工作沿用了 ST-Conv 的基本思路要么在图结构上做自适应学习要么引入注意力机制但“时空两个维度分别建模再组合”的骨架基本没变。这个框架的可迁移性也值得强调。凡是能抽象成“传感器网络 时序信号”的任务都可以套用这套思路城市人流预测、电网负荷预测、空气质量监测、物联网设备异常检测本质上都是图上的时序预测问题。我在另一个环境监测项目里试过把 STGCN 稍作修改迁移过去只换了邻接矩阵和特征通道数效果就直接超过了原来的逐点 LSTM。这种跨任务的泛化能力是它比很多“针对特定数据集精心调参”的方法更有价值的地方。6.2 局限性、后续工作与我的一些想法STGCN 当然也有明显局限。第一它的图是预先定义并且固定的但真实路网的空间依赖会随交通状态动态变化——早高峰和半夜两点同样两个路段的相关系数完全不同突发事故更是会在短时间内重构一段路的“影响力拓扑”。固定图建模不了这种动态性。第二邻接矩阵只编码了距离相近的传感器关系两个不相邻但功能相似的路段比如平行的两条主干道之间可能存在强相关但图里没有边模型就学不到这种隐藏关联。后续 Graph WaveNet 提出自适应邻接矩阵、ASTGCN 引入时空注意力都是在补这些短板。从个人经验说我读完这篇论文最大的收获不是某一层实现而是这种建模思维面对一个时空任务先问数据背后的图结构是什么再决定用什么样的卷积算子去匹配这个结构。很多任务的数据天然带图结构只是没有被显式建模出来硬套序列模型其实是在绕远路。如果你正准备复现 STGCN我的建议是先别急着把代码堆起来而是把邻接矩阵、数据切分、指标计算这三件事的细节先钉死这三处出问题的概率最大。跑通基线之后再去改图卷积阶数、时间核宽度这些超参你会发现自己对“空间依赖和时间依赖分别怎么被模型捕捉”的理解会明显上了一个台阶。
返回列表