1、LSTM与化合物生成概述:分子生成与深度学习的关系

各位朋友,咱们今天进入这门课的第一个话题——分子生成到底跟深度学习有什么关系?我个人习惯先把问题说清楚,再讲技术怎么干。说白了,新药研发的起点就是找到有活性的分子,而传统方式靠化学家画结构,试错成本高得吓人。我十年前刚开始接触这个方向时,就觉得这事儿必须用算法来加速。

分子生成的核心目标很简单:给定一些约束(比如靶点、活性、毒性),让模型自动产生大量新颖且合理的分子结构。那为什么要用深度学习?你想想看,化学空间的理论大小是10^60量级,穷举不现实。深度学习能学到化学规则的隐性分布,直接从这个分布里采样,效率高很多。

分子生成问题:为什么要用深度学习?

传统的分子生成方法主要有两种。一种是基于片段的拼接,像搭积木一样。另一种是基于规则的穷举。但它们的共同问题是——

  • 搜索空间有限:只能组合已知的分子片段
  • 缺乏全局约束:很难同时满足多个目标
  • 生成速度慢:每生成一个都得化学家手动检查

深度学习带来的是端到端的生成范式。我做一个简单的对比表格,你看就明白了:

方法 原理 缺点 深度学习优势
碎片拼接 预定义碎片库 + 连接规则 碎片数量限制,难出新颖骨架 隐式学习碎片模式,自动拓展
遗传算法 进化搜索,交叉变异 收敛慢,容易早熟 分布平滑,采样可控
变分自编码器(VAE) 编码 → 隐空间 → 解码 离散分子表示难连续化 序列模型天然处理离散符
LSTM 循环结构,按字符预测 长依赖易遗忘,但比传统RNN好很多 显式建模SMILES序列顺序

这里面最关键的一点:分子结构可以被表示成字符串。最常见的就是SMILES表示法,比如水分子H2O可以写成O,苯是c1ccccc1。SMILES本质上就是一个字符序列,恰好是LSTM最擅长的活儿。你想想看,自然语言处理里LSTM能写诗、能翻译,那用在SMILES序列上,道理完全一样——只要模型学会下一个字符该是什么,就能构造出完整分子。

LSTM凭什么胜任分子序列生成?

LSTM长短期记忆网络的最大特点是引入了门控机制。它解决了普通RNN的梯度消失问题,能记住几百步之前的上下文信息。举个具体的例子:

SMILES CCO 表示乙醇。模型在生成最后一个O时,需要知道前面有两个碳原子且已经饱和,不能加多余氢。LSTM的遗忘门可以控制前面的C和C对当前O的影响权重,输出门又把记忆压缩成合理概率。这种机制让生成出来的分子99%以上都是化学上有效的。

我曾经在早期项目里试过直接用普通RNN,结果生成的SMILES有一半连语法都不对,比如括号不对称、环编号混乱。当时我意识到,必须用LSTM。后来换上去,有效率直接跳到87%。嗯,这里要说明:剩下的13%可能是连写法规,比如出现c1cc2c3c1这种自相交环,但至少语法对了。

我个人觉得LSTM在化学信息学里能站稳脚跟,还有一个原因——它容易训练。你不需要特别大的模型,几百万个分子就能训出不错的生成器。代码实现也简单,基本上就是一个嵌入层、一个或两个LSTM层、一个分类头:

import torch
import torch.nn as nn

class LSTMMoleculeGenerator(nn.Module):
    def __init__(self, vocab_size, embed_dim=128, hidden_dim=256, num_layers=2):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embed_dim)
        self.lstm = nn.LSTM(embed_dim, hidden_dim, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_dim, vocab_size)

    def forward(self, x, hidden=None):
        x = self.embedding(x)
        out, hidden = self.lstm(x, hidden)
        logits = self.fc(out)
        return logits, hidden

这个模型训练时,输入一串SMILES字符,预测下一个字符。推理时从起始标记开始,逐字符采样直到终止标记。完整流程我画了个图,你一看就明白:

LSTM生成分子流程图 LSTM生成分子核心流程 分子库(SMILES) 预处理(Token化) LSTM训练 逐字符采样 新分子(SMILES) 有效性评估 虚线箭头表示:评估不合格的分子反馈回训练集或调整采样温度 循环迭代直到生成出满足化学约束的有效分子

从图上你可以看到,整个流程是闭环的。评估这一步非常关键,我做过一个项目,生成出来的分子有93%在化学上有效,但评估一通后真正能进下一轮的只有不到30%。为什么?因为除了语法有效,还得满足分子量、logP、可合成性等约束。LSTM只负责语法正确,其他任务需要后处理。

小提示:初期训练LSTM时,建议先用ChEMBL或ZINC数据库的100万条SMILES。我试过用MDL SDF解析直接丢进去,结果很多含盐、含碎片的分子导致模型学到奇怪的片段。清洗步骤不能省——去盐、去重复、保留合理原子数。

我在项目中遇到的坑与经验

讲三个我自己踩过的坑吧,你以后做项目时能少走弯路。

  1. SMILES表示不唯一——同一个分子可以写成多个SMILES,比如丙酮可以是CC(=O)C也可以是C(C)C=O(不规范)。模型会学到这种冗余表示,导致生成时稳定性差。我的对策:训练前用RDKit把所有SMILES规范化成同一个Canoical SMILES。
  2. 长序列遗忘——虽然LSTM比RNN强,但当分子长度超过80个字符时,依然会出现环编号错乱。我曾经遇到一个38元大环内酯,模型从来没生成成功过。后来我把LSTM层数从1增加到2,再把hidden_size从128提到256,才勉强解决。
  3. 采样温度对有效性影响巨大——温度太高(>1.5)生成的全是乱码,温度太低(<0.3)全是高频片段重复。我踩过的教训是:把温度设置在0.8~1.0之间,同时加上Top-k采样(k=5~10),效果稳定很多。

注意:不要以为LSTM生成出的分子一定可合成。即使化学语法正确、符合分子量范围,可能合成路线极其曲折甚至不可能实现。我合作过的药化同事经常抱怨“你生成的分子很美,但我买不到原料也做不出来”。所以后续必须有可合成性打分器(如SCScore)做二次过滤。

最后再说说LSTM在化学信息学里的其他应用。除了分子生成,它还常用于反应预测、分子性质回归(比如logP预测)、以及逆合成分析。但咱们这门课只专注在生成环节。你想想看,生成只是第一步,后续还要对接ADMET预测、对接打分、优化,但学会了生成就等于拿到了「开天辟地」的钥匙。

嗯,关于LSTM与化合物生成的关系,今天就先聊到这儿。下节课我们会深入具体的数据集准备和SMILES分词实操。