循环神经网络与图神经网络的联系:从序列到图的学习
循环神经网络与图神经网络的联系:从序列到图的学习
循环神经网络(RNN)和图神经网络(GNN)虽然在处理的数据类型上有所不同,但在核心思想和数学原理上有着深刻的联系[4]。理解这种联系不仅有助于我们更好地掌握图神经网络,还能为设计新的网络架构提供启发。
循环神经网络基础
RNN的基本概念
循环神经网络被称为”循环”,因为它们对序列的每个元素执行相同的任务,输出取决于先前的计算。RNN有一个”记忆”,可以捕获到目前为止计算的信息。

符号定义:
- $X_t$:$t$时刻输入层的输入
- $S_t$:$t$时刻的隐藏层输出($S_0$通常初始化为全0)
- $O_t$:$t$时刻输出层的输出
- $W_{in}$:输入权重
- $W_s$:隐藏层权重
- $W_{out}$:输出权重
RNN的数学定义
隐藏层输出: \(S_t = f(W_{in} \cdot X_t + W_s \cdot S_{t-1} + b_{hidden})\)
输出层输出: \(O_t = g(W_{out} \cdot S_t + b_{out})\)
RNN的不同模式

RNN存在多种输入输出模式:
- One-to-One:一对一映射
- One-to-Many:一对多映射(如图像描述生成)
- Many-to-One:多对一映射(如情感分析)
- Many-to-Many:多对多映射(如机器翻译)
graph LR
X0["X₀"] --> S0["隐藏状态 S₀"] --> O0["O₀"]
X1["X₁"] --> S1["S₁"] --> O1["O₁"]
X2["X₂"] --> S2["S₂"] --> O2["O₂"]
S0 -.->|"Wₛ"| S1 -.->|"Wₛ"| S2
RNN的核心问题:梯度消失与梯度爆炸
问题分析
RNN在处理长序列时面临严重的梯度消失和梯度爆炸问题。让我们从数学角度分析这个问题:
假设RNN的损失函数为 $L = \sum_{t=1}^T L_t$,其中$t$为模型的时间步。对模型求偏导:
输出层权重: \(\frac{\partial L_3}{\partial W_{out}} = \frac{\partial L_3}{\partial O_3}\frac{\partial O_3}{\partial W_{out}}\)
输入层权重: \(\frac{\partial L_3}{\partial W_{in}} = \frac{\partial L_3}{\partial O_3} \frac{\partial O_3}{\partial S_3} \frac{\partial S_3}{\partial W_{in}} + \frac{\partial L_3}{\partial O_3} \frac{\partial O_3}{\partial S_3} \frac{\partial S_3}{\partial S_2} \frac{\partial S_2}{\partial W_{in}} + \frac{\partial L_3}{\partial O_3} \frac{\partial O_3}{\partial S_3} \frac{\partial S_3}{\partial S_2} \frac{\partial S_2}{\partial S_1} \frac{\partial S_1}{\partial W_{in}}\)
隐藏层权重: \(\frac{\partial L_3}{\partial W_{s}} = \frac{\partial L_3}{\partial O_3} \frac{\partial O_3}{\partial S_3} \frac{\partial S_3}{\partial W_s} + \frac{\partial L_3}{\partial O_3} \frac{\partial O_3}{\partial S_3} \frac{\partial S_3}{\partial S_2} \frac{\partial S_2}{\partial W_s} + \frac{\partial L_3}{\partial O_3} \frac{\partial O_3}{\partial S_3} \frac{\partial S_3}{\partial S_2} \frac{\partial S_2}{\partial S_1} \frac{\partial S_1}{\partial W_s}\)
梯度消失的数学分析
对于任意时刻的$W_{in}$和$W_s$,偏导公式为:
\[\frac{\partial L_t}{\partial W_{[in/s]}} = \sum_{k=0}^t \frac{\partial L_t}{\partial O_t} \frac{\partial O_t}{\partial S_t}\left(\prod_{j=k+1}^t \frac{\partial S_j}{\partial S_{j-1}}\right) \frac{\partial S_k}{\partial W_{[in/s]}}\]如果加上激活函数 $S_j = \tanh(W_x W_j + W_s S_{j-1} + b_1)$,得到:
\[\prod_{j=k+1}^t \frac{\partial S_j}{\partial S_{j-1}} = \prod_{j=k+1}^t \tanh' W_s\]由于 $\tanh’ \leq 1$,当$W_s < 1$时,连乘结果趋于0(梯度消失);当$W_s > 1$时,连乘结果趋于无穷(梯度爆炸)。[1]
从RNN到GNN的演进
消息传递的统一框架
RNN和GNN都可以用消息传递的框架来理解:
RNN的消息传递:
- 每个时间步,当前状态接收来自前一个时间步的信息
- 信息传递是线性的(时间序列)
- 状态更新:$S_t = f(X_t, S_{t-1})$
GNN的消息传递:
- 每个节点,当前节点接收来自邻居节点的信息
- 信息传递是图结构的(空间关系)
- 状态更新:$h_v^{(l+1)} = f(h_v^{(l)}, {h_u^{(l)} : u \in \mathcal{N}(v)})$[5]
图结构作为序列的推广
我们可以将图结构看作是序列的推广:
- 序列:每个元素只与前一个元素相连
- 树结构:每个节点有多个子节点
- 图结构:每个节点可以与多个邻居节点相连
这种推广使得GNN能够处理更复杂的结构化数据。
graph LR
subgraph SEQ["序列 RNN"]
A["A"] --> B["B"] --> C["C"] --> D["D"]
end
SEQ -->|"推广"| TREE["树结构<br/>Root→A→C,D<br/>Root→B"]
TREE -->|"推广"| GRAPH["图 GNN<br/>任意节点连接"]
图神经网络中的梯度问题
过平滑问题
GNN面临类似RNN梯度消失的问题,称为”过平滑”(Over-smoothing):
现象:随着层数增加,所有节点的表示趋于相同 原因:消息传递过程中,节点信息被过度平均化 数学表达:$\lim_{l \to \infty} h_v^{(l)} = c$,其中$c$是常数[2]
解决方案
残差连接
\(h_v^{(l+1)} = h_v^{(l)} + \text{GNN}(h_v^{(l)}, \{h_u^{(l)} : u \in \mathcal{N}(v)\})\)
跳跃连接
\(h_v^{(l+1)} = \text{Concat}(h_v^{(0)}, h_v^{(1)}, \ldots, h_v^{(l)})\)
注意力机制
为不同的邻居节点分配不同的权重,避免信息被过度平均[3]。
实际应用中的联系
序列到图的转换
许多实际问题可以同时用序列和图来建模:
文本处理:
- 序列视角:字符序列 → RNN/LSTM
- 图视角:句法依存树 → GNN
时间序列:
- 序列视角:时间点序列 → RNN
- 图视角:时间点间的因果关系图 → GNN
混合架构
现代深度学习模型经常结合RNN和GNN:
图序列网络:
- 用RNN处理时间维度
- 用GNN处理空间维度
- 适用于动态图数据
注意力机制的统一:
- RNN中的自注意力机制
- GNN中的图注意力机制
- 都基于查询-键-值框架
代码实现对比
RNN实现示例
import torch
import torch.nn as nn
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.hidden_size = hidden_size
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
# x shape: (batch_size, seq_len, input_size)
output, _ = self.rnn(x)
# 取最后一个时间步的输出
output = self.fc(output[:, -1, :])
return output
GNN实现示例
import torch
import torch.nn as nn
from torch_geometric.nn import GCNConv
class SimpleGNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleGNN, self).__init__()
self.conv1 = GCNConv(input_size, hidden_size)
self.conv2 = GCNConv(hidden_size, output_size)
self.dropout = nn.Dropout(0.5)
def forward(self, x, edge_index):
# x shape: (num_nodes, input_size)
# edge_index shape: (2, num_edges)
x = torch.relu(self.conv1(x, edge_index))
x = self.dropout(x)
x = self.conv2(x, edge_index)
return x
总结
RNN和GNN虽然在处理的数据类型上不同,但在核心思想上有着深刻的联系:
- 消息传递:都基于信息在结构中的传播
- 状态更新:都通过聚合信息来更新状态
- 梯度问题:都面临信息传播中的衰减问题
- 解决方案:都可以通过残差连接、注意力机制等方法解决
理解这种联系有助于我们:
- 更好地掌握图神经网络的核心思想
- 设计新的网络架构
- 解决实际应用中的问题
- 理解深度学习模型的统一性
在下一篇文章中,我们将深入探讨图卷积网络(GCN)的具体实现,包括数学原理和PyTorch代码实现。
参考文献
- Hochreiter, S., & Schmidhuber, J. Long Short-Term Memory. Neural Computation, 1997. DOI:10.1162/neco.1997.9.8.1735
- Kipf, T. N., & Welling, M. Semi-Supervised Classification with Graph Convolutional Networks. ICLR, 2017. arXiv:1609.02907
- Veličković, P., Cucurull, G., Casanova, A., Romero, A., Liò, P., & Bengio, Y. Graph Attention Networks. ICLR, 2018. arXiv:1710.10903
- Wu, Z., Pan, S., Chen, F., Long, G., Zhang, C., & Yu, P. S. A Comprehensive Survey on Graph Neural Networks. IEEE Transactions on Neural Networks and Learning Systems, 2020. arXiv:1901.00596
- Gilmer, J., Schoenholz, S. S., Riley, P. F., Vinyals, O., & Dahl, G. E. Neural Message Passing for Quantum Chemistry. ICML, 2017. arXiv:1704.01212