347

用 REINVENT4 生成新分子:从规则到奖励函数

REINVENT4 通过配置文件定义生成模式与奖励函数。这篇给出完整配置、四种生成模式的选择,以及打分函数设计的关键原则。

REINVENT4(见 221《REINVENT4》)是最成熟的开源分子生成平台。它的核心不是生成算法,而是打分函数(奖励函数)的工程化——生成模型只会优化你写下的分数,打分函数设计不当,模型会精确地钻空子

安装

git clone https://github.com/MolecularAI/REINVENT4.git
cd REINVENT4
pip install -r requirements-linux-64.lock
pip install --no-deps .

reinvent --help
reinvent config.toml

四种生成模式:先选对模式

模式 输入 用途 实际使用频率
Reinvent 从头生成全新分子
LibInvent 骨架 + 连接点 R 基团枚举,做类似物库
LinkInvent 两个片段 设计连接子(片段生长、PROTAC linker)
Mol2Mol 起始分子 相似性约束下的分子优化

先导优化阶段优先用 LibInvent 和 Mol2Mol。从头生成看着惊艳,但产出往往难合成、偏离已知 SAR。实际项目通常不需要天马行空的新骨架,而是在已有系列上做受控改造。

完整配置示例

run_type = "staged_learning"
device = "cuda:0"
tb_logdir = "tb_logs"

[parameters]
prior_file = "priors/reinvent.prior"
agent_file = "priors/reinvent.prior"
summary_csv_prefix = "stage1"
batch_size = 128
use_checkpoint = false

[learning_strategy]
type = "dap"
sigma = 128
rate = 0.0001

[[stage]]
chkpt_file = "stage1.chkpt"
termination = "simple"
max_score = 0.7
min_steps = 50
max_steps = 300

[stage.scoring]
type = "geometric_mean"        # 关键:几何平均而非算术平均

# ---- 组件 1:类药性 ----
[[stage.scoring.component]]
[stage.scoring.component.QED]
[[stage.scoring.component.QED.endpoint]]
name = "QED"
weight = 0.6

# ---- 组件 2:合成可及性(必备护栏)----
[[stage.scoring.component]]
[stage.scoring.component.SAScore]
[[stage.scoring.component.SAScore.endpoint]]
name = "SA"
weight = 1.0
transform.type = "reverse_sigmoid"
transform.high = 6.0
transform.low = 2.0
transform.k = 0.4

# ---- 组件 3:结构警报(必备护栏)----
[[stage.scoring.component]]
[stage.scoring.component.custom_alerts]
[[stage.scoring.component.custom_alerts.endpoint]]
name = "Alerts"
params.smarts = [
  "[*;r8]", "[*;r9]", "[*;r10]",          # 大环
  "[#7;!n][S;!$(S(=O)=O)]",               # 不稳定 N-S
  "[#16][#16]",                            # 二硫键
  "[#7;!n][#7;!n]",                        # 肼类
  "C(=[O,S])[O,S]",                        # 硫酯/酸酐
  "[#6](=O)[#6](=O)",                      # 二酮
]

# ---- 组件 4:分子量(用平滑变换而非硬阈值)----
[[stage.scoring.component]]
[stage.scoring.component.MolecularWeight]
[[stage.scoring.component.MolecularWeight.endpoint]]
name = "MW"
weight = 0.6
transform.type = "double_sigmoid"
transform.high = 500.0
transform.low = 250.0
transform.coef_div = 500.0
transform.coef_si = 20.0
transform.coef_se = 20.0

打分函数设计的五条原则

  • 1. 必加护栏:SA score、结构警报、PAINS 过滤是必备的。只优化活性预测分,模型会产出高分但完全没法合成的怪物。
  • 2. 用几何平均type = "geometric_mean" 下任一项接近 0 则整体接近 0,防止「牺牲一个性质换其它高分」。算术平均会允许模型用高分项掩盖致命缺陷。
  • 3. 用平滑变换代替硬阈值:直接卡 MW < 500 会造成优化悬崖(499 和 501 天差地别),用 double_sigmoid 让梯度平滑,模型更容易学。
  • 4. 分阶段(staged learning):先优化基本性质,再逐步加入更严格的目标。一次性上全部约束往往学不动。
  • 5. QSAR 组件要配不确定性约束:接入自己训练的活性模型时,生成分子很可能落在训练分布之外,此时预测值不可信。模型会专门找模型的漏洞——必须配合相似性下限或不确定性惩罚。

分阶段配置

# 阶段 1:先学会生成合理的类药分子
[[stage]]
chkpt_file = "stage1.chkpt"
max_score = 0.6
max_steps = 200
# 只用 QED + SA + Alerts

# 阶段 2:加入性质约束
[[stage]]
chkpt_file = "stage2.chkpt"
max_score = 0.7
max_steps = 300
# 加入 MW、logP、TPSA

# 阶段 3:加入活性预测
[[stage]]
chkpt_file = "stage3.chkpt"
max_score = 0.8
max_steps = 500
# 加入 QSAR 模型 + 相似性约束

监控与诊断

import pandas as pd

df = pd.read_csv("stage1_1.csv")
print(df.columns.tolist())

# 1) 分数是否在提升
print(df.groupby(df.index // 100)["Score"].mean())

# 2) 检查模式坍塌 —— 最重要的诊断
print(f"唯一分子比例: {df['SMILES'].nunique() / len(df):.2%}")
# 低于 50% 说明模型开始重复生成同一批分子

# 3) 检查各组件分数
for col in df.columns:
    if col.startswith("raw_"):
        print(f"{col}: 均值 {df[col].mean():.3f}")
# 某个组件始终很低 → 该目标可能与其它目标冲突
# 某个组件突然变得很高 → 检查是不是被钻了空子

# 4) 内部多样性
from rdkit import Chem, DataStructs
from rdkit.Chem import rdFingerprintGenerator
import numpy as np

gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048)
fps = [gen.GetFingerprint(Chem.MolFromSmiles(s))
       for s in df["SMILES"].head(1000) if Chem.MolFromSmiles(s)]
sims = []
for i in range(len(fps)):
    sims.extend(DataStructs.BulkTanimotoSimilarity(fps[i], fps[i+1:]))
print(f"内部平均相似度: {np.mean(sims):.3f}")
# > 0.6 说明多样性不足

结果评估

  • 分布整体的移动,而非最高分单点;
  • 用 GuacaMol / MOSES 指标做基本体检(见 222《GuacaMol》223《MOSES》);
  • 务必人工过一遍:用 mols2grid(见 217《Mols2grid》)渲染 top 分子,让药化同事看。这一步几乎总能发现自动指标漏掉的问题。
  • 最终判据是可合成、可验证——挑出的分子要能真正做出来并测活性。

常见坑与提示

  • 先导优化优先用 LibInvent / Mol2Mol,从头生成产出往往难合成;
  • 打分函数决定一切:必加 SA score 与结构警报做护栏;
  • 用几何平均 + 平滑 transform,避免模型钻空子;
  • 监控唯一分子比例与内部多样性,警惕模式坍塌。

延伸资源