
化学人转 AI最容易踩的坑不是 Python 不会写而是照搬计算机视觉或 NLP 的套路学了一两个月最后发现分子数据根本用不上。分子不是一张像素图也不是一段自然语言它是一张由原子和化学键构成的图。真正跟化学科研场景强相关的核心技术是图神经网络GNN以及把药物、靶点、疾病、材料、反应条件统一建模的异构图神经网络HGNN。本文围绕“化学人转 AI”这条主线展开先从能力地图看清 GNN/HGNN 在科研应用中的定位再讲清楚分子图表示、消息传递机制这些核心概念然后给出一套可在本机跑通的 GNN 分子性质预测实战流程以及异构图模型的代码骨架最后是完整学习路径、资源占用观察、常见问题排查和合规边界。下面内容不需要你懂深度学习的数学推导但要求你会一点 Python。如果你已经会用 pandas 读数据、能写简单的训练循环这篇文章可以直接当路线图用。1. 化学AI学习地图与核心技术速览先给一张速览表把整个知识域的关键信息列清楚后续每一行都会在正文展开。维度核心内容核心技术GNNGCN、GraphSAGE、GAT、GINHGNNRGCN、HAN、HGT、HeteroConv主流框架PyTorch GeometricPyG、Deep Graph LibraryDGL化学工具RDKit、PubChemPy、MoleculeNet 基准数据集、QM9、ESOL、BACE、HIV典型科研任务分子性质预测、虚拟筛选、逆合成分析、反应条件预测、药物重定位、材料性能回归数据形态分子图节点原子边化学键、晶体结构、药物-靶点-疾病异构图、反应网络环境要求Python 3.10、PyTorch、PyG、RDKit学习阶段 CPU 可跑硬件建议实验阶段 4GB 显存可用预训练大模型或大规模异构图建议 8GB 以上适合人群化学、材料、药学、生物背景学生或工程师目标进入 AI for Science 交叉方向需要说明的是这些参数不是拍脑袋写死的。数据量、批量大小、图卷积层数变化时显存占用和训练时间都会变化判断方法会在第 7 节单独给出来。2. GNN 核心原理分子为什么天然适合图神经网络2.1 分子表示从 SMILES 到分子图化学人最熟悉的分子表示是 SMILES 字符串比如阿司匹林是CC(O)Oc1ccccc1C(O)O。SMILES 的优势是紧凑、便于存储和检索但它把二维拓扑结构压缩成一个线性序列模型直接学习时容易丢失原子之间的局部连接上下文。两个结构差异很大的分子SMILES 字符串可能只差一个字符两个几乎一样的分子字符串表达也可能很不一样。分子图是更接近化学直觉的表示方式每个原子是一个节点每条化学键是一条边。节点可以携带特征比如原子序数、杂化类型、形式电荷、手性标记、氢原子数量边也可以携带特征比如键级、共轭状态、是否成环。一张分子图就是结构信息的完整载体不需要像 SMILES 那样做语法解析。用 RDKit 把 SMILES 转成分子对象并读取原子信息的代码很简单from rdkit import Chem smiles CC(O)Oc1ccccc1C(O)O # 阿司匹林 mol Chem.MolFromSmiles(smiles) for atom in mol.GetAtoms(): print(atom.GetSymbol(), atom.GetDegree(), atom.GetTotalNumHs())运行后能看到每个原子的元素符号、度和氢原子数量这是构造图节点特征的基础步骤。实际项目中节点特征还会加入芳香性、杂化方式、是否在环中等信息边特征则包括键级、共轭状态、是否可旋转等。这里必须提醒一句SMILES 存在多种等价写法同一个分子用不同 SMILES 表示时如果不做标准化模型可能把它当成不同样本。这个细节会在第 8 章排查表里重点说。2.2 消息传递机制GNN 的核心机制是消息传递Message Passing。每一层里节点聚合邻居节点的特征更新自己的表示。可以这样理解一个原子“看见”直接相连的原子经过一层后它携带了自己和邻居的信息经过两层它携带了二阶邻居的信息层数越多信息沿化学键扩散的范围越大。消息传递的一般形式# 第 l 层节点 i 的更新伪代码 # h_i^(l1) UPDATE(h_i^(l), AGGREGATE({h_j^(l) : j in N(i)}))AGGREGATE 把邻居特征聚合成一个向量UPDATE 把聚合结果和自身特征融合在一起。不同 GNN 变体的主要差异就在这两个函数上GCN对邻居特征做归一化求和再经过权重变换最简单直接GraphSAGE支持 Mean、Max、LSTM 等聚合方式适合大图GAT引入注意力权重每个邻居对中心节点的贡献不同GIN用求和聚合加多层感知机理论上对图结构的区分能力更强。对分子性质预测任务GIN 和 GAT 是目前比较常用且效果稳定的基线GCN 作为入门模型最直观先跑通再换更强变体是更稳妥的路线。2.3 图读出与分子级预测节点表示更新完之后如果任务是预测整个分子的性质水溶性、毒性、HOMO-LUMO 带隙还需要把全图节点表示聚合成一个图级向量这个操作叫图读出Readout。常见方法包括均值池化、最大值池化、加和池化和注意力池化。在 PyG 里这些都是现成函数代码上就是一行调用但理解它们各自的语义仍然很重要加和池化保留了图的规模信息均值池化对规模不敏感注意力池化则让模型自己学每个节点的权重。3. 环境准备从零搭建化学 GNN 开发环境3.1 安装与验证学习阶段建议用 conda 建独立虚拟环境避免和日常科研环境互相污染。conda create -n chemai python3.10 -y conda activate chemai pip install torch torchvision pip install torch-geometric pip install rdkit pandas scikit-learn matplotlib关于 PyTorch 版本如果本机有 NVIDIA 显卡需要根据 CUDA 版本选择对应的 PyTorch 安装命令官方安装页有完整的索引地址如果只有 CPU也能跑完本文所有代码。PyG 安装后建议立刻做一次验证import torch from torch_geometric.nn import GCNConv print(torch.__version__) conv GCNConv(16, 32) print(conv)能正常打印出 GCNConv 结构说明环境没问题。如果 import 阶段报错优先检查 PyTorch 和 PyG 版本是否匹配PyG 官网有安装矩阵可以对照。3.2 项目目录规划建议按下面的结构管理 GNN 学习项目避免所有代码堆在一个文件里chemai-lab/ ├── data/ # 数据集缓存 ├── models/ # 模型定义 ├── scripts/ # 训练和评估脚本 ├── notebooks/ # 调试和可视化 └── outputs/ # 训练日志、预测结果GNN 项目迭代很快模型、数据、训练逻辑拆开后面换数据集或换模型会省很多时间。另一个容易被忽略的问题是数据下载缓存目录和输出目录要分开数据集一旦下载完成就不要再动输出结果按日期命名方便回溯。4. 实战用 GNN 做分子性质预测4.1 数据集选择先别直接上 QM9 这种十几万分子的大数据集建议用 MoleculeNet 里的 ESOL 做第一次完整流程。ESOL 是水溶性回归数据集样本量较小单个 epoch 训练时间可控适合验证模型、调试超参数。PyG 内置了 MoleculeNet 加载接口from torch_geometric.datasets import MoleculeNet dataset MoleculeNet(root./data, nameESOL) print(f样本量: {len(dataset)}) print(f节点特征维度: {dataset.num_node_features}) print(f任务数: {dataset.num_tasks})第一次运行会自动下载数据需要联网下载完成后缓存在./data目录后续直接加载。4.2 模型定义这里用三层 GCN 加图级均值池化。目的不是刷精度而是看清“节点特征经过消息传递、再经过池化变成图级特征”这条完整链路。import torch import torch.nn.functional as F from torch_geometric.nn import GCNConv, global_mean_pool class MoleculeGCN(torch.nn.Module): def __init__(self, in_channels, hidden_channels128, out_channels1): super().__init__() self.conv1 GCNConv(in_channels, hidden_channels) self.conv2 GCNConv(hidden_channels, hidden_channels) self.conv3 GCNConv(hidden_channels, hidden_channels) self.classifier torch.nn.Linear(hidden_channels, out_channels) def forward(self, data): x, edge_index, batch data.x, data.edge_index, data.batch x F.relu(self.conv1(x, edge_index)) x F.relu(self.conv2(x, edge_index)) x F.relu(self.conv3(x, edge_index)) x global_mean_pool(x, batch) return self.classifier(x)三层对 ESOL 这类小分子数据集是安全起点。层数不是越深越好GNN 存在过平滑问题层数过多时所有节点表示趋于一致反而降低区分度。第一次跑就用一到三层观察效果再决定是否加深。4.3 训练与评估import torch from torch_geometric.loader import DataLoader # 划分数据集 train_size int(len(dataset) * 0.8) val_size int(len(dataset) * 0.1) test_size len(dataset) - train_size - val_size train_data, val_data, test_data torch.utils.data.random_split( dataset, [train_size, val_size, test_size] ) model MoleculeGCN(in_channelsdataset.num_node_features) optimizer torch.optim.Adam(model.parameters(), lr0.001) criterion torch.nn.MSELoss() train_loader DataLoader(train_data, batch_size32, shuffleTrue) for epoch in range(100): model.train() total_loss 0.0 for data in train_loader: optimizer.zero_grad() out model(data).view(-1) loss criterion(out, data.y.view(-1)) loss.backward() optimizer.step() total_loss loss.item() * data.num_graphs avg_loss total_loss / len(train_data) if (epoch 1) % 10 0: print(fEpoch {epoch1:03d}, Loss: {avg_loss:.4f})评估阶段model.eval() test_loader DataLoader(test_data, batch_size64) preds, trues [], [] with torch.no_grad(): for data in test_loader: out model(data).view(-1) preds.append(out) trues.append(data.y.view(-1)) preds torch.cat(preds) trues torch.cat(trues) rmse torch.sqrt(torch.mean((preds - trues) ** 2)) print(fTest RMSE: {rmse:.4f})判断成功的标准是训练 loss 随 epoch 下降测试 RMSE 落在合理范围。至于什么范围算合理不同数据集差异很大不要拿一个绝对值当通用标准。同一数据集上跑多个随机种子对比均值和方差比单次跑分更有说服力。判断模型真实水平一定要固定随机种子并记录配置文件否则结果不可复现。4.4 训练不收敛时的调整顺序训练出现问题按顺序检查比盲目改参数高效学习率从 0.001 改到 0.0001 重跑回归任务先对 y 做标准化消除量纲影响减少层数到一到两层排除过平滑干扰增大 hidden_channels但同步调小 batch_size换 GIN 或 GAT 变体对比不要在同一模型上调太久。4.5 批量预测把模型接到科研流程化学 AI 真正有价值的地方不是预测一个分子而是对一批候选分子做批量打分。下面是一个通用的批量预测模式from torch_geometric.loader import DataLoader def predict_batch(smiles_list, model, feature_builder): 对一批 SMILES 做分子性质预测返回预测值列表。 model.eval() data_list [] for s in smiles_list: data feature_builder(s) # 自定义函数SMILES - PyG Data 对象 if data is not None: data_list.append(data) preds [] with torch.no_grad(): for batch in DataLoader(data_list, batch_size32): out model(batch).view(-1) preds.extend(out.tolist()) return preds使用torch_geometric.utils.from_smiles可以直接把 SMILES 转成分子图但要注意它默认的原子特征维度和 MoleculeNet 预处理后的维度未必一致。实际做批量预测时训练集和预测集必须使用同一套特征函数否则会出现维度不匹配或者预测结果失效。5. 异构图神经网络化学场景里的“天花板”技术5.1 什么是异构图前面说的分子图是同构图所有节点都是原子所有边都是化学键。但真实的化学科研场景很少这么清爽。拿药物重定位举例节点可能同时包含药物分子、靶点蛋白质、疾病基因和通路数据药物与靶点之间有“结合”关系靶点与疾病之间有“关联”关系基因与通路之间有“参与”关系。节点类型不同边的类型也不同这种图就是异构图Heterogeneous Graph建模它的模型就是异构图神经网络。异构图模型的意义在于它允许一个统一的框架同时学习多种实体、多种关系的表示而不是把药物、蛋白、疾病分别建模之后再拼起来。分开建模的问题在于实体间的交互信息被结构性地割裂而 HGNN 天然保留这些交互关系这正好是药物研发这类问题最核心的需求。5.2 化学科研里的典型异构图场景场景节点类型边类型典型目标药物-靶点相互作用药物、蛋白质结合、抑制、激活药物重定位、靶点发现反应预测反应物、产物、试剂、条件参与、生成、催化逆合成分析、产率预测材料-性能预测元素、晶体节点、实验条件组成、掺杂、测量带隙、硬度、导电性预测多组学整合基因、蛋白质、代谢物、表型调控、表达、关联疾病分型、标志物筛选用同构图处理这些场景时必须先把多种节点硬编码到同一特征空间信息损失很大用异构图模型则可以直接在不同类型节点之间传递消息边的关系类型也变为模型可学习的信息。5.3 PyG 中的异构图数据对象PyG 提供了HeteroData构建异构数据结构非常直观from torch_geometric.data import HeteroData data HeteroData() # 三种节点类型 data[drug].x drug_feature_tensor # [num_drugs, drug_dim] data[protein].x protein_feature_tensor # [num_proteins, protein_dim] data[disease].x disease_feature_tensor # [num_diseases, disease_dim] # 两种边类型 data[drug, interacts, protein].edge_index drug_protein_edge_index data[protein, associated, disease].edge_index protein_disease_edge_index print(data)HeteroData 的结构逻辑是“节点类型到特征”和“节点类型对到边索引”。它底层会维护不同节点类型的偏移量把异构索引映射到统一索引模型层只看到统一的 edge_index 和 edge_type所以 RGCN 这类模型可以直接使用。5.4 RGCN 模型骨架RGCNRelational Graph Convolutional Network是异构图入门最经典的分层聚合模型。它在 GCN 基础上引入关系类型每种关系使用独立的变换矩阵这样不同类型边的语义差异就能被模型学习到。import torch import torch.nn.functional as F from torch_geometric.nn import RGCNConv class InteractionRGCN(torch.nn.Module): def __init__(self, in_channels, hidden_channels, num_relations, out_channels1): super().__init__() self.conv1 RGCNConv(in_channels, hidden_channels, num_relations) self.conv2 RGCNConv(hidden_channels, hidden_channels, num_relations) self.classifier torch.nn.Linear(hidden_channels, out_channels) def forward(self, x, edge_index, edge_type): x F.relu(self.conv1(x, edge_index, edge_type)) x F.relu(self.conv2(x, edge_index, edge_type)) return self.classifier(x)使用步骤通常三步先把 HeteroData 转成统一节点空间的 edge_index 和 edge_type再把各节点类型的特征拼接成统一特征矩阵最后送入 RGCN 训练。PyG 也提供 HGTConv、HeteroConv 等更高级的异构图层可以直接处理 HeteroData 结构而不用手动转换但对初学者来说手动走一遍 RGCN 的输入构造过程对理解消息传递逻辑的帮助最大。5.5 HGNN 为什么是“天花板”HGNN 的优势不是某一个模型架构的胜利而是问题建模方式的升级。同构图只能回答“这个分子有什么性质”异构图能回答“这个药物和这个靶点结合后对这条疾病通路会产生什么影响”。后者才是化学和生物科研真正需要的问题。从落地角度讲异构图模型在虚拟筛选流程中的位置很明确先做图构建再做子图或元路径采样然后进入 RGCN/HGT 训练最后输出候选列表交给湿实验验证。整个流程可以做成批量任务脚本这也是化学 AI 平台工程化的核心环节。6. 完整学习路径化学人转 AI 分阶段路线6.1 阶段一Python 与数据基础2-4 周目标不是成为软件工程师而是能独立处理科研数据。需要掌握 Python 基础语法、函数、类NumPy 数组操作pandas 读表、过滤、合并Matplotlib 画训练曲线和分子分布图。化学背景的读者最容易忽略的是“写代码的耐心”。从 pandas 读一张数据表到画出可解释的分布图这个闭环比记住某个 API 重要得多。建议每天留固定时间写代码不要只看教程。6.2 阶段二PyTorch 深度学习基础4-6 周目标是理解张量、自动求导、模型定义、训练循环这几个核心概念。建议完成两件事用 PyTorch 写一个线性回归和两层 MLP复现一次 MNIST 分类理解 batch、epoch、loss、accuracy 的含义。不需要在视觉或 NLP 任务上花太长时间能跑通分类和回归各一个任务把训练循环的肌肉记忆建立起来就够了。6.3 阶段三GNN 核心原理与代码6-8 周学习 GCN、GraphSAGE、GAT、GIN 的结构差异用 PyG 跑通文中的分子性质预测流程在 ESOL、FreeSolv、BACE 三个数据集上做对比实验。每个模型跑完都要记录三个数字训练 loss、验证指标、测试指标并保持相同的随机种子配置。6.4 阶段四化学信息学与基准数据集4 周掌握 RDKit 的分子读写、二值描述符、2D/3D 构象生成理解 MoleculeNet 各数据集的适用任务学会 SMILES 合法性和标准化处理理解分子指纹模型Morgan/ECFP与 GNN 的对比关系。很多时候 GNN 的对手不是另一个 GNN而是简单可靠的分子指纹加机器学习模型学会做这种基线对比才能判断 GNN 是否真的带来增益。6.5 阶段五异构图与真实科研应用持续进行阅读 RGCN、HAN、HGT 论文在药物-靶点-疾病数据上构建 HeteroData复现一次链路预测或节点分类实验最后结合自己的课题把 GNN/HGNN 应用到一个具体化学问题中。不要追求模型越复杂越好先解决一个具体的、数据可获取的问题把整个实验闭环跑通。6.6 学习路径总结表阶段核心技能可交付成果基础Python、NumPy、pandas数据处理脚本深度学习PyTorch 训练循环分类/回归基准实验GNNGCN/GAT/GIN PyG分子性质预测模型化学信息RDKit 处理分子数据分子图数据集构建异构图RGCN/HAN/HGT药物-靶点-疾病预测实验科研落地实验设计、消融分析、可复现训练项目报告或论文7. 资源占用与性能观察GNN 训练的资源占用和 CV 大模型不同。单个分子图很小但一个 batch 里可能包含几十到几百个分子图计算图规模取决于 batch 内总节点数和总边数而不是图像分辨率。实际观察资源占用只需要关注几个指标训练每个 epoch 耗时、显存占用峰值、数据加载耗时和 GPU 利用率。使用nvidia-smi可以实时观察显存占用。如果显存不足优先减小 batch_size而不是改模型结构其次是降低 hidden_channels最后才考虑减少层数。数据加载通常是瓶颈分子数量多时尽量把数据缓存到内存不要每次从磁盘读取。学习阶段用 CPU 跑 ESOL 这类小数据集完全可以接受但换到 QM9 或大规模异构图之后GPU 优势会非常明显。更稳妥的做法是先用 CPU 把训练流程调试通再切换到 GPU 训练避免在等待资源分配上浪费时间。所有训练脚本都应该把设备抽象成可配置参数device torch.device(cuda if torch.cuda.is_available() else cpu) model MoleculeGCN(in_channelsdataset.num_node_features).to(device)关于“跑多快、占多少”不同机器差别很大任何脱离具体硬件的断言都不靠谱。正确做法是记录自己机器的基准线固定数据、固定 batch_size统计每个 epoch 的耗时和显存占用后续改动模型时才能判断是否真正有效。8. 常见问题与排查方法问题现象可能原因排查方式解决方案PyG import 失败PyTorch 和 PyG 版本不匹配检查安装版本按 PyG 官方安装矩阵重装RDKit 转换 SMILES 返回 NoneSMILES 非法或格式不对打印原始字符串先把 SMILES 清洗标准化再转换训练 loss 不下降学习率过大、数据未归一化、模型过深打印每轮 loss调低学习率、做标准化、减少层数CUDA out of memorybatch 太大或图过大nvidia-smi 观察显存减小 batch_size 和 hidden_channels测试效果远差于训练数据划分泄漏或过拟合检查预处理统计量标准化 fit 在训练集上进行异构模型维度对不上各节点类型特征维度不一致打印各类型节点 shape统一节点特征维度数据集下载超时网络问题手动下载把数据文件放到缓存目录并设置环境变量结果不稳定、每次跑分不同随机种子未固定检查训练脚本固定 torch.manual_seed 和 DataLoader shuffle化学 AI 项目最常见的坑不是模型写不出来而是数据问题。SMILES 清洗、构型一致性、数据划分泄漏、标签错误任何一个环节出问题都会直接影响模型效果。遇到结果不合理先查数据再查模型这个顺序不要颠倒。9. 最佳实践、合规边界与后续扩展方向9.1 代码与科研规范固定随机种子多次运行取平均每个实验保留配置文件记录数据版本、模型结构、超参数模型、数据、训练脚本分目录管理图数据预处理一旦确定就不要重复执行随机操作。分子数据涉及专利化合物或未公开结构时注意数据来源的合法性和授权范围。科研实验必须有对照组。只跑一个 GNN 模型并展示结果说服力有限对比分子指纹加机器学习、对比不同 GNN 变体、对比不同池化策略才能说明你的方案到底强在哪里。这不仅是论文写作的要求也是判断自己模型是否有效的基本方法。9.2 合规与安全边界化学 AI 涉及药物研发、材料设计、分子筛查等敏感方向使用边界必须明确模型预测结果只能作为科研线索不能直接替代湿实验验证涉及人类疾病、药物毒理、临床试验相关数据必须遵守所在机构和国家的数据安全与伦理规范涉及患者基因组、医疗记录等隐私数据必须匿名化处理并获得合规授权使用公开数据集时注意各数据集原始来源的许可协议条款从论文复现模型时尊重原作者代码库的开源协议。9.3 后续扩展方向跑通 GNN 和异构图基础之后可以按兴趣选择扩展方向化学大语言模型方向MolT5、ChemLLM 等把分子表示和自然语言结合适合做分子描述生成和问答三维分子建模方向3D 构象对齐、SE(3) 等变图神经网络适合构象敏感的酶催化、结合亲和力预测分子生成模型方向基于 VAE、GAN、扩散模型做新分子生成配合性质预测模型形成闭环AI Agent 与化学自动化方向把模型接入实验记录系统做高通量筛选的自动化决策。这些方向都建立在 GNN/HGNN 的基础上前面的基础学得越扎实切换到新方向的时间成本越低。10. 总结与下一步化学人转 AI最容易犯的错误就是照着计算机视觉或自然语言处理的学习路线走了一遍最后发现跟自己的科研问题对不上。分子的数据结构天然是图GNN 和异构图神经网络才是化学 AI 的技术主赛道。运行建议很直接先跑通第 4 节的 ESOL 训练流程建立消息传递、图池化、回归训练的整体感知再去加载 QM9 观察大数据量下的显存差异之后尝试构建一个药物-靶点-疾病的 HeteroData 对象用 RGCN 做一次链路预测。每次实验保留数据和配置记录持续积累自己的化学 AI 基线库。值得提醒的是HGNN 不是可选项而是化学场景复杂化后的必然选择。药物重定位、多组学整合、材料筛选这些问题天然是异构的RGCN 和 HGT 这类模型值得在基础 GNN 之后优先投入。数据和合规问题要提前建立意识SMILES 清洗、数据划分泄漏、随机种子不固定任何一个都会让模型结果失效涉及药物和人类数据时授权和伦理边界必须优先确认。