基于motif的分子生成工具 - DrugGPS 测评

DrugGPS是 一种基于亚口袋和分子motif的分子生成方法,是中科大计算机学院刘淇教授 ICLR 2023的文章 《Learning Subpocket Prototypes for Generalizable Structure-based Drug Design》。

一、模型介绍

DrugGPS( a structure-based Drug design method that is Generalizable with Protein Subpocket prototypes)是针对口袋条件下的,基于分子motif的3D分子生成网络。其模型结构如下图:

DrugGPS是基于他们之前开发的FLAG方法,与FLAG类似,分子生成过程是一个 motif-by-motif的过程,仍然是包含了局部motif选择,下一个motif预测,motif的连接位置预测,motif链接之后的扭转角预测。

不一样的是,在嵌入motif的时候,在encoder中,使用了原子层面和残基层面的3D graph transformer(如上图b),以捕捉分层的结构信息。然后构建了一个全局相互作用图,去模拟子口袋和配体之间的相互作用。该全局的相互作用图有两种节点:子口袋类型节点和motif库中分子motif节点。如果在数据集中,同一类的子口袋与某个motif之间存在相互作用,那么在他们之间添加一条边,如果出现的频率越高,则边的权重越大。关于相互作用的判断,作者使用的BINANA工具,仅计算口袋类型和motif之间的氢键相互作用。关于全局相互作用图的边的权重更新方法,如下图,详看作者文章3.4 Global Interaction Graph Construction部分。

因此,可以认为DrugGPS是FLAG的改良模型,在算法上改良了口袋和分子motif之间的相互联系,在数据上,新增了H键相互作用。

DrugGPS可以识别motif和子口袋类型之间的相互作用,故能生成结合力更强的分子。全局的相互作用图是之前FLAG方法没有的。

二、文章结果介绍

作者对比了DrugGPS和FLAG, Pocket2Mol等模型的对比结果,如下图:

可以看到DrugGPS生成分子的vina score,要明显优于FLAG等模型。此外,DrugGPS生成的分子,在成药性,可合成性上也优于之前的模型,效果比较明显。

作者还研究了子口袋类型数量与motif数量对生成分子vina score之间的关系,如下图。

还有,就是一些消融实验。

可能是因为预印本的原因,代码可能仍在修改,实验的结果并不多。

三、模型测评

作者在文章中提供了GitHub 链接:GitHub - zaixizhang/DrugGPS_ICML23: Implementation of ICML23 paper "Learning Subpocket Prototypes for Generalizable Structure-based Drug Design"

首先,复制项目到本地

git clone https://github.com/zaixizhang/DrugGPS_ICML23.git

安装conda环境

conda env create -f druggps_env.yaml
conda activate druggps_env
pip install kmeans-pytorch

由于当前作者并未提供已经训练好的checkpoint和处理好的数据集,因此,需要数据预处理开始。

1. 下载数据集

作者使用的是crossdocked_pocket10.tar.gz数据集。下载链接为:

https://drive.google.com/drive/folders/1CzwxmTpjbrt83z_wBzcQncq84OVDPurM

里面的两个文件都要下载。下载完成后,放置在./data文件夹内,然后解压crossdocked_pocket10.tar.gz文件。

tar -xzvf crossdocked_pocket10.tar.gz

然后切换到 ./utils目录,执行如下命令,为模型提取H键相互作用的原子:

cd utils
unzip binana.zip 
python preprocess_data.py

注:unzip binana.zip 解压binana模块,否则会报错:ModuleNotFoundError: No module named 'binana'。

此外,在执行上述命令过程中,发现应该会生成一个atoms_hbond.npy文件,用于记录每个口袋-分子对中H键原子。

但是,由于作者提供的数据集中,没有pdbqt文件,而作者使用的提取H键相互作用的程序是binana是需要pdbqt文件作为输入的,导致无法提取H键相互作用原子。

因此,直接运行上述命令,生成的atoms_hbond.npy实际上是空值,不影响后面的训练,相当于没有相互作用。

我单独为crossdocked_pocket10中的分子和蛋白生成pdbqt文件,然后再进行预处理。

成功生成了含有H键的数据集。为了与代码中的路径配合,需要将atoms_hbond.npy需要移动到./目录下。

2. 训练模型

由于作者没有提供训练好的模型checkpoint,我们只能自己训练。

按照作者在github上的介绍,在./目录下执行如下命令:

python train.py

执行时,可能会遇上如下问题,包括:

(1)FileNotFoundError: [Errno 2] No such file or directory: './atoms_hbond.npy',请调整./atoms_hbond.npy文件放置在./目录下。

(2)ModuleNotFoundError: No module named 'chemutils'。这个可能是执行路径的原因,改一下代码就好,在train.py文件中,添加

import sys
sys.path.append("..")
sys.path.append("./utils") # wufeil

(3)FileNotFoundError: [Errno 2] No such file or directory: './data/crossdocked_pocket10_name2id.pt',删除./data文件夹中的crossdocked_pocket10_processed.lmdb;从新执行上述训练代码就可以生成了。

这是因为加载数据集时,如果存在crossdocked_pocket10_processed.lmdb文件,就认为已经存在处理过的数据集,就不再重新处理,所以直接加载。直接加载需要每个蛋白的index文件,即crossdocked_pocket10_name2id.pt,但是作者没有提供。

因此,删除crossdocked_pocket10_processed.lmdb文件重新运行即可。

但是后续运行中,加载数据集报错,所有的口袋-分子都无法加载到模型中。其实,这里这么处理是不对的,因为作者使用了H-bond相互作用,分子的序号是不一样的。

!!!关于这一部分,我查看了原始代码,并进行了修改,修改内容复杂,就不描述了。具体原因是在处理分子的时候,parse_sdf_file函数中 moltree = MolTree(mol)少了一个参数。

总的来说,改代码改的很累很累,小错误太多,很有可能是我们的版本问题。

因此代码中的小修改太多了,这里就不一一列举了。

在更改代码以后,重新运行

python train.py

会自动按照配置文件,开始处理数据集,生成crossdocked_pocket10_processed.lmdb和crossdocked_pocket10_name2id.pt。运行输出如下:

在长时间的数据处理之后(大约是6个小时),开始执行训练,但是报错

 File "/home/DrugGPS/models/protein_features.py", line 47, in _rbf
    RBF = torch.exp(-((D_expand - D_mu) / D_sigma)**2)
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!

此时,仍然需要代码。修改过程较为复杂,这里就不描述了。在修正代码后,开始训练,输出每个批次的训练损失:

每迭代10000次保存一次模型checkpoint。

如果训练过程中遇到,如下错误:

File "train.py", line 188, in proto_init
    _, centers = kmeans(X=torch.cat(emb_list, dim=0), num_clusters=config.train.num_prototypes, iter_limit=100)
TypeError: kmeans() got an unexpected keyword argument 'iter_limit'

是因为kmeans_pytorch版本的原因,需要重新安装一下。安装指定版本,命令如下:

sudo pip3 install -e git+https://github.com/subhadarship/kmeans_pytorch.git#egg=kmeans_pytorch

训练开始后,会在log文件夹内生成一个对应时间的文件夹,例如:train_model_2024_01_24__16_45_04,其中的文件目录如下:

.
├── checkpoints
├── events.out.tfevents.1706089504.a01.1834344.0
├── log.txt
├── models
└── train_model.yml

2 directories, 3 files

其中,models文件夹为对应的模型代码,log.txt为训练过程输出,train_model.yml为训练过程中的超参数配置,checkpoints为训练过程中的pt格式的checkpoint,即模型权重。我最终一共训练了600000次迭代,3090显卡花费了5天时间,获得了一个600000.pt的checkpoint。

3. 生成分子

首先将我们训练获得的600000.pt从/logs/train_model_2024_01_24__04_45_04/checkpoints目录拷贝出来,放置在./目录下。

然后,修改分子采样配置文件,修改为(其实在训练模型时,也作了修改。。。):

dataset:
  name: pl
  path: ./data/crossdocked_pocket10
  split: ./data/seq_split.pt

model:
  hidden_channels: 256
  subpocket_motif: True
  num_prototypes: 64
  checkpoint: ./600000.pt
  encoder:
    name: hierGT
    hidden_channels: 256
    edge_channels: 64
    key_channels: 128
    num_heads: 4
    num_interactions: 6
    cutoff: 10.0
    knn: 32
    num_filters: 128

sample:
  seed: 2023
  num_samples: 100
  beam_size: 10
  logp_thres: -.inf
  num_retry: 5
  max_steps: 12
  batch_size: 10
  num_workers: 4

按照作者早github上的描述,我们再./目录下执行如下命令:

python sample.py

默认是使用CPU。运行输出为:

在生成结束以后,输出所有生成分子的SA,QED, LogP,  Lipinski的平均值。,如下:

QED 0.493651 | LogP 0.448651 | SA 0.589300 | Lipinski 4.890000 

这一结果显示,生成的分子类药性还可以的。

根据运行的时间,会在outputs文件夹内生成一个以时间命名的文件夹,例如:sample-0_2024_01_29__21_34_31,文件夹内包含了生成100个分子的sdf文件,和分子的smiles文件SMILES.txt,还包括口袋信息文件pocket_info.txt,以及相应的生成分子的配置文件sample.yml,所有的文件目录如下:

.
├── 0.sdf
├── 10.sdf
├── 11.sdf
├── 12.sdf
...
├── 98.sdf
├── 99.sdf
├── 9.sdf
├── log.txt
├── pocket_info.txt
├── sample.yml
└── SMILES.txt

0 directories, 104 files

我们使用如下命令,将所有的生成分子的sdf文件合并成all.sdf, 在sample-0_2024_01_29__21_34_31目录下执行。

for i in `ls *.sdf | sort -t'_' -k 4,4 -n `; \
  do cat $i >> all.sdf; done

按照作者在代码中的设定,对测试集的第一个样本(即,crossdocked_pocket10数据集中的BSD_ASPTE_1_130_0文件夹下的2z3h_A_rec_1wn6_bst_lig_tt_docked_3_pocket10.pdb,即2z3h.pdb)进行分子生成,生成100个分子。2z3h口袋结构及其原来的配体结构如下图:

配体结构:

DrugGPS生成分子的2D结构如下(部分):

生成的3D分子与口袋的位置如下视频:

DrugGPS_Case_2z3h

其实这个体系,在之前的FLAG的文章中也有介绍过,DrugGPS的结果,分子更小一些,没有FLAG的大。但是与FLAG生成的分子类似的,仍有大量的并环结构存在。可惜,在测试FLAG模型时,生成的分子并没有进行对接,因此无法在这个体系上指导,是FLAG生成的分子还是DrugGPS生成的分子bind ding更好。注意,在生成的分子速度上,100个分子,DrugGPS确实非常快,大约只花了5分钟,要比FLAG快很多。

对于原来的晶体参考分子而言,DrugGPS生成的分子偏小,可能是DrugGPS仅仅针对半封闭口袋部分进行分子生成,但是对于暴露在溶剂区的位置,并未生成片段。

从生成分子与口袋的3D位置来看,生成的分子大部分都能不与口袋发生“碰撞”但是,发生碰撞的情况也非常明显。

另外,作者使用rdkit保存3D分子为sdf格式,有时会因为原子的连接顺序问题,导致出现错乱情况,如下图:

比较重要的一点是,DrugGPS生成分子含有大量的极性基团位于支链或者侧链位置,例如-OH等。这一点是非常奇怪的,这些分子显然是不类药的,但是QED score不能识别的。原因可能是:

(1)一个分子的生长迭代次数太多了,当找不到口袋内的生长点时,模型会不断尝试一些支链和侧链位置,那么就会生成一些侧链基团,这一点可以通过限制生长步数,以及生长点限制来实现。

(2)另外一种原因是,数据集中其实包含了大量的非类药的分子,特别是一些内源性分子,含有大量的OH, PO4结构,这都导致模型倾向生成极性的侧链基团。

(3)分子片段的切割方法,也是一种解决思路,特别是减少小片段。

为了查看参考分子和对接分子的打分,进行了对接。

参考分子的对接打分为-8.735,对接pose与晶体中的类似,如下图:

生成分子中,前三好的打分分别为:-7.78, -6.22, -6.14,对应的对接pose分别如下图:

考虑到生成分子仅仅占据口袋区域,且生成分子较小,为此,计算了LE。参考分子的LE 为-0.281,上述三个分子的LE为-0.458, -0.212, -0.249。从LE的角度上看,DrugGPS确实生成了一些结合力更强的分子。

当然,模型真实的情况,需要作者提供训练好的checkpoint才能知道。

我们自己训练的模型,不知道是否迭代次数是否充足。我也没有进行超参数优化,包括epoch的选择都是直接选最后一个epoch。

就连数据集中,生成pdbqt文件然后使用BINANA计算H键,不知道是否有问题。

毕竟代码里面小错误很多,改的有点乱了。这也是没有提供这个模型修改方法的原因。

四、总结

DrugGPS是基于FLAG 改进而来,提出了一种基于亚口袋原型和motif的分子生成方法,使用原子层面和残基层面的3D graph transformer,捕捉分层的结构信息,以识别motif和子口袋类型之间的相互作用,故能生成结合力更强的分子。

经过修改作者提供的代码,成功训练迭代了600000次,然后,按照作者提供的采样代码,针对测试集中的第一个体系2z3h,进行分子生成测试。2z3h体系上一共生成了100个3D分子。生成3D分子很好落在口袋范围内,但是部分生成分子存在于口袋发生碰撞的情况,同时生成的分子较小,未占据到溶剂区。此外,生成分子中,存在大量的极性侧链基团,导致类药性差。

重对接的都docking和LE结果表明,DrugGPS生成分子与口袋之间具有较强的结合力。

DrugGPS是一次比较好的概念研究,距离实际应用还有太多需要工业界的开发。在应用模式上,需要进行改进,改为制定生长位点的指定迭代次数生长。

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值