组合药物筛选最麻烦的地方,不是单个药有没有效,而是药和药组合之后的效果很难猜。ScreenShot 这个名字听起来像“截图”,但它解决的是组合药物筛选中“组合爆炸”的问题。从标题看,这个模型走的是 Foundation Model 加 Few-Shot 的路线:先用基础模型学习药物、细胞、组合效应背后的通用规律,再用少量已知实验数据,去预测大量还没做过的药物组合。如果你在制药研发、生物信息学或者 AI for Science 方向,想了解少样本组合药物筛选能怎么做、怎么评估、有哪些坑,这篇文章应该能帮上忙。下面我不会照着论文标题复读,而是按真实落地顺序拆一遍。
1. 组合药物筛选为什么需要少样本基础模型
1.1 组合爆炸与实验成本
组合药物筛选的难点,首先是搜索空间太大。假设你手里有 100 种候选药,两药组合有 100 × 99 / 2 = 4950 组;如果做三药联合,数量直接到 161700 组。真实场景里,化合物库往往是几万、几十万个分子,完整组合空间几乎不可能靠湿实验全部覆盖。
更麻烦的是,药物组合实验不是“测一个浓度”就结束。A 药取 5 个浓度,B 药取 5 个浓度,两两配对就是 25 个剂量组合。一个组合要覆盖多个浓度比例,才能判断协同效果。再加上不同细胞系、不同疾病背景、不同处理时间,实验次数会迅速膨胀。
所以组合药物筛选天然需要先算后测。模型负责从大量候选组合里筛选出一批高潜力的组合,实验人员只对这部分做湿实验验证。这样可以把实验成本集中在最有希望的方向上。
1.2 传统机器学习与基础模型的思路差异
过去做组合药物预测,主流方案是提取药物分子指纹、细胞系基因表达、靶点信息等特征,然后用随机森林、XGBoost、图神经网络等模型学习一个分类器或回归器。这个路线很成熟,但问题在于它更偏向“单任务”学习:换一个新细胞系、换一批候选药,往往要重新准备标签数据,重新训练。
少样本场景下,这种传统方案很容易失灵。因为它没有利用历史实验积累出来的药物知识,每来一个新任务都要从零开始。如果新任务里只有几十组已知结果的药物组合,模型很难学到可靠的规律。
ScreenShot 标题里的 Foundation Model 和 Few-Shot,指向的是另一条路线。基础模型在大规模数据上预训练,先学会药物结构、分子性质、细胞反应等通用知识。到了具体的组合筛选任务,只需要少量已知组合做微调,甚至不微调就可能给出一版排序。这种“先学通用知识,再快速适配小样本任务”的模式,在图像和文本领域已经被验证过,现在用在组合药物筛选上,解决的问题就是少标签条件下的候选组合优先排序。
2. 理解 ScreenShot 的模型定位与输入输出
2.1 从“少样本”看模型要解决的任务类型
少样本药物组合筛选,要区分几种实际场景。
场景一:新细胞系。某个新的肿瘤细胞系,历史数据很少,只有十来个药物组合做过实验。ScreenShot 这类模型要利用其他细胞系上学习到的规律,在这个新细胞系上快速给出预测。
场景二:新药物库。一批新设计的化合物,还没有太多组合实验数据。模型需要根据分子结构相似性、已知靶点和通路信息,推断这批新组合的协同可能性。
场景三:新疾病背景。换一个适应症,比如从肿瘤转到抗纤维化,标签数据同样稀缺。这时少样本模型要做得事情不是记住训练集,而是利用预训练阶段积累的药物和生物知识,快速迁移到新任务。
无论哪种场景,少样本模型的核心评价标准都不是拟合训练集,而是举一反三:给一组没见过的组合,能不能把真正高潜力的排在前面。
2.2 输入特征和输出标签的常见形式
组合药物筛选模型的输入,通常不是单一模态,而是多路信息拼接。
药物结构信息是最常见的输入,包括 SMILES 字符串、Morgan 指纹、MACCS 指纹、分子图等。结构信息刻画的是“这个药本身长什么样”。
药物属性信息也很关键,比如靶点、代谢通路、药物类别、分子量、脂溶性等。结构相似的药也可能作用在不同靶点上,所以属性信息能补足结构特征的盲区。
生物学背景信息同样不能少,最典型的是细胞系基因表达谱、突变信息、拷贝数变异、组织类型。同一组药物在不同细胞系上效果可能完全不同,模型要有办法把细胞背景编码进去。
输出标签一般有三种形式:
- 二分类:协同 or 不协同。
- 回归:协同分数,比如 Bliss 分数、Loewe 分数,或者组合后的效应值。
- 排序:模型输出一个连续分数,用于候选组合优先级排序。
具体到 ScreenShot,它到底用哪些特征、输出哪种标签,要以论文和官方仓库为准。但从基础模型这个定位看,它有较大概率是把药物结构、生物背景和组合方式一起编码,最终输出一个可以排序的打分。
2.3 基础模型的预训练与微调关系
基础模型通常分成两个阶段。
预训练阶段,模型在大规模数据上学习通用表征。如果预训练数据是海量药物分子结构,模型就能学到化学结构里的基本规律,比如哪些官能团常见、哪些结构片段容易出现活性。这个阶段不需要太多标签,可以用自监督方式完成。
微调阶段,模型在下游任务上做少量调整。组合药物筛选属于少样本场景,微调时要注意两点:一是学习率不能太大,否则预训练学到的知识容易被破坏;二是不要整个模型都放开微调,可以只训练最后的预测头,或者冻结大部分底层参数。数据越少,越要保守。
很多人拿到基础模型后习惯性全量微调,结果小样本数据不够,模型在训练集上拟合得很好,测试集上却一塌糊涂。这属于少样本使用中最常见的路线错误。
3. 复现与使用前的准备清单
3.1 硬件、软件和数据条件
如果要复现 ScreenShot 或者使用类似的基础模型,第一步是确认自己的环境能不能跑起来。
显存是第一个要关注的点。中等体量的模型,推理时显存起步大约需要 8GB 到 16GB;如果模型很大,或者需要编码大量特征,24GB 甚至更高才稳。显存不够时,可以把 batch size 调小,或者只加载模型的一部分,比如只跑特征编码,不一次加载所有组件。
内存方面,处理药物分子指纹和细胞系表达谱时,数据会展开成很大的矩阵。如果一次性把所有特征载入内存,32GB 内存是一个比较稳的起点,低于 16GB 时建议使用数据流式加载。
磁盘空间也容易忽略。预训练权重文件可能达到几 GB,甚至十几 GB;数据预处理后生成的缓存文件也可能占几十 GB。开工前先看磁盘余量,避免训练到一半磁盘写满。
软件环境没有固定答案,PyTorch 和 TensorFlow 都可能出现,具体看官方仓库。关键是把 Python 版本、CUDA 版本和深度学习框架版本对齐,否则经常出现“代码没错但跑不起来”的问题。
3.2 数据划分与少样本任务构建
少样本实验最怕的是数据划分不合理。
第一种划分方式是按组合随机划分。把所有药物对随机分成训练集和测试集。这种方式操作简单,但风险是同一个药物可能在训练集和测试集里都出现,模型可能记住药物本身,而不是学习组合规律,测试指标会虚高。
第二种划分方式是按药物划分。训练集里出现的药物,测试集里完全不再出现。这个设定更接近真实场景,因为你希望模型能预测新药物的组合效果。难度也更高,通常指标会比随机划分低不少。
第三种划分方式是按细胞系划分。训练集里出现的细胞系,测试集里没有。这个设定用于评估模型能不能跨细胞系泛化,是药物筛选里非常关键的一种评估方式。
选择哪种划分,取决于业务目标。如果只想知道某个已有细胞系里哪些组合值得做实验,随机划分可以接受。如果目标是筛选新药物、新细胞系,就必须用更严格的划分,否则上线后效果会明显变差。
3.3 验证环境与最小样例
拿到代码后,不要直接启动完整训练。先用最小样例把链路跑通。
取 5 到 10 条样本,确认数据加载没问题。看特征维度是否和模型输入层对齐。再看模型前向传播能不能跑,能不能算出 loss。最后跑一次预测,确认输出格式能正常保存。
调通最小样例之后,再把 batch size 调大、数据量逐步增加。这一步的核心是隔离问题:如果数据加载、模型结构、输出保存都有问题,在 5 条样本上暴露出来,比跑到一半再发现容易处理得多。我一般会先把日志打开,确认每一步的输入输出形状,路径和权限都要留意。
4. 一套通用的少样本药物组合筛选实验流程
4.1 从单任务到元任务的实验设计
少样本实验有两种常见组织方式,决定整个实验流程怎么搭。
第一种是单任务小样本训练。假设你只有当前这一个数据集,把它切成 support set 和 query set。support set 用来微调模型,query set 用来评估。这种方式适合还没有多少历史实验数据、只有一个目标任务的阶段。
第二种是多任务或元学习式设计。把多个历史实验数据分别看成不同任务,先让模型在大量历史任务上学习,再把它放到一个新任务上快速适配。这种方式的优势是:当新任务只有几个样本时,模型已经知道“药物组合预测这件事应该怎么适应新数据”,而不是临时学一套新规则。
ScreenShot 如果定位是 Foundation Model,大概率走的是第二种路线。它会在很多药物筛选数据上做预训练,之后面对新组合时只需要少量样本就能输出排序。我们自己设计实验时,也要提前确认是单任务评估还是跨任务评估,因为两者的模型选择、参数设置、指标解读都不一样。
4.2 微调、评估和结果解释
如果模型支持微调,基本流程可以按下面这套走:
- 加载预训练权重。
- 构造少样本训练集,一般支持集每个类别只取几个样本。
- 设置较小的学习率,控制微调轮数。
- 在验证集上选择最优模型。
- 在测试集上报告最终指标。
评估指标方面,分类任务看 AUROC、AUPR、F1、Precision@k;回归任务看 RMSE、MAE,或者预测分数和实际协同分数的相关系数。
少样本场景下,AUPR 往往比 AUROC 更值得关注,因为正负样本可能严重不平衡。正样本很少时,准确率没有参考意义,AUPR 能更好地反映模型在少数正例上的识别能力。
还要注意,少样本训练的结果波动很大。同一个模型,换一个随机种子,测试指标可能差几个点甚至十几个点。正确做法是固定多个随机种子各跑几次,报告均值和标准差。只跑一次就说效果很好,容易误判。
结果解释上,不要把模型的输出分数当成绝对实验值。它更多是排序依据。实际筛选流程里,研究者只关心预测分数最高的前 50 或前 100 个组合,这时候 Top-K 命中率比全局 AUROC 更有用。比如你验证了前 100 个组合里有 30 个确实协同,这就是一个可操作的业务指标。
4.3 批量预测与输出管理
模型真正用于筛选时,往往要一次性预测几千几万个组合。批量阶段要提前设计好输出格式,否则下游实验没法跟进。
建议每个输出行都包含唯一标识:药物 A ID、药物 B ID、细胞系、浓度条件、预测分数。不要只用药物名称拼接,因为药物名可能有别名、大小写不一致等问题,数据库主键更可靠。
批处理时要注意显存和内存限制。不要一次性把所有组合都塞进去,建议固定 batch size 按批读取、按批预测、按批落盘。同时保留进度日志,方便任务中断后定位到哪里。
如果任务特别大,还要考虑断点续跑。已经在输出文件里记下来的预测结果不要重复算,可以直接跳过。这个在少样本模型使用中很容易被忽略,但实际投入生产筛选时非常关键。
5. 评估指标与参数调整的核心思路
5.1 协同、加性与拮抗怎么度量
组合药物效果不是只有“有效”和“无效”两种。通常需要区分协同、加性和拮抗。
协同指组合后的效果明显超过两个单药效果的简单叠加。拮抗则相反,组合后效果低于单药预期。加性就是两个药各自效果相加,没有额外增强也没有相互抵消。
量化这些概念,常用的是 Bliss、Loewe、HSA 等参考模型。Bliss 假设两个药物独立作用,用概率方式计算预期效应;Loewe 基于剂量相加的假设,强调两个药物是否作用于同一通路;HSA 的逻辑更直观,组合效果只要超过效果最好的单药就算有协同。
不同参考模型给出的协同分数可能不一致。训练模型之前,要先把标签来源统一。如果你从多个数据库收集数据,一个库用 Bliss,另一个库用 Loewe,直接混在一起训练,相当于标签定义都不同,模型学起来会很混乱。
5.2 少样本评估的稳定性
少样本实验里,数据集小,评估结果波动大。稳定评估可以从这几个方面入手:
第一,固定数据划分,不要每次重新随机切。否则不同实验之间没有可比性。
第二,多跑几个随机种子。建议至少 5 个种子,计算指标均值和标准差。如果标准差过大,说明模型在这个少样本设置下还不够稳定。
第三,选择对类别不平衡更敏感的指标。正样本比例很低时,AUPR 更合适,Precision@k 则更贴近实际筛选需求。
第四,对比基线时要保持相同条件。如果想证明 ScreenShot 比传统随机森林好,基线也要用相同的数据划分、相同的特征预处理、相同的随机种子。否则对比出来的差异分不清是模型优势还是评估口径差异。
5.3 哪些参数值得调,哪些不应该乱调
值得调整的参数,首先是学习率。基础模型微调时学习率不宜过大,常见范围在 1e-5 到 1e-4 量级。学习率太大,预训练知识容易被冲掉;太小,模型在小样本上可能学不进去。
batch size 也要调。它影响训练稳定性和显存占用。显存不够就调小,配合梯度累积。微调轮数要设置早停,小样本下训练时间稍长就会过拟合。
特征工程也值得检查。不是所有特征都有用,加入过多无关特征反而增加过拟合风险。可以先跑一版只用药物结构特征的模型,再加细胞系背景,对比效果上升还是下降。
不应该乱调的,一是不要为了训练集 loss 降到接近 0 而无限增加训练轮数,少样本下过拟合比欠拟合更常见。二是不要随意做数据增强,药物分子的 SMILES 字符串改写可能改变分子语义,不是所有增强都安全。三是不要反复用同一个验证集调参,调多了验证集本身也会间接泄漏信息。
6. 实测中最容易踩的坑与排查顺序
6.1 数据泄露和样本重叠
少样本药物筛选里,最隐蔽的问题是数据泄露。
一个典型的例子是同一个药物对出现在多个细胞系中。如果按药物对随机划分,训练集见过这对药,测试集又出现同一对药在不同细胞系里的效果,模型很可能学会了“这对药历史表现如何”,而不是“这对药在这种细胞下如何”。测试指标虚高,实际应用却不灵。
另一种情况是浓度切分。同一个药物对,高浓度组合在训练集,低浓度组合在测试集。看似是两个样本,实际上共享同一个药物组合的信息,也会造成泄漏。
排查方法很简单:训练集和测试集之间检查三件事——有没有重叠的药物对、有没有重叠的药物分子、有没有重叠的细胞系。如果业务目标是推荐全新组合,建议按药物分子完全隔离的方式做一次验证,看看指标下降多少。指标明显下降,说明模型更多依赖记忆,泛化能力有限。
6.2 输入特征不一致和缺失值
特征不一致是报错和效果差的常见来源。
药物 ID 格式不一致最常出现。同一个药,有的数据源写 PubChem CID,有的写 ChEMBL ID,有的直接写商品名。不统一,特征对齐就出问题。SMILES 也需要标准化,同一分子可能有多种写法,最好用 RDKit 做 canonical SMILES 归一化。
细胞系表达谱的数据来源也要注意。不同数据库可能用不同的基因名版本,有的是 ENSEMBL ID,有的是 Gene Symbol,直接拼接会产生大量 NaN。平台差异也很大,不同芯片或测序平台出来的表达量分布不同,需要先做标准化。
缺失值处理要谨慎。把缺失表达量填成 0,可能让模型把“未测量”误认为“表达量为 0”,产生错误信号。一般建议先看缺失比例,缺失比例高就删掉该特征,缺失比例低再用中位数或均值填充,或者用模型能够处理缺失值的方案。
如果训练时 loss 不收敛,或者预测结果全是同一个值,先检查特征分布,看看是不是存在大量 NaN 或者某一列特征全为 0。很多时候问题出在数据,而不是网络结构。
6.3 资源占用和任务卡顿排查
模型跑得慢或者卡住,不要直接怀疑模型结构。按下面顺序排查。
先看现象:是完全没有输出,还是中途卡住,还是报错退出。再看日志:卡在数据加载、模型前向、loss 计算,还是保存输出。然后看资源:显存有没有吃满,内存有没有暴涨,磁盘 IO 是不是瓶颈。很多卡顿是 dataloader 太慢,模型在等数据,表现出来就是 GPU 利用率为 0,但程序一直没跑完。
显存溢出时,优先把 batch size 调小。如果还需要更大 batch,用梯度累积。内存溢出时,改用流式加载,不要一次性把全部数据读进内存。输出文件写不进去时,检查目录路径和写权限,这经常表现为“程序正常结束但没有任何输出文件”。
依赖版本问题也常见。某些深度学习算子只在特定版本下可用,升级框架后可能报错,换到旧版本又可以用。复现过程中尽量锁定环境版本,避免不必要的兼容问题。
6.4 同类型任务的替代方案
如果 ScreenShot 的官方代码还没公开,或者你的数据格式和特征要求对不上,可以先跑替代方案,建立起对照基线。
最简单的替代方案是传统机器学习。用 Morgan 指纹加细胞系表达谱作为特征,训练随机森林或者 XGBoost 做协同分类。这个方法不算先进,但非常适合摸清数据底子:数据划分合理的情况下,传统模型能到什么水平,后续换更复杂模型才知道提升空间有多大。
图神经网络也是一个可选的替代方案。把药物作为节点,药物-靶点关系或已知组合关系作为边,做图的节点或边预测。它在利用结构信息上有优势,但实现复杂度会高一些。
另外一些开源药物组合预测模型也值得参考。这类模型很多以药物对和细胞系为输入,直接输出协同分数。先跑通一个开源模型,再用自己的数据微调,可以作为基础模型方案之外的第二选择。
替代方案真正的价值不是替代 ScreenShot,而是提供可比较的基线。基础模型如果连随机森林都打不过,那说明它在这个数据上并没有发挥出优势;如果明显超过传统方法,再深入排查它擅长哪类样本、在哪种划分下提升最大,这样使用起来才更有针对性。
最后说一点个人看法。如果只是复现论文结果,按官方仓库跑一遍即可。但如果想真正把 ScreenShot 这类少样本基础模型用在自己的药物筛选流程里,我的建议是先把三件事定下来:数据划分方式、协同分数定义、Top-K 评估口径。这三件事不统一,后续所有调参和对比都说不清楚。踩过几次坑之后你会发现,很多模型效果不理想,不是模型本身不行,而是数据和评估没有对齐。基础模型的优势是通用表征和少样本适应能力,但它不是魔法。给足质量可控的标签、做干净的样本划分、保持稳定的评估协议,才有可能让模型真正帮你筛出值得做实验的药物组合。