提出背景
- 论文:Yaguang Li, Rose Yu, Cyrus Shahabi, Yan Liu, Diffusion Convolutional Recurrent Neural Network: Data-Driven Traffic Forecasting, ICLR 2018.
- 目标:解决具有图结构依赖的时空序列预测问题(如交通速度预测)。
- 核心思想:将图扩散过程(如随机游走)融入RNN的状态更新中。
关键技术
- Diffusion Convolution (扩散卷积):
- 不使用固定的邻接矩阵,而是基于有向图上的前向/反向随机游走构建多补传播核。
- 能捕捉"上游 →\rightarrow→ 下游"的非对称影响。
- Encoder-Decoder架构:
- 编码器:用Gated Recurrent Unit (GRU) + 扩散卷积处理历史序列。
- 解码器:同样结构,逐步生成未来多步预测(支持多步ahead预测)。
优点
- 显式建模空间依赖的方向性。
- 在早期时空图学习中性能优异,是很多后续工作的baseline。
缺点
- 图结构需预先定义且固定(无法动态适应)。
- RNN 结构难以并行,训练慢;对长期依赖建模能力有限。
为什么说DCRNN的输入必须包含一个有向图的邻接矩阵AAA,且这个矩阵"需要预先定义且固定"?
核心结论
DCRNN确实使用了"固定的邻接矩阵"作为输入,但它通过"扩散卷积(Diffusion Convolution)"在这个固定图上模拟 多步、有向、非对称的信息传播过程,从而 超越了传统GCN仅依赖一阶邻居的局限。
所以:图结构是预定义且固定的,但信息传播是动态、多跳、方向敏感的。
DCRNN 的输入必须包含一个有向图的邻接矩阵AAA ,通常是基于领域知识构建的,例如:
- 交通流:路段之间的连接关系(来自路网拓扑);
- 空气质量:可以使用网格点之间的地理距离构建有向边(比如只保留上风向到下风向的边),或根据历史相关性构建。
这个邻接矩阵AAA在整个训练和推理过程中不会被更新,也不由模型学习------它是人为设定的先验结构。
那Diffusion Convolution到底做了什么?
虽然图是固定的,但 DCRNN 并不像普通 GCN 那样只聚合直接邻居(1-hop)。它通过随机游走(Random Walk) 在这个固定图上定义多步转移概率,从而实现长距离、方向感知的信息扩散。
具体来说:
-
构造两个转移矩阵(基于有向邻接矩阵AAA):
-
前向转移(Forward): Df−1AD^{-1}_fADf−1A(出度归一化)
表示信息从节点iii流出到其下游邻居。
-
反向转移(Backward):Db−1ATD^{-1}_bA^{T}Db−1AT(入度归一化)
表示信息从节点jjj流入到上游节点。
-
-
计算KKK步扩散核:
- 前向kkk步:(Df−1A)k(D^{-1}_fA)^k(Df−1A)k
- 反向kkk步:(Db−1AT)k(D^{-1}_bA^T)^k(Db−1AT)k
-
扩散卷积操作:
对输入特征XXX,输出为:
DC(X)=∑k=0K−1[θk(f)(Df−1A)kX+θk(b)(Db−1A⊤)kX]\mathrm{DC}(X)=\sum_{k=0}^{K-1}\left[\theta_k^{(f)}(D_f^{-1}A)^kX+\theta_k^{(b)}(D_b^{-1}A^\top)^kX\right]DC(X)=k=0∑K−1[θk(f)(Df−1A)kX+θk(b)(Db−1A⊤)kX]
其中θk(f),θk(b)\theta_{k}^{(f)},\theta_{k}^{(b)}θk(f),θk(b)是可学习参数。
直观理解:
- 即使你的邻接矩阵只连接相邻网格(1-hop),DCRNN也能通过(D−1A)2,(D−1A)3,...(D^{-1}A)^2,(D^{-1}A)^3,\ldots(D−1A)2,(D−1A)3,...捕捉2跳、3跳...甚至区域的传输路径。
- 而且因为区分了前向/反向,它能建模非对称影响。
DCRNN时空序列预测步骤
整体任务设定
- 输入:过去T=nT=nT=n的时空数据
X1:T∈RT×N×FX_{1:T}\in\mathbb{R}^{T\times N\times F}X1:T∈RT×N×F,其中(N表示节点数,F表示特征数) - 输出:未来H=3H=3H=3小时的预测
Y^T+1:T+H∈RH×N×F\hat{\mathbf{Y}}_{T+1:T+H}\in\mathbb{R}^{H\times N\times F}Y^T+1:T+H∈RH×N×F - 图结构:预定义有向邻接矩阵A∈RN×NA\in\mathbb{R}^{N\times N}A∈RN×N
核心组件:DCRNN Cell(带扩散卷积的GRU)
在介绍编码器/解码器前,先明确DCNN Cell是什么:
它是一个修改版的GRU但愿,其中所有线性变换(如Wx+UhWx+UhWx+Uh)都被替换为Diffusion Convolution。
具体来说,标准GRU中的:
Lincar(xt)→DC(xt)=∑k=0K−1θk(f)(Df−1A)kxt+θk(b)(Db−1A⊤)kxt\mathrm{Lincar}(x_t)\quad\to\quad\mathrm{DC}(x_t)=\sum_{k=0}^{K-1}\theta_k^{(f)}(D_f^{-1}A)^kx_t+\theta_k^{(b)}(D_b^{-1}A^\top)^kx_tLincar(xt)→DC(xt)=k=0∑K−1θk(f)(Df−1A)kxt+θk(b)(Db−1A⊤)kxt
所以,DCRNN Cell的状态更新为:
ht=DCRNNCell(xt,ht−1;A)h_t=\mathrm{DCRNNCell}(x_t,h_{t-1};A)ht=DCRNNCell(xt,ht−1;A)
它同时考虑了时间动态(通过 GRU 门控)和空间扩散(通过 DC)。
编码器(Encoder):压缩历史信息
目标:
将整个历史序列X1:TX_{1:T}X1:T压缩成一个上下文向量(context vector),即最后一个隐藏状态hTh_ThT。
结构:
- 堆叠LLL层DCRNN Cell (通常L=1L=1L=1或2)
- 每一层按时间步顺序处理输入:
h1(1)=DCRNNCell1(x1,h0(1))h2(1)=DCRNNCell1(x2,h1(1))⋮hT(1)=DCRNNCell1(xT,hT−1(1))\begin{aligned}h_{1}^{(1)}&=\mathrm{DCRNNCell}_1(x_1,h_0^{(1)})\\h_2^{(1)}&=\mathrm{DCRNNCell}_1(x_2,h_1^{(1)})\\&\vdots\\h_T^{(1)}&=\mathrm{DCRNNCell}1(x_T,h{T-1}^{(1)})\end{aligned}h1(1)h2(1)hT(1)=DCRNNCell1(x1,h0(1))=DCRNNCell1(x2,h1(1))⋮=DCRNNCell1(xT,hT−1(1)) - 如果有多层,第2层以第1层的隐藏序列为输入:
ht(2)=DCRNNCell2(ht(1),ht−1(2))h_t^{(2)}=\mathrm{DCRNNCell}2(h_t^{(1)},h{t-1}^{(2)})ht(2)=DCRNNCell2(ht(1),ht−1(2))
输出:
- 最终隐藏状态hT=hT(L)∈RN×Hh_T=h_T^{(L)}\in\mathbb{R}^{N\times H}hT=hT(L)∈RN×H(HHH是隐藏维度)
- 这个hTh_ThT包含了整个历史时空演化模式,作为解码器的初始状态。
注意:编码器只看"过去",不接触未来。
解码器(Decoder):逐步生成未来
目标:
从hTh_ThT出发,逐步生成未来HHH个时间步的预测。
关键机制:Scheduled Sampling(计划采样)
DCRNN使用一种混合策略来训练解码器,避免误差累积:
- 训练阶段:
- 在训练第t步时,以概率ppp输入真实值yt−1y_{t-1}yt−1,以概率1−p1-p1−p输入上一步的预测y^t−1\hat y_{t-1}y^t−1
- 随训练进行,ppp逐渐减小(从1→01\rightarrow 01→0),让模型自己学会依赖自己的预测。
- 推理阶段:
- 只能用自己预测的值作为下一步输入(因为真是未来不可见)。
解码过程(以预测未来3步为例):
- 初始化:
- 隐藏状态s0=hTs_0=h_Ts0=hT(来自编码器)
- 输入d0=0d_0=0d0=0(或可学习的起始token)
- Step 1 (预测t=T+1t=T+1t=T+1):
s1=DCRNNCelldec(d0,s0)s_1= DCRNNCell_{dec}(d_0,s_0)s1=DCRNNCelldec(d0,s0)
y^T+1=Linear(s1)\hat y_{T+1}=Linear(s_1)y^T+1=Linear(s1) - Step 2 (预测t=T+2t=T+2t=T+2):
d1={yT+1(训练,以概率 p)y^T+1(训练,以概率 1−p; 或推理)d_1=\begin{cases}y_{T+1}&(\text{训练,以概率 }p)\\\hat{y}{T+1}&(\text{训练,以概率 }1-p;\text{ 或推理})\end{cases}d1={yT+1y^T+1(训练,以概率 p)(训练,以概率 1−p; 或推理)
s2=DCRNNCelldec(d1,s1)s{2}=DCRNNCell_{{dec}}({d}{1},s{1})s2=DCRNNCelldec(d1,s1)
y^T+2=Linear(s2){\hat{y}}{T+2}=\operatorname*{Linear}(s{2})y^T+2=Linear(s2) - Step 3 (预测t=T+3t=T+3t=T+3)
d2=y^T+2d_{2}= \hat{y}{T+2}d2=y^T+2 (推理)
s3=DCRNNCelldec(d2,s2)s_3 = DCRNNCell{dec}(d_{2}, s_{2})s3=DCRNNCelldec(d2,s2)
y^T+3=Linear(s3)\hat{y}_{T + 3 }= Linear(s _ { 3 })y^T+3=Linear(s3)
注意:解码器也使用 DCRNN Cell,所以每一步的隐藏状态更新都包含空间扩散
为什么这种架构适合多步预测?
| 优势 | 说明 |
|---|---|
| 时空耦合 | 每一步预测都通过扩散卷积融合空间邻居的信息(包括已预测的未来状态) |
| 误差传播建模 | 通过 scheduled sampling,模型学会在存在预测误差的情况下继续预测 |
| 灵活输出长度 | 只需运行解码器 HHH 步,即可预测任意长度的未来 |