图神经网络(GNN)完全指南

📚 从零开始学习图神经网络

🎯 目标:用最通俗的语言,讲清楚最前沿的图学习技术

🌐 图神经网络是处理关系数据的利器,应用于社交网络、推荐系统、药物发现等领域

📅 最后更新:2025年11月


📋 目录


1. 什么是图(Graph)?

1.1 生活中的图

在讲图神经网络之前,我们先理解什么是"图"。

图不是照片,而是一种数据结构!

图 = 节点(Node/Vertex)+ 边(Edge)

节点:表示实体(人、物品、地点等)
边:表示关系(朋友、购买、连接等)

1.2 图的例子

例子1:社交网络
        张三 ────────── 李四
         │    朋友关系    │
         │                │
        朋友             朋友
         │                │
         │                │
        王五 ────────── 赵六

节点:人(张三、李四、王五、赵六)
边:朋友关系

可视化

    ●───────●
   张三     李四
    │       │
    │       │
    ●───────●
   王五     赵六
例子2:分子结构
        H
        │
    H─C─C─O─H  (乙醇分子)
        │
        H

节点:原子(C, H, O)
边:化学键
例子3:交通网络
    北京 ──飞机─→ 上海
     │             │
    高铁          高铁
     ↓             ↓
    广州 ──飞机─→ 深圳

节点:城市
边:交通方式(有向、带权重)
例子4:知识图谱
    苹果公司
       │
     创始人
       │
       ↓
    乔布斯 ─── 出生于 ──→ 旧金山
       │
    发明了
       │
       ↓
    iPhone

节点:实体(公司、人、产品、地点)
边:关系(创始人、出生于、发明了)

1.3 图的数学定义

图 G = (V, E)

V = {v1, v2, ..., vn}  节点集合
E = {(vi, vj), ...}     边集合

例如:
V = {张三, 李四, 王五}
E = {(张三, 李四), (李四, 王五)}

1.4 图的类型

无向图 vs 有向图
无向图:
A ─── B    A和B互为朋友(双向)

有向图:
A ──→ B    A关注B(单向)

可视化对比

【无向图】社交好友
    ●───●───●
    A   B   C
    
边没有箭头,关系是对称的

【有向图】Twitter关注
    ●──→●──→●
    A   B   C
    
边有方向,A关注B,B关注C
加权图 vs 无权图
无权图:
A ─── B    只表示有连接

加权图:
A ──5km─→ B    边有权重(距离、强度等)

可视化

【加权图】城市距离
    
    北京
     │ 1000km
     │
    上海 ────── 300km ────── 杭州
     │
   500km
     │
    广州
同质图 vs 异质图
同质图:
所有节点类型相同,所有边类型相同
例如:只有"人"节点,只有"朋友"关系

异质图:
多种类型的节点和边
例如:有"人"、"电影"、"导演",有"喜欢"、"导演"关系

可视化

【异质图】电影推荐

    用户 ──喜欢──→ 电影 ←──导演─── 导演
     ●              ●              ●
    张三          《盗梦空间》    诺兰
     │                           │
   朋友                        导演
     ↓                           ↓
     ●              ●              ●
    李四          《星际穿越》   (同一个诺兰)

节点类型:用户、电影、导演
边类型:喜欢、导演、朋友

1.5 图的表示方法

邻接矩阵(Adjacency Matrix)
节点:A, B, C, D

图:
  A ─── B
  │     │
  C ─── D

邻接矩阵 A:
     A  B  C  D
A [  0  1  1  0 ]
B [  1  0  0  1 ]
C [  1  0  0  1 ]
D [  0  1  1  0 ]

A[i][j] = 1 表示节点i和节点j之间有边

优点

  • ✅ 表示简单
  • ✅ 查询两个节点是否相连:O(1)

缺点

  • ❌ 空间复杂度:O(n²),大图很浪费
  • ❌ 大部分图是稀疏的(边很少),矩阵大部分是0
邻接表(Adjacency List)
节点:A, B, C, D

图(同上)

邻接表:
A: [B, C]
B: [A, D]
C: [A, D]
D: [B, C]

每个节点存储其邻居列表

优点

  • ✅ 空间复杂度:O(V + E),节省空间
  • ✅ 遍历邻居快

缺点

  • ❌ 查询两节点是否相连:需要遍历,O(degree)
边列表(Edge List)
边列表:
[(A, B), (A, C), (B, D), (C, D)]

只存储所有边

可视化总结

┌────────────────────────────────────────────┐
│          图的三种表示方法                   │
├────────────────────────────────────────────┤
│                                             │
│  原始图:                                   │
│      A ─── B                                │
│      │     │                                │
│      C ─── D                                │
│                                             │
│  邻接矩阵(稠密存储):                      │
│  ┌──────────┐                              │
│  │ 0 1 1 0  │                              │
│  │ 1 0 0 1  │                              │
│  │ 1 0 0 1  │                              │
│  │ 0 1 1 0  │                              │
│  └──────────┘                              │
│                                             │
│  邻接表(稀疏存储):                        │
│  A → [B, C]                                │
│  B → [A, D]                                │
│  C → [A, D]                                │
│  D → [B, C]                                │
│                                             │
│  边列表:                                   │
│  (A,B), (A,C), (B,D), (C,D)               │
│                                             │
└────────────────────────────────────────────┘

2. 为什么需要图神经网络?

2.1 传统神经网络的局限

CNN(卷积神经网络)
适用于:网格数据(图像、视频)

图像特点:
- 规则的网格结构(像素排列)
- 每个像素有固定数量的邻居(8个)
- 平移不变性

图的特点:
- 不规则结构
- 每个节点的邻居数量不同
- 无法用固定大小的卷积核

结论:CNN 无法直接用于图!

可视化

【CNN 适用】图像(规则网格)

●───●───●───●
│   │   │   │
●───●───●───●   每个像素有固定的邻居
│   │   │   │
●───●───●───●
│   │   │   │
●───●───●───●

【不适用】图(不规则)

    ●
   ╱│╲
  ●─●─●    节点A有3个邻居
    │╲     节点B有2个邻居
    ●─●    节点C有1个邻居
RNN(循环神经网络)
适用于:序列数据(文本、时间序列)

序列特点:
- 有明确的顺序(从左到右)
- 一维结构

图的特点:
- 没有天然的顺序
- 多维关系网络

结论:RNN 无法直接处理图!

可视化

【RNN 适用】文本序列

我 → 爱 → 机器 → 学习
│    │     │      │
h1  h2    h3     h4

明确的时间顺序

【不适用】社交网络

    A
   ╱│╲
  B─C─D
   ╲│╱
    E

没有明确的顺序,应该先处理谁?

2.2 图数据的挑战

挑战1:不规则结构
  - 节点数量可变
  - 每个节点的邻居数量不同

挑战2:置换不变性
  - 节点的编号是任意的
  - 改变节点顺序,图的本质不变

挑战3:大规模图
  - 社交网络:数亿节点
  - 知识图谱:数千万实体

挑战4:动态图
  - 关系随时间变化
  - 新节点和边不断加入

2.3 图神经网络的解决方案

GNN 的核心思想

通过"消息传递",让每个节点
1. 聚合邻居的信息
2. 更新自己的表示
3. 多轮迭代,捕捉更大范围的信息

类比:
就像朋友圈,你的观点会受到朋友的影响
朋友的观点又受到他们朋友的影响
经过多轮传播,你能间接了解更多人的想法

可视化示例

初始状态:
    A(1)
   ╱  ╲
  B(2) C(3)
   ╲  ╱
    D(4)

第1轮消息传递:
  A 收到 B, C 的信息
  B 收到 A, D 的信息
  C 收到 A, D 的信息
  D 收到 B, C 的信息

更新后:
    A(1.5)     ← 聚合了 B, C 的信息
   ╱    ╲
  B(2.2) C(2.8)
   ╲    ╱
    D(3.5)

经过多轮传递,节点能"看到"更远的邻居!

3. 图神经网络基础

3.1 GNN 的核心任务

GNN 可以解决三类任务:

┌─────────────────────────────────────────┐
│         GNN 的三大任务类型               │
├─────────────────────────────────────────┤
│                                          │
│  1️⃣ 节点级任务(Node-level)           │
│     预测每个节点的属性                   │
│     例如:社交网络中预测用户兴趣         │
│                                          │
│  2️⃣ 边级任务(Edge-level)             │
│     预测节点间是否有边,或边的类型       │
│     例如:推荐系统(用户-物品连接)      │
│                                          │
│  3️⃣ 图级任务(Graph-level)            │
│     预测整个图的属性                     │
│     例如:分子毒性预测                   │
│                                          │
└─────────────────────────────────────────┘
任务1:节点分类(Node Classification)
任务:预测每个节点的类别

例子:论文引用网络
  节点:论文
  边:引用关系
  目标:预测论文的研究领域

可视化:
    ● AI
   ╱│╲
  ●─●─● 
  CV│ML NLP   预测中间论文属于哪个领域?
    │
    ●
任务2:链接预测(Link Prediction)
任务:预测两个节点之间是否应该有边

例子:推荐系统
  节点:用户、商品
  边:购买关系
  目标:预测用户可能购买什么商品

可视化:
    用户A ────→ 商品1
      │          ?
      │         ╱
      ?      商品2
       ╲     ╱
        ╲   ╱
        商品3

预测:用户A会买商品2吗?
任务3:图分类(Graph Classification)
任务:预测整个图的类别

例子:分子性质预测
  节点:原子
  边:化学键
  目标:预测分子是否有毒

可视化:
    H
    │
H─C─C─O─H  → 预测:无毒 ✓
    │
    H
(乙醇)

    Cl
    │
Cl─C─Cl    → 预测:有毒 ✗
    │
    Cl
(四氯化碳)

3.2 GNN 的基本组件

┌────────────────────────────────────────┐
│        GNN 的四大组件                   │
├────────────────────────────────────────┤
│                                         │
│  1. 节点特征(Node Features)          │
│     每个节点的初始表示                  │
│     X ∈ ℝ^(n×d)                       │
│                                         │
│  2. 邻接矩阵(Adjacency Matrix)       │
│     图的结构信息                        │
│     A ∈ ℝ^(n×n)                       │
│                                         │
│  3. 消息传递函数(Message Function)   │
│     如何聚合邻居信息                    │
│     m_i = Σ φ(h_i, h_j, e_ij)        │
│                                         │
│  4. 更新函数(Update Function)        │
│     如何更新节点表示                    │
│     h_i' = ψ(h_i, m_i)                │
│                                         │
└────────────────────────────────────────┘

3.3 简单的 GNN 层

数学公式

第 k 层的节点表示:

h_i^(k) = σ( W^(k) · Σ (h_j^(k-1) / √(d_i · d_j)) )
                   j∈N(i)

其中:
- h_i^(k):节点 i 在第 k 层的表示
- N(i):节点 i 的邻居集合
- W^(k):第 k 层的权重矩阵
- d_i:节点 i 的度(邻居数量)
- σ:激活函数(如 ReLU)

直观理解

步骤1:聚合邻居
  收集所有邻居的特征

步骤2:归一化
  按邻居数量归一化(度归一化)

步骤3:线性变换
  乘以权重矩阵 W

步骤4:激活
  通过非线性激活函数

可视化流程

┌──────────────────────────────────────────┐
│      单层 GNN 的计算过程                  │
├──────────────────────────────────────────┤
│                                           │
│  初始状态:                               │
│      A(h_A)                               │
│     ╱  ╲                                  │
│   B(h_B) C(h_C)                          │
│                                           │
│  对节点 A:                               │
│                                           │
│  Step 1: 聚合邻居特征                     │
│  m_A = h_B + h_C                         │
│                                           │
│  Step 2: 归一化                           │
│  m_A = m_A / √(2 × 2)  [A和B都有2个邻居] │
│                                           │
│  Step 3: 线性变换                         │
│  z_A = W · m_A                           │
│                                           │
│  Step 4: 结合自身 + 激活                  │
│  h_A' = σ(W_self · h_A + z_A)           │
│                                           │
│  更新后:                                 │
│      A(h_A') ← 包含了 B, C 的信息         │
│     ╱  ╲                                  │
│   B(h_B') C(h_C')                        │
│                                           │
└──────────────────────────────────────────┘

4. 消息传递机制

4.1 消息传递的三个阶段

┌────────────────────────────────────────┐
│       消息传递神经网络 (MPNN)          │
├────────────────────────────────────────┤
│                                         │
│  阶段1:消息生成 (Message)             │
│    m_ij = φ(h_i, h_j, e_ij)          │
│    每条边生成消息                       │
│                                         │
│  阶段2:消息聚合 (Aggregate)           │
│    m_i = ⊕(m_ij)                      │
│          j∈N(i)                        │
│    聚合所有邻居的消息                   │
│    ⊕ 可以是:SUM, MEAN, MAX           │
│                                         │
│  阶段3:节点更新 (Update)              │
│    h_i' = ψ(h_i, m_i)                 │
│    更新节点表示                         │
│                                         │
└────────────────────────────────────────┘

4.2 详细示例

场景:社交网络,预测用户兴趣

初始图:
    A(爱运动:0.8)
   ╱  ╲
  B(?) C(爱读书:0.6)
   ╲  ╱
    D(?)

已知:A喜欢运动,C喜欢读书
未知:B, D 的兴趣?

目标:通过 GNN 预测 B, D 的兴趣

第一层消息传递

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
对节点 B:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

初始特征:
  h_B = [?, ?]  # 未知,可以初始化为随机向量

邻居:A, D
  h_A = [0.8, 0.2]  # [运动, 读书]
  h_D = [0.3, 0.7]  # 初始化

Step 1: 消息生成
  从 A 到 B 的消息:
  m_AB = W_msg · h_A
       = [[0.5, 0.3],   · [0.8]
          [0.2, 0.4]]     [0.2]
       = [0.46, 0.24]

  从 D 到 B 的消息:
  m_DB = W_msg · h_D
       = [0.27, 0.34]

Step 2: 消息聚合
  m_B = MEAN(m_AB, m_DB)
      = ([0.46, 0.24] + [0.27, 0.34]) / 2
      = [0.365, 0.29]

Step 3: 节点更新
  h_B' = ReLU(W_update · [h_B; m_B])
       = ReLU([[...]] · [?, ?, 0.365, 0.29])
       = [0.55, 0.45]  # 新的表示

解释:
B 的新表示结合了邻居 A, D 的信息
偏向运动多一些(因为 A 影响更大)

多层传递的效果

【1层 GNN】
    A
   ╱│╲
  B─C─D    B 只能"看到"直接邻居 A, D

【2层 GNN】
    A
   ╱│╲
  B─C─D    B 能"看到" 2-hop 邻居:A, C, D
            (通过 A 和 D 间接感知 C)

【3层 GNN】
    整个图的信息都能传播到 B
    
类比:
1层 = 你只知道朋友的信息
2层 = 你知道朋友的朋友的信息
3层 = 你知道更远的人的信息

4.3 不同的聚合函数

┌────────────────────────────────────────┐
│         常见聚合函数对比                │
├────────────────────────────────────────┤
│                                         │
│  1. SUM 聚合                           │
│     m_i = Σ m_ij                       │
│     优点:简单,保留总信息量            │
│     缺点:受邻居数量影响大              │
│                                         │
│  2. MEAN 聚合                          │
│     m_i = (1/|N(i)|) Σ m_ij          │
│     优点:归一化,不受邻居数量影响      │
│     缺点:丢失了节点度的信息            │
│                                         │
│  3. MAX 聚合                           │
│     m_i = MAX(m_ij)                    │
│     优点:捕捉最显著特征                │
│     缺点:忽略大部分信息                │
│                                         │
│  4. ATTENTION 聚合                     │
│     m_i = Σ α_ij · m_ij               │
│     优点:自适应权重,重要邻居影响大    │
│     缺点:计算复杂度高                  │
│                                         │
└────────────────────────────────────────┘

可视化对比

场景:节点 A 有3个邻居

    B(2)
     ╲
      A(?)  ← 预测 A 的值
     ╱ ╲
   C(5) D(8)

【SUM 聚合】
m_A = 2 + 5 + 8 = 15

【MEAN 聚合】
m_A = (2 + 5 + 8) / 3 = 5

【MAX 聚合】
m_A = MAX(2, 5, 8) = 8

【ATTENTION 聚合】
假设权重:α_AB=0.2, α_AC=0.3, α_AD=0.5
m_A = 0.2×2 + 0.3×5 + 0.5×8 = 5.9

5. 常见的 GNN 架构

5.1 GCN(图卷积网络)

Graph Convolutional Network (Kipf & Welling, 2017)

公式:
H^(l+1) = σ(D̃^(-1/2) Ã D̃^(-1/2) H^(l) W^(l))

其中:
- Ã = A + I  (邻接矩阵 + 自环)
- D̃ 是 Ã 的度矩阵
- H^(l) 是第 l 层的节点特征
- W^(l) 是权重矩阵
- σ 是激活函数

直观理解

GCN 做了什么?
1. 每个节点聚合邻居的特征
2. 按度归一化(避免度大的节点主导)
3. 线性变换 + 激活

类比:
就像图像卷积,但是:
- 图像卷积:固定 3×3 窗口
- 图卷积:动态大小,取决于邻居数量

可视化

┌────────────────────────────────────────┐
│         GCN 的计算流程                  │
├────────────────────────────────────────┤
│                                         │
│  输入图:                               │
│      A(x_A)                             │
│     ╱  ╲                                │
│   B(x_B) C(x_C)                        │
│     ╲  ╱                                │
│      D(x_D)                             │
│                                         │
│  GCN 层 1:                             │
│  h_A^(1) = σ(W^(0)·[x_A + x_B + x_C]) │
│  聚合邻居 B, C 的特征                   │
│                                         │
│  GCN 层 2:                             │
│  h_A^(2) = σ(W^(1)·[h_A^(1) + ...])   │
│  再聚合一次,感知范围扩大                │
│                                         │
│  输出:                                 │
│  每个节点的embedding,用于下游任务      │
│                                         │
└────────────────────────────────────────┘

代码示例

import torch
import torch.nn as nn

class GCNLayer(nn.Module):
    def __init__(self, in_features, out_features):
        super().__init__()
        self.linear = nn.Linear(in_features, out_features)
    
    def forward(self, X, A):
        """
        X: 节点特征矩阵 [N, in_features]
        A: 归一化的邻接矩阵 [N, N]
        """
        # 聚合邻居特征
        support = torch.mm(A, X)  # [N, in_features]
        
        # 线性变换
        output = self.linear(support)  # [N, out_features]
        
        return output

5.2 GraphSAGE(图采样聚合)

SAmple and aggreGatE (Hamilton et al., 2017)

核心思想:
不聚合所有邻居,而是采样固定数量的邻居

优点:
- 可扩展到大图
- 计算复杂度可控
- 支持 inductive learning(泛化到新节点)

公式:
h_i^(k) = σ(W^(k) · [h_i^(k-1) || AGG({h_j^(k-1), ∀j∈S(i)})])

S(i):从 N(i) 中采样的邻居子集
||:拼接操作

可视化

┌────────────────────────────────────────┐
│      GraphSAGE vs GCN                  │
├────────────────────────────────────────┤
│                                         │
│  GCN:聚合所有邻居                      │
│                                         │
│       N₁  N₂  N₃  N₄  N₅              │
│        ╲  │  │  │  ╱                   │
│         ╲ │  │  │╱                     │
│          ╲│  │ ╱                       │
│           ╲  │╱                        │
│            ╲│╱                         │
│             A  ← 聚合全部5个邻居       │
│                                         │
│  GraphSAGE:采样 K 个邻居               │
│                                         │
│       N₁  N₂  N₃  N₄  N₅              │
│        ✓     ✗  ✓  ✗                  │
│         ╲       ╱                       │
│          ╲     ╱                        │
│           ╲   ╱                         │
│            ╲ ╱                          │
│             A  ← 只采样2个(N₁, N₃)   │
│                                         │
│  好处:                                 │
│  - 计算量可控(固定K个邻居)            │
│  - 大图也能处理                         │
│  - 每次采样不同,类似 dropout           │
│                                         │
└────────────────────────────────────────┘

聚合函数的变体

GraphSAGE 支持多种聚合器:

1. Mean Aggregator
   AGG = MEAN({h_j, ∀j∈S(i)})

2. LSTM Aggregator
   将邻居看作序列,用 LSTM 处理

3. Pooling Aggregator
   AGG = MAX({σ(W·h_j), ∀j∈S(i)})

4. GCN Aggregator
   类似标准 GCN

5.3 GAT(图注意力网络)

Graph Attention Network (Veličković et al., 2018)

核心思想:
不同邻居的重要性不同,用注意力机制加权

公式:
α_ij = softmax(e_ij)
e_ij = LeakyReLU(a^T · [W·h_i || W·h_j])

h_i' = σ(Σ α_ij · W·h_j)
       j∈N(i)

α_ij:节点 j 对节点 i 的注意力权重

可视化

┌────────────────────────────────────────┐
│        GAT 注意力机制                   │
├────────────────────────────────────────┤
│                                         │
│  节点 A 的邻居:B, C, D                 │
│                                         │
│  Step 1: 计算注意力分数                │
│                                         │
│       B(重要) ──── e_AB = 0.9          │
│      ╱                                  │
│     ╱                                   │
│    A ────────── e_AC = 0.3 ──── C(不重要)
│     ╲                                   │
│      ╲                                  │
│       D(中等) ──── e_AD = 0.6          │
│                                         │
│  Step 2: Softmax 归一化                │
│  α_AB = 0.45  (45%)                    │
│  α_AC = 0.15  (15%)                    │
│  α_AD = 0.40  (40%)                    │
│                                         │
│  Step 3: 加权聚合                       │
│  h_A' = 0.45×h_B + 0.15×h_C + 0.40×h_D│
│                                         │
│  结果:B 的影响最大!                   │
│                                         │
└────────────────────────────────────────┘

多头注意力

类似 Transformer,GAT 也用多头注意力

单头:
h_i' = σ(Σ α_ij^(1) · W^(1)·h_j)

多头(K个头):
h_i' = ||_{k=1}^K σ(Σ α_ij^(k) · W^(k)·h_j)

或者(最后一层):
h_i' = σ(1/K Σ_{k=1}^K Σ α_ij^(k) · W^(k)·h_j)

好处:
- 不同头关注不同特征
- 类似 CNN 的多通道
- 增强表达能力

可视化多头注意力

┌────────────────────────────────────────┐
│       多头注意力(3个头)                │
├────────────────────────────────────────┤
│                                         │
│  Head 1: 关注"年龄"相似性               │
│     B(25岁) ──0.8──→ A(24岁)           │
│     C(50岁) ──0.2──→                   │
│                                         │
│  Head 2: 关注"职业"相似性               │
│     B(工程师) ──0.3──→ A(工程师)       │
│     C(教师)   ──0.7──→                 │
│                                         │
│  Head 3: 关注"地域"相似性               │
│     B(北京) ──0.6──→ A(北京)           │
│     C(上海) ──0.4──→                   │
│                                         │
│  最终:拼接或平均三个头的输出           │
│                                         │
└────────────────────────────────────────┘

5.4 GNN 架构对比

┌────────────────────────────────────────────────────────┐
│              主流 GNN 架构对比                          │
├────────────────────────────────────────────────────────┤
│                                                         │
│  模型      │ 聚合方式  │ 特点           │ 复杂度      │
│  ─────────┼──────────┼───────────────┼────────────│
│  GCN      │ 均值     │ 简单高效       │ O(E)        │
│           │          │ 谱方法         │             │
│  ─────────┼──────────┼───────────────┼────────────│
│  GraphSAGE│ 采样     │ 可扩展         │ O(K×N)      │
│           │          │ Inductive      │ K=采样数    │
│  ─────────┼──────────┼───────────────┼────────────│
│  GAT      │ 注意力   │ 自适应权重     │ O(E×K)      │
│           │          │ 可解释性强     │ K=头数      │
│  ─────────┼──────────┼───────────────┼────────────│
│  GIN      │ SUM      │ 表达力最强     │ O(E)        │
│           │          │ WL test        │             │
│                                                         │
└────────────────────────────────────────────────────────┘

6. 图的表示学习

6.1 什么是图表示学习?

目标:
将高维的图数据(节点、边、图)
映射到低维的向量空间(embedding)

原始图:
  A ─── B
  │     │
  C ─── D

embedding:
A → [0.2, 0.8, 0.5, ...]  (d维向量)
B → [0.3, 0.7, 0.6, ...]
C → [0.1, 0.9, 0.4, ...]
D → [0.25, 0.75, 0.55, ...]

好处:
✅ 可以用传统机器学习算法
✅ 保留图的结构信息
✅ 降维,节省计算

6.2 好的 embedding 应该满足什么?

原则1:结构相似性
图中相近的节点,embedding 也应该相近

    A ─── B        embedding(A) ≈ embedding(B)
    
原则2:语义相似性
属性相似的节点,embedding 应该相近

    人A(医生) embedding(人A) ≈ embedding(人B)
    人B(医生)

原则3:任务相关性
embedding 应该有利于下游任务

例如:节点分类任务
同类节点的 embedding 应该聚在一起

可视化

【原始图】
    ●A────●B    同一社区
    │      │
    ●C────●D
    
         远距离
    
    ●E────●F    另一社区
    │      │
    ●G────●H

【embedding 空间】(降到2维)

  ●A  ●B
  ●C  ●D     ← 第一社区聚在一起
  
        (距离远)
  
  ●E  ●F
  ●G  ●H     ← 第二社区聚在一起

保留了图的社区结构!

6.3 Node2Vec(经典方法)

核心思想:
用随机游走采样节点序列
类似 Word2Vec,学习节点 embedding

算法流程:
1. 在图上随机游走,生成节点序列
   例如:A → B → D → C → A → ...

2. 把节点序列看作"句子"
   节点看作"单词"

3. 用 Skip-gram 模型训练
   最大化:P(context | node)

优点:
- 无监督学习
- 灵活的游走策略(BFS vs DFS)

缺点:
- 不是端到端学习
- 不能处理新节点(transductive)

随机游走的策略

【BFS 风格】(breadth-first)
优先探索近邻

    A
   ╱│╲
  B C D   先访问 A 的所有邻居
   \│/    再深入
    E

路径:A → B → C → D → E → ...

捕捉:局部社区结构(micro-view)


【DFS 风格】(depth-first)
优先深入

    A
    │
    B
    │
    C      一直深入
    │
    D

路径:A → B → C → D → ...

捕捉:全局结构角色(macro-view)


【Node2Vec】结合两者
用参数 p, q 控制:
- p:返回概率(避免回到刚访问的节点)
- q:BFS vs DFS 偏好

6.4 GNN 的表示学习

GNN vs Node2Vec:

Node2Vec:
  - 基于随机游走
  - 独立训练每个节点
  - 不共享参数

GNN:
  - 基于消息传递
  - 所有节点共享权重矩阵
  - 端到端训练
  - 可以处理新节点(inductive)

选择:
- 图静态、无节点特征 → Node2Vec
- 图动态、有节点特征 → GNN
- 大规模图 → GraphSAGE (GNN变体)

7. 实际应用场景

7.1 社交网络分析

┌────────────────────────────────────────┐
│        社交网络应用                     │
├────────────────────────────────────────┤
│                                         │
│  任务1:好友推荐                        │
│    给定:社交图                         │
│    预测:哪些用户可能成为朋友?         │
│    方法:链接预测(Link Prediction)   │
│                                         │
│  任务2:社区发现                        │
│    给定:社交图                         │
│    目标:找出紧密连接的用户群体         │
│    方法:图聚类(Graph Clustering)    │
│                                         │
│  任务3:影响力传播                      │
│    给定:社交图 + 用户行为               │
│    预测:信息如何在网络中传播?         │
│    方法:时序图神经网络                 │
│                                         │
└────────────────────────────────────────┘

可视化:好友推荐

当前好友关系:
    你 ────── 张三 ────── 李四
    │                     │
    │                     │
    王五 ────── 赵六 ────── 李四

分析:
- 你和李四有2个共同好友(张三、王五)
- GNN 学习到:共同好友多 → 可能认识

推荐:
你 ─────?─────→ 李四  (推荐成为好友)

7.2 推荐系统

┌────────────────────────────────────────┐
│        推荐系统应用                     │
├────────────────────────────────────────┤
│                                         │
│  异质图:用户-物品二部图                │
│                                         │
│    用户1 ──购买──→ 商品A                │
│      │              ↑                  │
│    浏览           购买                  │
│      ↓              │                  │
│    商品B ←──购买── 用户2                │
│                                         │
│  GNN 方法:                             │
│  1. 用户和商品都有 embedding            │
│  2. 通过消息传递更新 embedding          │
│  3. 预测用户对未交互商品的兴趣          │
│                                         │
│  优势:                                 │
│  - 利用高阶连接(朋友的朋友)           │
│  - 缓解冷启动问题                       │
│  - 可解释性(通过注意力权重)           │
│                                         │
└────────────────────────────────────────┘

实际案例:Pinterest(图钉)

Pinterest 用 PinSage(基于 GraphSAGE)做推荐:

图结构:
    Pin(图片) ─────→ Board(画板)
       │                 │
    相似性              包含
       │                 │
    Pin(图片) ←───── User(用户)

做法:
1. 构建 Pin-Pin 图(相似图片连接)
2. 用 GraphSAGE 学习 Pin 的 embedding
3. 对于用户喜欢的 Pin,推荐相似的 Pin

效果:
比传统方法提升 20% 点击率

7.3 药物发现

┌────────────────────────────────────────┐
│        药物发现中的 GNN                 │
├────────────────────────────────────────┤
│                                         │
│  任务1:分子性质预测                    │
│    分子 → 图                            │
│    节点:原子                           │
│    边:化学键                           │
│    预测:毒性、溶解度、生物活性         │
│                                         │
│  任务2:药物-靶点相互作用预测           │
│    输入:药物分子 + 蛋白质结构           │
│    输出:是否会结合?结合强度?         │
│    应用:虚拟筛选,加速新药开发         │
│                                         │
│  任务3:化学反应预测                    │
│    输入:反应物分子                     │
│    输出:可能的产物                     │
│    方法:图到图的生成模型               │
│                                         │
└────────────────────────────────────────┘

可视化:分子图

阿司匹林分子:

    O
    ║
H₃C─C─O─●─●─●─●─COOH
        │ │ │ │
        ●─●─●─●

转换为图:
节点:C, H, O 原子
边:单键、双键
节点特征:原子类型、电荷、杂化态等
边特征:键类型、键长等

GNN 任务:
输入:分子图
输出:是否有药效?毒性如何?

7.4 交通预测

┌────────────────────────────────────────┐
│        交通流量预测                     │
├────────────────────────────────────────┤
│                                         │
│  问题设定:                             │
│    节点:路口/路段                      │
│    边:道路连接                         │
│    节点特征:历史流量、时间、天气等     │
│    目标:预测未来流量                   │
│                                         │
│  方法:时空图神经网络(STGNN)          │
│    空间维度:用 GNN 捕捉路网结构        │
│    时间维度:用 RNN/TCN 捕捉时序模式    │
│                                         │
│  应用:                                 │
│    - 交通拥堵预警                       │
│    - 路径规划优化                       │
│    - 信号灯控制                         │
│                                         │
└────────────────────────────────────────┘

时空图的可视化

【空间图】路网结构

    路口A ─── 路口B
      │        │
      │        │
    路口C ─── 路口D

【时间序列】某个路口的流量

    流量
      ↑
    100│     ╱╲    ╱╲
     50│   ╱    ╲╱    ╲
      0└──────────────────→ 时间
         早  中  晚  夜

【时空图神经网络】
同时考虑:
1. 路口A的流量受邻近路口影响(空间)
2. 流量有周期性规律(时间)

7.5 知识图谱

┌────────────────────────────────────────┐
│        知识图谱应用                     │
├────────────────────────────────────────┤
│                                         │
│  结构:                                 │
│    (实体1, 关系, 实体2) 三元组          │
│    例如:(乔布斯, 创立, 苹果公司)       │
│                                         │
│  任务1:知识图谱补全                    │
│    给定:(?, 创立, 特斯拉)              │
│    预测:? = 马斯克                     │
│    方法:链接预测                       │
│                                         │
│  任务2:实体对齐                        │
│    不同知识图谱中的相同实体对齐         │
│    例如:维基百科的"北京" = 百度百科的"北京" │
│                                         │
│  任务3:问答系统                        │
│    问题:"谁创立了苹果公司?"           │
│    在知识图谱上推理,得到答案           │
│                                         │
└────────────────────────────────────────┘

知识图谱示例

            创立
    乔布斯 ─────→ 苹果公司
      │             │
    出生于         总部
      │             │
      ↓             ↓
    旧金山 ←────── 库比蒂诺
           位于

GNN 应用:
1. 学习实体和关系的 embedding
2. 预测缺失的三元组
3. 多跳推理(A→B→C 传递关系)

8. 代码实现示例

8.1 使用 PyTorch Geometric

# 安装
# pip install torch-geometric

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.datasets import Planetoid

# 1. 加载数据集(Cora 论文引用网络)
dataset = Planetoid(root='/tmp/Cora', name='Cora')
data = dataset[0]

print(f'数据集: {dataset}')
print(f'节点数: {data.num_nodes}')
print(f'边数: {data.num_edges}')
print(f'特征维度: {data.num_node_features}')
print(f'类别数: {dataset.num_classes}')

# 数据结构:
# data.x: 节点特征矩阵 [num_nodes, num_features]
# data.edge_index: 边索引 [2, num_edges]
# data.y: 节点标签 [num_nodes]

# 2. 定义 GCN 模型
class GCN(torch.nn.Module):
    def __init__(self, num_features, num_classes):
        super().__init__()
        # 第一层 GCN
        self.conv1 = GCNConv(num_features, 16)
        # 第二层 GCN
        self.conv2 = GCNConv(16, num_classes)
    
    def forward(self, data):
        x, edge_index = data.x, data.edge_index
        
        # 第一层
        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, p=0.5, training=self.training)
        
        # 第二层
        x = self.conv2(x, edge_index)
        
        return F.log_softmax(x, dim=1)

# 3. 创建模型
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GCN(dataset.num_node_features, dataset.num_classes).to(device)
data = data.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

# 4. 训练
def train():
    model.train()
    optimizer.zero_grad()
    out = model(data)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()
    return loss.item()

# 5. 测试
def test():
    model.eval()
    out = model(data)
    pred = out.argmax(dim=1)
    
    # 训练集准确率
    train_correct = pred[data.train_mask] == data.y[data.train_mask]
    train_acc = int(train_correct.sum()) / int(data.train_mask.sum())
    
    # 测试集准确率
    test_correct = pred[data.test_mask] == data.y[data.test_mask]
    test_acc = int(test_correct.sum()) / int(data.test_mask.sum())
    
    return train_acc, test_acc

# 6. 训练循环
for epoch in range(1, 201):
    loss = train()
    if epoch % 20 == 0:
        train_acc, test_acc = test()
        print(f'Epoch: {epoch:03d}, Loss: {loss:.4f}, '
              f'Train Acc: {train_acc:.4f}, Test Acc: {test_acc:.4f}')

8.2 从零实现简单 GCN

import torch
import torch.nn as nn
import numpy as np

class SimpleGCN(nn.Module):
    """
    简单的 GCN 实现(教学用)
    """
    def __init__(self, num_features, num_classes, hidden_dim=16):
        super().__init__()
        
        # 两层 GCN
        self.weight1 = nn.Linear(num_features, hidden_dim)
        self.weight2 = nn.Linear(hidden_dim, num_classes)
    
    def normalize_adjacency(self, A):
        """
        归一化邻接矩阵
        
        Ã = D^(-1/2) A D^(-1/2)
        """
        # 添加自环
        A_hat = A + torch.eye(A.size(0), device=A.device)
        
        # 计算度矩阵
        D = torch.diag(A_hat.sum(dim=1))
        
        # D^(-1/2)
        D_inv_sqrt = torch.pow(D, -0.5)
        D_inv_sqrt[torch.isinf(D_inv_sqrt)] = 0.
        
        # D^(-1/2) A D^(-1/2)
        A_norm = D_inv_sqrt @ A_hat @ D_inv_sqrt
        
        return A_norm
    
    def forward(self, X, A):
        """
        前向传播
        
        X: 节点特征 [num_nodes, num_features]
        A: 邻接矩阵 [num_nodes, num_nodes]
        """
        # 归一化邻接矩阵
        A_norm = self.normalize_adjacency(A)
        
        # 第一层
        H = A_norm @ X  # 聚合邻居
        H = self.weight1(H)  # 线性变换
        H = torch.relu(H)  # 激活
        
        # 第二层
        H = A_norm @ H
        H = self.weight2(H)
        
        return torch.log_softmax(H, dim=1)


# 使用示例
if __name__ == "__main__":
    # 构造一个小图
    num_nodes = 5
    num_features = 3
    num_classes = 2
    
    # 节点特征(随机)
    X = torch.randn(num_nodes, num_features)
    
    # 邻接矩阵
    A = torch.tensor([
        [0, 1, 1, 0, 0],  # 节点0连接1,2
        [1, 0, 1, 1, 0],  # 节点1连接0,2,3
        [1, 1, 0, 1, 1],  # 节点2连接0,1,3,4
        [0, 1, 1, 0, 1],  # 节点3连接1,2,4
        [0, 0, 1, 1, 0],  # 节点4连接2,3
    ], dtype=torch.float)
    
    # 标签
    y = torch.tensor([0, 0, 1, 1, 1])
    
    # 创建模型
    model = SimpleGCN(num_features, num_classes)
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
    
    # 训练
    for epoch in range(100):
        optimizer.zero_grad()
        
        # 前向传播
        out = model(X, A)
        
        # 计算损失
        loss = nn.functional.nll_loss(out, y)
        
        # 反向传播
        loss.backward()
        optimizer.step()
        
        if (epoch + 1) % 20 == 0:
            # 预测
            pred = out.argmax(dim=1)
            acc = (pred == y).float().mean()
            print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}, Acc: {acc:.4f}')

8.3 图注意力网络(GAT)实现

import torch
import torch.nn as nn
import torch.nn.functional as F

class GATLayer(nn.Module):
    """
    图注意力层
    """
    def __init__(self, in_features, out_features, dropout=0.6, alpha=0.2):
        super().__init__()
        self.in_features = in_features
        self.out_features = out_features
        
        # 权重矩阵
        self.W = nn.Parameter(torch.empty(size=(in_features, out_features)))
        nn.init.xavier_uniform_(self.W.data)
        
        # 注意力参数
        self.a = nn.Parameter(torch.empty(size=(2*out_features, 1)))
        nn.init.xavier_uniform_(self.a.data)
        
        self.leakyrelu = nn.LeakyReLU(alpha)
        self.dropout = nn.Dropout(dropout)
    
    def forward(self, h, adj):
        """
        h: 节点特征 [N, in_features]
        adj: 邻接矩阵 [N, N]
        """
        # 线性变换
        Wh = torch.mm(h, self.W)  # [N, out_features]
        
        # 计算注意力系数
        a_input = self._prepare_attentional_mechanism_input(Wh)
        e = self.leakyrelu(torch.matmul(a_input, self.a).squeeze(2))
        
        # 只保留有边的注意力
        zero_vec = -9e15 * torch.ones_like(e)
        attention = torch.where(adj > 0, e, zero_vec)
        
        # Softmax
        attention = F.softmax(attention, dim=1)
        attention = self.dropout(attention)
        
        # 加权聚合
        h_prime = torch.matmul(attention, Wh)
        
        return h_prime, attention
    
    def _prepare_attentional_mechanism_input(self, Wh):
        """
        准备注意力机制的输入
        """
        N = Wh.size()[0]
        
        # 扩展维度
        Wh_repeated_in_chunks = Wh.repeat_interleave(N, dim=0)
        Wh_repeated_alternating = Wh.repeat(N, 1)
        
        # 拼接
        all_combinations_matrix = torch.cat([
            Wh_repeated_in_chunks,
            Wh_repeated_alternating
        ], dim=1)
        
        return all_combinations_matrix.view(N, N, 2 * self.out_features)


class GAT(nn.Module):
    """
    多头图注意力网络
    """
    def __init__(self, num_features, num_classes, hidden=8, num_heads=8, dropout=0.6):
        super().__init__()
        
        # 第一层:多头注意力
        self.attentions = nn.ModuleList([
            GATLayer(num_features, hidden, dropout)
            for _ in range(num_heads)
        ])
        
        # 第二层:单头注意力
        self.out_att = GATLayer(hidden * num_heads, num_classes, dropout)
        
        self.dropout = nn.Dropout(dropout)
    
    def forward(self, x, adj):
        # 第一层:多头拼接
        x = self.dropout(x)
        x = torch.cat([att(x, adj)[0] for att in self.attentions], dim=1)
        x = F.elu(x)
        
        # 第二层
        x = self.dropout(x)
        x, attention = self.out_att(x, adj)
        
        return F.log_softmax(x, dim=1), attention


# 使用示例
if __name__ == "__main__":
    # 创建模型
    model = GAT(num_features=10, num_classes=3, hidden=8, num_heads=4)
    
    # 随机数据
    num_nodes = 20
    X = torch.randn(num_nodes, 10)
    A = torch.randint(0, 2, (num_nodes, num_nodes)).float()
    
    # 前向传播
    output, attention = model(X, A)
    
    print(f"输出形状: {output.shape}")  # [20, 3]
    print(f"注意力权重形状: {attention.shape}")  # [20, 20]

9. 进阶话题

9.1 Over-smoothing 问题

问题:
GNN 层数过多时,所有节点的表示会趋于相同

原因:
每一层都聚合邻居信息
多层后,所有节点都看到了整个图
表示变得无法区分

可视化:
     初始 →  2层  →  4层  →  8层
      ●       ●       ●       ●
     ╱│╲     ╱│╲     ╱│╲     ╱│╲
    ●─●─●   ●─●─●   ●─●─●   ●─●─●
    
表示:
    不同    略相似   很相似   几乎相同
    
    h_i ≠ h_j → h_i ≈ h_j → h_i ≈ h_j ≈ h_k

解决方案

方法1:跳跃连接(Skip Connection)
  h_i^(k) = h_i^(k-1) + GNN(h_i^(k-1))
  保留初始信息

方法2:Dropout + DropEdge
  随机丢弃边,防止过度平滑

方法3:预训练 + 微调
  先用浅层GNN,再精调

方法4:图正则化
  添加正则项,鼓励节点表示差异化

方法5:采样邻居
  不聚合所有邻居(GraphSAGE)

9.2 GNN 的可解释性

问题:
GNN 是黑盒模型,难以理解预测依据

解决方案:

方法1:可视化注意力权重(GAT)

优势:
- 直接显示哪些邻居重要
- 可以画热力图

示例:
节点A的注意力分布:
  B: ████████ 80%  ← 最重要
  C: ██ 15%
  D: █ 5%

结论:A的预测主要受B影响

方法2:GNNExplainer

思想:
找到最小的子图,能够解释预测结果

算法:
1. 遮盖掉某些边
2. 看预测是否改变
3. 找到最关键的边

可视化:
    ●───●───●
     ╲  │  ╱     完整图
      ● ●
      
    ●───●   ●
         │       关键子图(解释预测)
      ● ●

方法3:反事实解释

问题:
如果改变某个边/特征,预测会如何变化?

例子:
原图:A-B-C,预测A是"研究生"
反事实:去掉A-B边,预测A变成"本科生"
结论:A-B的连接是关键!

9.3 动态图神经网络

问题:
真实世界的图是动态变化的
- 社交网络:用户不断建立/删除好友
- 交通网络:流量实时变化
- 知识图谱:新知识不断加入

传统GNN:
只能处理静态图

动态GNN:
处理时序变化的图

方法1:时序图神经网络(TGNN)

思想:
结合GNN和RNN/LSTM

架构:
    时刻1    时刻2    时刻3
    G_1 →    G_2 →    G_3
     ↓        ↓        ↓
    GNN      GNN      GNN
     ↓        ↓        ↓
    h_1  →  h_2  →  h_3
     └─────LSTM─────┘

空间:GNN捕捉图结构
时间:LSTM捕捉演化

方法2:连续时间动态图

事件流:
t=0.5: 用户A关注B
t=1.2: 用户B发帖子
t=2.1: 用户C点赞
...

方法:
- 每个事件触发更新
- 用时间编码(time encoding)
- 持续学习(continual learning)

9.4 异质图神经网络

异质图:
多种类型的节点和边

例子:学术网络
  节点类型:论文、作者、会议
  边类型:写作、发表、引用

挑战:
- 不同类型节点的特征空间不同
- 不同类型边的语义不同

解决:异质图神经网络(HAN, HGT)

HAN(Heterogeneous Graph Attention Network)

核心思想:
1. 元路径(Meta-path)
   定义不同类型节点间的路径
   例如:作者-论文-作者(合作关系)
        作者-论文-会议(研究领域)

2. 节点级注意力
   聚合同一元路径上的邻居

3. 语义级注意力
   融合不同元路径的信息

可视化:
元路径1: A─论文─A  (合作者)
元路径2: A─论文─会议 (领域)

对作者A:
1. 沿元路径1聚合
2. 沿元路径2聚合
3. 用注意力融合两种信息

10. 常见问题解答

Q1: GNN 和 CNN 的区别?

CNN(卷积神经网络):
- 适用于:规则网格数据(图像)
- 卷积核:固定大小(如3×3)
- 邻居:固定数量(8个)
- 平移不变性

GNN(图神经网络):
- 适用于:不规则图数据
- "卷积":动态,取决于邻居数
- 邻居:变化的(1个、10个、100个...)
- 置换不变性

可以理解为:
CNN是GNN的特例(用于网格图)

Q2: GNN 可以处理多大的图?

小图(<10K节点):
  所有GNN都可以
  可以存整个邻接矩阵

中等图(10K-1M节点):
  用采样方法(GraphSAGE)
  minibatch训练

大图(>1M节点):
  必须用采样 + 分布式训练
  例如:Pinterest有数十亿节点

技巧:
1. 邻居采样(固定K个邻居)
2. 层采样(每层采样)
3. 子图采样(训练时只用子图)
4. 分布式GNN(多机多卡)

Q3: 如何选择 GNN 架构?

决策树:

1. 图的规模?
   小 (<10K)  → GCN/GAT 都可以
   大 (>1M)   → GraphSAGE

2. 是否有节点特征?
   有 → 直接用GNN
   无 → 先用Node2Vec预训练

3. 需要可解释性?
   是 → GAT(可视化注意力)
   否 → GCN(更简单快速)

4. 图是否动态?
   是 → 动态GNN(TGNN)
   否 → 静态GNN

5. 是否异质图?
   是 → HAN/HGT
   否 → GCN/GAT/GraphSAGE

Q4: GNN 的训练很慢怎么办?

加速技巧:

1. 硬件加速
   - 用GPU(10-100倍加速)
   - 多GPU并行

2. 采样技巧
   - 邻居采样(GraphSAGE)
   - 层采样(FastGCN)
   - 子图采样(ClusterGCN)

3. 模型简化
   - 减少层数(2-3层通常够用)
   - 减少隐藏维度
   - 去掉非必要组件

4. 训练技巧
   - 预计算邻接矩阵的归一化
   - 缓存中间结果
   - 混合精度训练(FP16)

5. 分布式训练
   - 数据并行
   - 模型并行

Q5: GNN 会过拟合吗?如何防止?

会!尤其是小图上。

防止过拟合的方法:

1. Dropout
   - 节点 Dropout
   - 边 Dropout(DropEdge)

2. 正则化
   - L2 正则
   - 图正则化

3. 早停(Early Stopping)
   - 监控验证集性能
   - 性能不再提升时停止

4. 数据增强
   - 添加边(增加连接)
   - 删除边(提高鲁棒性)
   - 节点特征加噪声

5. 模型集成
   - 训练多个GNN
   - 投票或平均预测

6. 预训练
   - 在大图上预训练
   - 在小图上微调

Q6: 如何处理新加入的节点(Inductive Learning)?

问题:
训练时没见过的节点,如何预测?

Transductive方法(不行):
- GCN:必须重新训练整个图
- Node2Vec:每个节点独立embedding

Inductive方法(可以):
- GraphSAGE:学习聚合函数,不是固定embedding
- GAT:注意力机制泛化到新节点

关键:
学习的是"如何聚合邻居"
而不是"每个节点的embedding"

例子:
训练:节点A, B, C
测试:新节点D
GraphSAGE:
  1. 看D的邻居(假设是A, B)
  2. 用学到的聚合函数处理A, B
  3. 得到D的embedding

📚 总结

核心要点

图神经网络(GNN):
✅ 处理图结构数据的深度学习方法
✅ 通过消息传递机制学习节点/图表示
✅ 结合了图论和神经网络

核心思想:
节点 → 聚合邻居 → 更新自己 → 多轮传递

三大任务:
1. 节点分类(Node Classification)
2. 链接预测(Link Prediction)
3. 图分类(Graph Classification)

常用架构:
- GCN:简单高效,谱方法
- GraphSAGE:可扩展,采样聚合
- GAT:注意力机制,可解释

学习路径

入门阶段(1-2周):
□ 理解图的基本概念
□ 掌握消息传递机制
□ 实现简单的GCN

进阶阶段(1-2月):
□ 学习主流GNN架构(GCN, GAT, GraphSAGE)
□ 在公开数据集上实验
□ 理解over-smoothing等问题

高级阶段(3-6月):
□ 异质图、动态图
□ 大规模图的处理
□ 最新研究论文
□ 实际应用项目

推荐资源

入门教程:
1. Stanford CS224W - 图机器学习
2. Distill.pub - GNN可视化教程
3. PyTorch Geometric 官方教程

论文阅读:
1. GCN: "Semi-Supervised Classification with GCN"
2. GraphSAGE: "Inductive Representation Learning"
3. GAT: "Graph Attention Networks"

代码库:
1. PyTorch Geometric(最流行)
2. DGL(Deep Graph Library)
3. Spektral(Keras-based)

实战项目:
1. Cora论文分类(入门)
2. 社交网络链接预测(进阶)
3. 分子性质预测(高级)

未来方向

当前研究热点:
1. 大规模图的高效训练
2. 动态图、时序图
3. 图生成(Graph Generation)
4. 图Transformer
5. GNN + LLM 结合
6. 可解释性
7. 鲁棒性和对抗攻击

应用前沿:
1. 药物发现(AI制药)
2. 蛋白质结构预测
3. 推荐系统
4. 交通预测
5. 金融风控
6. 知识图谱

祝你在图深度学习的道路上越走越远!🚀

最后更新:2025年11月
作者:Echo

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐