Stanford CS224W(Machine Learning with Graphs)是图神经网络领域最系统的公开课程。对 AI 药物发现而言,它的价值在于讲清了「为什么图这种结构需要专门的方法」——而分子本质上就是图。
课程结构与药物发现的对应
| 课程主题 | 在药物发现中的对应 | 重要度 |
|---|---|---|
| 图的表示与特征 | 分子图的原子/键特征 | 高 |
| 传统方法(节点度、中心性) | 拓扑描述符 | 中 |
| 消息传递与 GNN | 分子性质预测的核心 | 最高 |
| GNN 的表达能力(WL 测试) | 理解 GNN 的能力上限 | 高 |
| 图池化与读出 | 从原子表示到分子表示 | 高 |
| 知识图谱嵌入 | 药物重定位(见 157《AI DTI 预测模型》) | 中 |
| 图生成 | 分子生成(见 158《AI 分子生成模型》) | 中 |
| 大规模图 | 生物网络分析 | 低(分子图很小) |
最需要理解的三个概念
# ---- 概念一:消息传递 ----
#
# 每个节点从邻居收集信息并更新自己
# 经过 K 层,每个节点包含 K 跳邻域的信息
#
# 【对分子的含义】:
# 一个原子的表示,编码了它周围 K 个键范围内的化学环境
# → 这与 ECFP 指纹的半径概念【几乎等价】(见 046)
#
# 【关键推论】:
# 3 层 GNN ≈ ECFP(r=3) 的信息范围
# → 这解释了为什么两者性能常常接近(见 159)
#
# ---- 概念二:表达能力与 WL 测试 ----
#
# Weisfeiler-Lehman 图同构测试:
# 一个判断两个图是否同构的经典算法
# 它的过程与消息传递惊人地相似
#
# 【重要结论】:
# 标准的消息传递 GNN 的判别能力
# 【不超过 1-WL 测试】
# → 存在不同的分子图,GNN 无法区分
#
# 【实际含义】:
# 某些环系结构的差异,GNN 「看不见」
# → 这是架构层面的限制,加数据也解决不了
# → 应对:加入额外特征(环信息、子结构计数)
#
# 【GIN 的意义】:
# 它是能达到 1-WL 上限的架构
# → 这是它在分子任务上常常表现好的理论依据
#
# ---- 概念三:过平滑 ----
#
# 层数增加时,所有节点的表示趋于相同
# → 因为反复平均邻居信息,差异被抹平
#
# 【实际含义】:
# GNN 通常只能做 3~5 层
# → 感受野受限
# → 难以捕捉分子内的长距离相互作用
#
# 应对:残差连接、跳跃连接、虚拟节点
与分子建模的差异:需要意识到的
- 分子图很小:通常几十个原子,而课程中很多内容针对的是社交网络这类百万节点的大图——可扩展性的讨论对分子不那么重要;
- 分子图有强的化学约束:价键规则、环的性质——通用图方法不知道这些,需要通过特征工程注入;
- 三维信息:课程主要讲拓扑图,而分子的三维构象常常重要——需要额外学等变网络(见 160《等变神经网络》);
- 数据量:分子数据集通常只有几千个样本,而课程中的方法很多是为大数据设计的——过拟合是分子任务的主要挑战;
- 基线的重要性:课程不会告诉你「ECFP + 随机森林常常打平 GNN」——这个实践认识需要另外补(见 131《Chemprop / D-MPNN 论文精读》)。
学习建议
# 【不需要看完整个课程】
#
# 对药物发现,重点是:
# □ 图的基本概念与表示
# □ 消息传递框架(【最核心】)
# □ GCN、GAT、GIN 的差异
# □ 表达能力与 WL 测试
# □ 图池化
# □ 图生成(如果要做分子生成)
#
# 可以跳过或略读:
# - 大规模图的扩展性
# - 社交网络特有的任务
# - 推荐系统
#
# 【配套实践】:
# 课程的 Colab 作业用 PyTorch Geometric
# → 【这正是分子 GNN 最常用的库】(见 176)
# → 做完作业就掌握了实现能力
#
# 【学完之后的练习】:
# 1) 用 PyG 实现一个分子性质预测的 GNN
# 2) 【与 ECFP + LightGBM 基线比较】
# 3) 试着加入 RDKit 全局描述符,看提升多少
# 4) 用骨架划分评测,看与随机划分的差距
# → 这四步做完,你对分子 GNN 的理解
# 会超过大部分只读论文的人
用 PyTorch Geometric 做分子图
from torch_geometric.data import Data
from rdkit import Chem
import torch
def mol_to_pyg(smiles, y=None):
mol = Chem.MolFromSmiles(smiles)
if mol is None:
return None
# 原子特征 —— 【特征设计比架构更影响结果】
x = []
for a in mol.GetAtoms():
x.append([
a.GetAtomicNum(),
a.GetDegree(),
a.GetFormalCharge(),
int(a.GetHybridization()),
int(a.GetIsAromatic()),
a.GetTotalNumHs(),
int(a.IsInRing()),
int(a.GetChiralTag()),
])
# 边 —— 【无向图必须存两个方向】
ei, ea = [], []
for b in mol.GetBonds():
i, j = b.GetBeginAtomIdx(), b.GetEndAtomIdx()
f = [int(b.GetBondTypeAsDouble() * 2),
int(b.GetIsConjugated()),
int(b.IsInRing()),
int(b.GetStereo())]
ei += [[i, j], [j, i]]
ea += [f, f]
return Data(
x=torch.tensor(x, dtype=torch.float),
edge_index=torch.tensor(ei, dtype=torch.long).t().contiguous(),
edge_attr=torch.tensor(ea, dtype=torch.float),
y=torch.tensor([y], dtype=torch.float) if y is not None else None,
)
# 【常见错误】:
# 1) 忘记双向边 → 消息只单向传递
# 2) 原子特征用原始数字而非独热编码
# → 模型会以为「碳(6) 与氮(7) 相邻」有数值意义
# 3) 忘记处理 mol 为 None 的情况
关键要点
- K 层 GNN 的信息范围与 ECFP 半径 K 几乎等价——这是理解两者性能接近的关键;
- 标准 GNN 的判别力不超过 1-WL 测试——某些分子图它「看不见」差异;
- 过平滑限制了层数(3~5 层),难以捕捉长距离相互作用;
- 课程不会讲「ECFP 基线常常打平 GNN」——这个实践认识必须另外补。
延伸资源
- GNN 论文精读:159《图神经网络 GNN》;等变网络:160《等变神经网络》;Chemprop:131《Chemprop / D-MPNN 论文精读》;
- PyTorch Geometric:176《PyTorch Geometric》;分子图表示:034《分子图表示》。