2. 概率基础与最大似然估计:概率分布、对数似然、MLE损失函数的推导与在分子生成中的应用
好,我们直接进入正题。做分子生成,你绕不开一个核心问题:怎么评价我生成的分子“像不像”真实的分子?
答案就藏在概率里。说白了,我们就是要学一个概率分布,让它能描述真实分子的结构特征。这一章,我带你搞定这个基础——从概率分布到最大似然估计,再落到分子生成的损失函数上。
2.1 概率分布:分子世界的语言
分子生成里,概率分布无处不在。原子的种类是离散的(C、H、O、N...),坐标是连续的(x, y, z),键的类型也是离散的。所以,你得同时处理两类分布。
离散分布:比如原子的类型,我们用分类分布(Categorical Distribution)来描述。这玩意儿就是多项分布的特例,每次选一个类。
连续分布:比如原子的三维坐标,我们用高斯分布(正态分布)来建模。记住,分子结构里的坐标往往是多模态的,一个简单的单峰高斯可能不够,需要用混合高斯。
我个人习惯把分子看成是一个“概率图”。节点是原子,边是化学键,整个分子的概率可以分解成若干条件概率的乘积。这种方式,我们后面讲自回归模型时会反复用到。
2.2 似然函数:凭什么说这个分子“像”真的?
假设你有一堆训练数据,真实分子的结构。你想学一个模型,它参数为θ,能输出一个概率分布 p(x|θ)。
对于给定的一个真实分子 x,p(x|θ) 越大,说明模型认为这个分子出现的可能性越高。这个 p(x|θ) 就是似然函数。
最大似然估计(MLE)的思路很简单:找到一组参数θ,使得所有训练数据的似然乘积最大。
写成公式是:
θ_MLE = argmax_θ ∏_{i=1}^{N} p(x_i | θ)
这里 N 是训练集大小。每一项 p(x_i|θ) 都代表模型对第 i 个分子的“认同度”。
2.3 对数似然:把乘法变加法,治好了我的数值恐惧症
对数函数是单调递增的,所以最大化似然等价于最大化对数似然:
θ_MLE = argmax_θ ∑_{i=1}^{N} log p(x_i | θ)
这个求和稳定多了。但我告诉你,这还不是终点。
在深度学习的框架里,我们习惯做最小化。所以,再取个负号:
L(θ) = - ∑_{i=1}^{N} log p(x_i | θ)
这个 L(θ) 就是我的损失函数了。最小化它,等价于最大化对数似然。
我们拿最常用的高斯分布举个例子。假设 p(x|θ) 是单变量高斯:
p(x|μ, σ²) = (1 / √(2πσ²)) * exp(- (x - μ)² / (2σ²))
取负对数:
-log p(x|μ, σ²) = 0.5 * log(2π) + log(σ) + (x - μ)² / (2σ²)
看到没?常数项不用管,核心就是那个 (x - μ)²。这不就是最小二乘法嘛。我在做第一个分子生成模型时,看到这个推导,恍然大悟——原来我一直在用的 L2 损失,默认假设数据是高斯分布的。
2.4 从 MLE 到分子生成损失函数:一步步落地
好,现在我们把 MLE 的框架装到分子生成上。下面这个表格,把几个常见分子生成场景的损失函数做了一一对应:
| 分子生成任务 | 建模的分布 | 对应的损失函数 | MLE 等价形式 |
|---|---|---|---|
| 预测原子类型 | 分类分布 | 交叉熵损失 | -∑ log p(类别 | θ) |
| 预测 3D 坐标 | 各向同性高斯 | MSE 损失 | (x - μ)² / (2σ²) + C |
| 预测化学键存在性 | 伯努利分布 | 二元交叉熵损失 | -∑ [y log p + (1-y) log(1-p)] |
| 预测键角/二面角 | 冯·米塞斯分布 | 负对数冯·米塞斯 | -κ cos(x - μ) + C |
你会发现,几乎所有的分子生成损失,都能纳入 MLE 的统一框架。为什么?因为我们在做的是密度估计。
现在的生成模型,无论是 VAE、GAN 还是扩散模型,核心目标都是在拟合数据的真实分布 p_data(x)。负对数似然(NLL)就是那个最通用的评价指标。
2.5 一张图总结:从概率分布到损失函数
下面这张图,是我画的知识结构图。它串联了这一章的核心逻辑:
[概率分布] (描述分子)
|
├── 离散型:分类分布、伯努利分布
│ (原子类型、键类型)
└── 连续型:高斯分布、混合高斯、冯·米塞斯分布
(坐标、键角、二面角)
|
v
[最大似然估计 MLE] (学习分布参数)
|
├── 核心思想:让观测数据出现的概率最大
└── 数学形式:最大化 ∏ p(x_i | θ)
|
v
[对数似然变换] (解决数值下溢)
|
├── 乘法 → 加法
└── 形式:最大化 ∑ log p(x_i | θ)
|
v
[损失函数构建] (取负号,适配梯度下降)
|
├── 高斯分布 → MSE 损失
├── 分类分布 → 交叉熵损失
└── 伯努利分布 → 二元交叉熵损失
|
v
[分子生成应用]
|
├── 训练模型拟合真实分子分布
└── 损失函数引导模型学出合理结构
嗯,这张图的逻辑线很清楚了。从概率分布出发,到 MLE,再到具体的损失函数,最后一头扎进分子生成的应用里。
我个人非常喜欢用这张图做教学开场。它把抽象的统计概念,直接映射到了你每天要调的损失函数上。下次你写代码选损失函数时,脑子里过一遍这张图,就知道为什么选它了。
2.6 实践:一个简单的 MLE 损失计算
我们来点实际的。假设你有一个 atom_type 预测任务,输出是 5 类原子的 logits。用 PyTorch 的 CrossEntropyLoss 就是 MLE:
import torch
import torch.nn as nn
# 假设 batch_size=4, num_classes=5
logits = torch.randn(4, 5) # 模型输出的 logits
targets = torch.tensor([1, 3, 0, 2]) # 真实原子类型索引
# 内置的 CrossEntropyLoss = LogSoftmax + NLLLoss
criterion = nn.CrossEntropyLoss()
loss = criterion(logits, targets)
print(loss.item())
# 输出类似: 1.8765
这段代码背后,做的就是我刚才推导的负对数似然。你传入 logits(未归一化的分数),CrossEntropyLoss 内部做了 softmax 变成概率,再取负对数。
内容到这就够了。MLE 是你构建分子生成损失函数的基石,后面所有复杂的损失,比如对比学习损失、KL 散度、ELBO,全都是从 MLE 这个根上长出来的。你把它吃透了,后面就容易了。