DeepDTA(Öztürk 等,Bioinformatics 2018)是深度学习做药物-靶点亲和力预测的开创性工作。它的架构极其简单——正是这个简单性让它成为长期的基线,也让后来的一个发现格外值得注意:很多更复杂的模型并没有真正超越它多少。
架构:两条 CNN
# 药物侧:
# SMILES 字符串 → 字符级 embedding → 1D CNN → 药物向量
#
# 蛋白侧:
# 氨基酸序列 → 字符级 embedding → 1D CNN → 蛋白向量
#
# 融合:
# 拼接 → 三层全连接 → 预测亲和力(回归)
#
# 就这么简单。没有注意力,没有图,没有预训练。
#
# 关键设计:
# 把 SMILES 与蛋白序列都当作「文本」处理
# 用同样的 CNN 架构提取局部模式
#
# 论文的贡献:
# 1) 证明了端到端深度学习在 DTA 上可行
# 2) 【把 DTA 从分类问题变成回归问题】
# 此前多数工作做「结合/不结合」的二分类,
# 而实际需要的是定量的亲和力
# 3) 建立了 Davis 与 KIBA 两个标准数据集的用法
为什么 SMILES 的 CNN 会有效
- SMILES 中相邻的字符往往对应化学上相邻的原子:因此局部卷积能捕捉到片段级的模式(如芳环、酰胺、卤素);
- 但也有明显的问题:
- 环闭合标记会把远距离的原子关联起来——
c1ccccc1中的两个1在字符串上相邻但语义上表示成环; - 同一分子有多种 SMILES 写法,模型对写法敏感(可用 SMILES 增强缓解);
- 分支括号的嵌套结构,CNN 难以正确解析;
- 没有显式的化学约束:模型不知道价键规则。
- 环闭合标记会把远距离的原子关联起来——
- 这些问题正是后续工作转向图表示的动机(见 139《GraphDTA 论文精读》)。
它为什么成为长期基线
# 后续大量工作声称超越 DeepDTA,但:
#
# 1) 【提升幅度普遍不大】
# Davis 数据集上 MSE 从 0.26 降到 0.22 之类
# 考虑到数据集规模与噪声,这个差距的意义存疑
#
# 2) 【很多提升可能来自超参数与训练技巧】
# 而非架构本身(见 131 的讨论)
#
# 3) 【平凡基线的表现被长期忽略】
# 只用「药物均值 + 靶点均值」的矩阵分解式基线
# 在随机划分下就能接近这些深度模型
# → 说明大部分「性能」来自记住了药物/靶点的边际分布
#
# 4) 【cold split 下所有方法都大幅下降】
# 这才是真实的泛化能力
#
# 这个现象不限于 DTA ——
# 它是深度学习应用于小数据科学问题时的普遍情况:
# 简单基线 + 好的评测设置,
# 常常比复杂模型 + 宽松评测更有信息量
# 【阅读 DTA 论文的检查清单】:
# □ 划分方式是什么?random / cold drug / cold protein
# □ 有没有平凡基线对照?
# □ 报告了多少个种子的结果?标准差多大?
# □ 提升是否超过种子间的方差?
# □ 有没有在独立数据上验证?
# □ 有没有实验验证的案例?
Davis 与 KIBA 数据集
| Davis | KIBA | |
|---|---|---|
| 药物数 | 68 | 2111 |
| 靶点数 | 442(全是激酶) | 229 |
| 测量 | Kd | KIBA 分数(整合 Ki/Kd/IC50) |
| 矩阵密度 | 完整(全部测过) | 稀疏 |
| 主要问题 | 药物太少;只有激酶 | KIBA 分数的物理含义模糊 |
Davis 只有 68 个药物——这意味着随机划分下,测试集中的每个药物几乎必然在训练集中出现过(配不同的靶点)。在这样的数据上比较模型的「泛化能力」,本身就站不住脚。
实现(作为对照基线)
import torch
import torch.nn as nn
class DeepDTA(nn.Module):
def __init__(self, n_smi_chars=64, n_seq_chars=25,
embed_dim=128, n_filters=32, dropout=0.1):
super().__init__()
self.embed_smi = nn.Embedding(n_smi_chars + 1, embed_dim)
self.cnn_smi = nn.Sequential(
nn.Conv1d(embed_dim, n_filters, 4), nn.ReLU(),
nn.Conv1d(n_filters, n_filters * 2, 6), nn.ReLU(),
nn.Conv1d(n_filters * 2, n_filters * 3, 8), nn.ReLU(),
nn.AdaptiveMaxPool1d(1),
)
self.embed_seq = nn.Embedding(n_seq_chars + 1, embed_dim)
self.cnn_seq = nn.Sequential(
nn.Conv1d(embed_dim, n_filters, 4), nn.ReLU(),
nn.Conv1d(n_filters, n_filters * 2, 8), nn.ReLU(),
nn.Conv1d(n_filters * 2, n_filters * 3, 12), nn.ReLU(),
nn.AdaptiveMaxPool1d(1),
)
self.head = nn.Sequential(
nn.Linear(n_filters * 6, 1024), nn.ReLU(), nn.Dropout(dropout),
nn.Linear(1024, 1024), nn.ReLU(), nn.Dropout(dropout),
nn.Linear(1024, 512), nn.ReLU(),
nn.Linear(512, 1),
)
def forward(self, smi_idx, seq_idx):
d = self.cnn_smi(self.embed_smi(smi_idx).permute(0, 2, 1)).squeeze(-1)
p = self.cnn_seq(self.embed_seq(seq_idx).permute(0, 2, 1)).squeeze(-1)
return self.head(torch.cat([d, p], dim=1))
# 用 TDC 加载数据并做正确的划分(见 133)
from tdc.multi_pred import DTI
data = DTI(name="DAVIS")
data.convert_to_log(form="binding")
split = data.get_split(method="cold_split", column_name="Drug", seed=42)
# 【用 cold_split 而非 random】
这条路线现在的位置
- 序列-序列的 DTA 模型已不是前沿,但仍有用武之地:超大规模的快速粗筛(毫秒级,可处理千万级药物-靶点对);
- 改进方向:
- 蛋白侧用语言模型表示(ESM-2,见 143《ESM-2 论文精读》)替代字符 CNN;
- 药物侧用图或预训练模型(见 139《GraphDTA 论文精读》、142《Uni-Mol 论文精读》);
- 引入结构信息(见 121《Boltz-2 技术报告精读》)——这是最有潜力的方向;
- 用知识图谱补充关系信息(见 157《AI DTI 预测模型》)。
- 但评测问题不解决,架构改进的意义都会被打折——这是这条线最需要的进步。
关键要点
- 架构极简(两条 CNN),正是这个简单性让它成为难以撼动的基线;
- 它把 DTA 从二分类变成回归——这个转变比架构本身更重要;
- Davis 只有 68 个药物,随机划分下比较「泛化能力」站不住脚;
- 后续工作的提升幅度普遍不大,且平凡基线的对照长期缺失。
延伸资源
- GraphDTA:139《GraphDTA 论文精读》;MolTrans:141《MolTrans 论文精读》;DTI 模型:157《AI DTI 预测模型》;
- TDC:133《TDC 论文精读》;Benchmark 陷阱:169《Benchmark 陷阱》;ESM-2:143《ESM-2 论文精读》。