4. 自监督学习范式:掩码建模、对比学习、生成式预训练
说到分子领域的预训练,你可能会问:没有标签数据,模型到底在学什么?
这个问题我当年也纠结过。直到我把 NLP 里的那套套路搬过来试了一下,才恍然大悟。说白了,分子就是一套自己跟自己玩的语法系统。自监督学习的核心,就是让模型从分子本身的结构中「找题做」。
今天咱们聊三种主流范式:掩码建模、对比学习、生成式预训练。它们各自解决了什么问题?我一个个拆开讲。
4.1 掩码建模:让模型学会「完形填空」
这个概念最早来自 BERT。你把序列中的一部分 token 遮住,让模型去猜被遮住的是什么。分子版的做法也很类似:随机 mask 掉某个原子或者某段子结构,然后预测被遮住的部分。
4.1.1 原子级掩码
我会把 SMILES 字符串当作句子来处理。比如"CC(=O)OC",把中间某个"C"替换成"[MASK]",任务就是预测这个位置最可能是哪个 token。
这个做法最直观。但有个坑要小心:SMILES 是线性化的字符串,同一个分子有多种合法写法。你在一种写法上训练的预训练模型,迁移到另一种写法可能完全失效。
# 伪代码:原子级掩码
graph = mol_to_graph("CC(=O)OC")
masked_atoms = random.sample(graph.atoms, k=0.15 * len(graph.atoms))
for atom in masked_atoms:
graph.node_features[atom] = MASK_TOKEN
predicted = model(graph)
loss = cross_entropy(predicted[masked_atoms], true_labels[masked_atoms])
4.1.2 片段级掩码
原子 mask 学到的是局部环境,但药效团、骨架这些更大的结构同样重要。片段级掩码就是把一组原子一起遮掉,比如一个苯环、一个羧基。我个人习惯用 BRICS 算法先分解分子,再随机 mask 掉整个片段。
| 掩码策略 | 粒度 | 学到的知识类型 | 下游任务偏好 |
|---|---|---|---|
| 原子级 mask | 单原子 | 局部化学环境 | 毒性位点预测 |
| 片段级 mask | 官能团/骨架 | 子结构语义 | 代谢稳定性预测 |
| 混合策略 | 两者兼有 | 多尺度表征 | 通用 |
4.2 对比学习:拉近正样本,推远负样本
掩码建模是在预测「被遮住的东西」。对比学习不同,它学习的是「哪些分子是相似的」。
具体做法:对同一个分子做两次不同的数据增强,得到两个视图。模型的任务就是让这两个视图的表示空间尽可能靠近,同时让不同分子的表示尽可能远离。
4.2.1 分子对构建
怎么构造正样本对?我常用的三种方法:
- 图扰动:随机加/删边、遮蔽节点特征
- SMILES 增强:对同一个分子,用不同 SMILES 写法(比如更换起始原子)
- 构象增强:从 3D 构象中随机采样一种
你想想看,如果模型连「同一个分子的两种写法」都认不出来,那它肯定没理解分子到底是什么。嗯,这里有一个关键点:增强不能太强,否则分子会变成另一个分子。我曾经把边的删除概率调到 0.3,结果正样本对几乎变成了负样本,下游性能直接崩了。
# 对比学习损失(NT-Xent)
def contrastive_loss(z_i, z_j, temperature=0.1):
# z_i, z_j: 两个视图的表示
batch_size = z_i.shape[0]
labels = torch.arange(batch_size)
logits = torch.mm(z_i, z_j.T) / temperature
loss = cross_entropy(logits, labels)
return loss
4.3 生成式预训练:从重建分子中学表征
生成式预训练的思路更直接:输入分子的一部分,让模型生成完整的分子。这就像让你通过几个关键词写一篇完整的文章。
4.3.1 自回归式生成
用类似 GPT 的做法。给定前半段 SMILES,逐 token 预测下一个 token。最后用下一个 token 预测的交叉熵作为损失。
这个方法的优势在于:生成的灵活性。模型不仅能理解分子,还能生成新的分子。我遇到过一个客户想要优化化合物的水溶性,我们就是用预训练的生成式模型做条件生成,效果比随机搜索好得多。
# 自回归生成训练
seq = tokenize("CC(=O)OC")
for i in range(1, len(seq)):
prefix = seq[:i]
target = seq[i]
logits = model(prefix)
loss += cross_entropy(logits, target)
4.4 三种范式的对比与选择
聊到这里,你可能想问:到底该用哪一种?我的答案很直接:看你的下游任务。
| 范式 | 代表模型 | 适用下游 | 计算开销 | 预训练数据量需求 |
|---|---|---|---|---|
| 掩码建模 | MolBERT, GROVER | 分类、回归任务 | 中等 | 高(10^5+) |
| 对比学习 | MolCLR, GraphCL | 分子相似性、聚类 | 低~中等 | 中等(10^4+) |
| 生成式预训练 | MolGPT, ChemBERTa-2 | 分子设计、优化 | 高 | 高(10^6+) |
我在 ADMET 项目中最常用的是对比学习 + 掩码建模的混合策略。先用对比学习让模型理解分子之间的相似性关系,再用掩码建模补充局部化学环境的细节信息。迁移到下游的 P-gp 底物预测任务上,AUC 从 0.78 提升到了 0.86。值不值?你自己判断。
说到底,三种范式是互补的。掩码建模擅长微观理解,对比学习擅长宏观关系,生成式预训练擅长结构创新。在真实的药物发现项目中,没人会只依赖一种自监督信号。我现在的标准管线是:用对比学习做粗粒度对齐,用掩码建模做细粒度纠错,用生成式预训练做探索和筛选。三驾马车一起跑,效果最稳。