MIT 6.S191(Introduction to Deep Learning)是节奏紧凑的深度学习入门课,一周左右能过一遍。对 AI 药物发现而言,关键不是学完所有内容,而是知道哪些基础是必需的、哪些可以暂时跳过。
课程内容与药物发现的相关性
| 主题 | 相关性 | 说明 |
|---|---|---|
| 神经网络基础 | 必需 | 前向传播、反向传播、损失函数 |
| 训练技巧 | 必需 | 正则化、dropout、批归一化、学习率 |
| 过拟合与泛化 | 最重要 | 分子任务数据少,这是核心挑战 |
| CNN | 低 | 分子任务用得少(除非做图像/显微数据) |
| RNN / 序列模型 | 中 | SMILES、蛋白序列 |
| Transformer / 注意力 | 高 | 见 161《Transformer 在分子中的应用》 |
| 生成模型(VAE、GAN、扩散) | 高 | 分子生成(见 158《AI 分子生成模型》、162《扩散模型在药物设计中》) |
| 不确定性与鲁棒性 | 高 | 见 166《不确定性估计》 |
| 强化学习 | 中 | REINVENT(见 137《REINVENT 论文精读》) |
| 计算机视觉应用 | 低 | 可跳过 |
对分子任务最关键的部分:过拟合
# 【为什么这在分子任务中格外重要】
#
# 图像/文本任务:
# 数据量:数十万到数十亿
# → 模型容量是瓶颈
#
# 分子任务:
# 数据量:【几百到几千】
# → 【过拟合是主要瓶颈】
#
# 而且分子数据还有一个特殊问题:
# 数据不是独立采样的,是【成系列产生的】
# → 即使做了交叉验证,也可能高估性能(见 051)
#
# 【必须掌握的应对手段】:
#
# 1) 【正确的数据划分】
# 骨架划分、时间划分(见 051、167)
# → 【这比任何正则化技巧都重要】
#
# 2) 正则化
# dropout、权重衰减、早停
#
# 3) 【减小模型】
# 分子任务上,小模型常常更好
# → 与图像/文本的直觉相反
#
# 4) 【集成】
# 多个种子训练后平均
# → 降低方差,还能给出不确定性(见 166)
#
# 5) 数据增强
# SMILES 随机化、构象采样
#
# 6) 【更强的归纳偏置】
# 用图表示、等变架构
# → 减少模型需要学的东西
#
# 【一个反直觉的实践建议】:
# 在分子任务上,先试【最小的模型】
# 逐步增大,直到验证集性能不再提升
# → 而非从大模型开始调小
训练一个分子模型的完整模板
import torch
import torch.nn as nn
import numpy as np
from torch.utils.data import TensorDataset, DataLoader
def train_model(X_train, y_train, X_valid, y_valid,
hidden=256, dropout=0.3, lr=1e-3,
epochs=200, patience=20, seed=0):
torch.manual_seed(seed)
np.random.seed(seed)
model = nn.Sequential(
nn.Linear(X_train.shape[1], hidden),
nn.ReLU(), nn.Dropout(dropout),
nn.Linear(hidden, hidden // 2),
nn.ReLU(), nn.Dropout(dropout),
nn.Linear(hidden // 2, 1),
)
opt = torch.optim.AdamW(model.parameters(), lr=lr, weight_decay=1e-4)
sched = torch.optim.lr_scheduler.ReduceLROnPlateau(
opt, factor=0.5, patience=8)
loss_fn = nn.MSELoss()
train_ds = TensorDataset(torch.tensor(X_train, dtype=torch.float),
torch.tensor(y_train, dtype=torch.float))
loader = DataLoader(train_ds, batch_size=32, shuffle=True)
Xv = torch.tensor(X_valid, dtype=torch.float)
yv = torch.tensor(y_valid, dtype=torch.float)
best_loss, best_state, wait = np.inf, None, 0
for ep in range(epochs):
model.train()
for xb, yb in loader:
opt.zero_grad()
loss = loss_fn(model(xb).squeeze(-1), yb)
loss.backward()
# 【梯度裁剪:小数据上有帮助】
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
opt.step()
model.eval()
with torch.no_grad():
vl = loss_fn(model(Xv).squeeze(-1), yv).item()
sched.step(vl)
# 【早停:小数据上必需】
if vl < best_loss:
best_loss, wait = vl, 0
best_state = {k: v.clone() for k, v in model.state_dict().items()}
else:
wait += 1
if wait >= patience:
break
model.load_state_dict(best_state)
return model, best_loss
# 【集成:分子任务上强烈推荐】
models = [train_model(Xtr, ytr, Xva, yva, seed=s)[0] for s in range(5)]
def predict(models, X):
X = torch.tensor(X, dtype=torch.float)
with torch.no_grad():
P = torch.stack([m(X).squeeze(-1) for m in models])
return P.mean(0).numpy(), P.std(0).numpy() # 【均值 + 不确定性】
学完之后要补的分子专属知识
- 分子表示:SMILES、指纹、图、三维(见 031《SMILES 入门》、035《分子指纹是什么》、034《分子图表示》);
- 图神经网络:通用课程通常不深入(见 006《Stanford CS224W 图神经网络》、159《图神经网络 GNN》);
- 等变网络:处理三维分子必需(见 160《等变神经网络》);
- 评测设计:这是通用深度学习课程最不会教、而分子任务最需要的(见 051《Scaffold Split》、167《模型外推性》);
- 领域约束:成药性、可合成性——模型输出必须经得起化学检验。
给不同背景的建议
| 背景 | 建议 |
|---|---|
| 完全没有 ML 基础 | 先补 scikit-learn 与统计基础,再看深度学习 |
| 有 ML 基础 | 重点看生成模型与 Transformer 部分 |
| 化学/生物背景 | 先掌握传统 ML,深度学习可以缓一缓 |
| 已有深度学习经验 | 直接跳到分子专属内容 |
对化学/生物背景的人,一个重要提醒:在几百到几千样本的常见情形下,认真调优的 ECFP + LightGBM 常常打平甚至超过深度模型(见 131《Chemprop / D-MPNN 论文精读》)。先把传统 ML 与评测设计做扎实,收益比学深度学习更大。
关键要点
- 过拟合是分子任务的核心挑战——数据量比图像/文本少几个数量级;
- 在分子任务上先试最小的模型再逐步增大,与图像/文本的直觉相反;
- CNN 与计算机视觉部分可以跳过;生成模型与 Transformer 部分最相关;
- 通用课程不会教评测设计,而这恰恰是分子任务最需要的。
延伸资源
- 学习路线:003《AI 药物发现学习路线》;CS224W:006《Stanford CS224W 图神经网络》;
- Chemprop:131《Chemprop / D-MPNN 论文精读》;不确定性:166《不确定性估计》;模型外推性:167《模型外推性》。