☰
等变注意力机制在3D分子表示中的原理与应用
2026/10/19 7:33:07 网站建设 项目流程

做3D分子表示这几年,我几乎每次都会被问到同一个问题:等变注意力机制到底是什么?这个问题值得认真回答,因为很多实现看起来只是给Transformer加了个三维坐标,结果分子一转,效果就崩了。这篇是3D等变几何深度学习与分子表示系列的第1.1.3节,我打算把等变注意力从动机、数学框架、分子落地、训练调参到应用场景,一次讲清楚。内容既适合刚接触几何深度学习的读者,也适合正在把自己的模型改成等变版本、却反复被bug折磨的朋友。理解这个东西的关键只有两条:注意力权重必须旋转不变,几何信息必须按等变规律更新。

1. 等变注意力机制背后的核心问题:为什么3D分子表示里必须谈等变

1.1 从分子的旋转开始:等变性到底要求什么

物理世界没有绝对方向。同样一个分子,你在实验室A和实验室B测量能量,唯一差别可能就是坐标系的摆放方向不同,但真实性质不该因此改变。神经网络如果把原子坐标当普通数字处理,输入稍微旋转一下,输出就可能完全变样。

用数学语言说,对于旋转平移变换 (g \in SE(3)),输入坐标变成 (g \cdot x),理想情况下输出也要以确定的方式跟着变。如果网络输出的是标量,比如分子能量,那就要求:

[ f(g \cdot x) = f(x) ]

这叫不变性。如果输出的是力、偶极矩这类向量,则要求:

[ f(g \cdot x) = g \cdot f(x) ]

也就是输出向量也要跟着旋转,这叫等变性。很多刚入门的朋友容易把这两个词混着用,实际项目中先搞清楚目标是哪种很重要:预测能级、自由能、活性值,基本只需要SE(3)不变性;预测坐标、原子受力、相互作用方向,则需要SE(3)等变性。内部层可以使用等变特征,最后再接一个不变读出层。

这一条是整个设计的地基。后面的注意力权重、位置编码、坐标更新,全部是为了让这种对称性在模型结构里强制成立,而不是指望数据量大了之后网络自己“硬学”出来。

1.2 把三维坐标直接塞进注意力:一次注定失败的尝试

我看到过不少早期实现,选择把原子坐标和原子类型拼在一起,先进MLP得到节点表示,再做标准自注意力。比如:

[ h_i = \text{MLP}([x_i, z_i]) ]

坐标 (x_i) 是三维向量,(z_i) 是原子类型编码。分子旋转后,坐标变成 (R x_i),MLP的输入完全变了。虽然MLP理论上可以拟合任何函数,但你没法期望它对所有旋转都自动不变,尤其是训练数据里没有覆盖所有方向的时候,模型只会对见过的方向有效。

有人会反驳:我不用绝对坐标,用相对坐标差 (x_i - x_j) 不就好了?相对坐标差至少不随平移变化,可它依然会随旋转变化。两个原子之间的距离是不变量,方向却会转。如果把坐标差直接拼进特征,MLP依然要处理无数个方向。更麻烦的是,聚合阶段如果只是把向量特征简单线性组合,组合结果并不会按旋转规律变化。

我见过一个极端的例子:同一个分子在某个角度下预测的电荷分布很好,旋转45度后结果完全不可用,明显不是物理问题,而是模型把坐标系当成了真实结构的一部分。等变架构要解决的就是这个系统性失效。

1.3 等变注意力的定位:不是新的注意力变体,而是一组约束

等变注意力不是一个独立于QKV之外的新注意力类型,它更接近一类满足SE(3)对称性的设计约束。你可以保留Attention里的softmax结构,也可以保留多头思想,但打分项和输出项必须重新设计。

通常可以把等变注意力拆成两半。第一半,决定注意力大小的权重,只能依赖旋转不变量,比如原子间距离、方向向量之间的夹角、原子类型、局部电荷等。第二半,要传递的空间方向或向量特征,必须按几何变换律更新,也就是节点输出里的向量通道要跟随旋转。

所以你会发现,一个合格的等变注意力层,最后往往长成这样:注意力权重是标量且旋转不变,节点标量特征更新成不变特征,节点向量特征更新成等变特征。后面所有章节都在围绕这两句话做文章。

2. 从QKV到旋转不变的几何量:等变注意力到底改了什么

2.1 普通自注意力的QKV为什么会在3D场景失效

普通Transformer的注意力打分通常写成:

[ \text{logits}_{ij} = \frac{(W_Q h_i) \cdot (W_K h_j)}{\sqrt{d}} ]

如果 (h_i) 只包含标量特征,这个打分本身是旋转不变的,因为标量不会转。问题在于,当节点特征包含3D方向信息时,情况就变了。假设 (h_i) 里有一个向量子特征 (v_i),旋转后变成 (R v_i)。经过线性层 (W_Q) 之后得到 (W_Q R v_i)。我们希望这个值等于 (R W_Q v_i),但普通矩阵 (W_Q) 几乎不可能和所有旋转矩阵交换。换句话说,旋转之后再投影,和投影之后再旋转,结果不一样。

即使你完全不用向量特征,只拿标量做QKV,注意力机制也只能回答“哪些特征相似”,无法回答“原子间相对方向是什么”。3D几何里大量重要信息恰恰藏在方向里,比如键角、二面角、氢键方向、作用力朝向。所以等变注意力不是简单地把QKV换成别的结构,而是把打分依据一部分转移到显式的旋转不变量上。

2.2 特征类型:标量、向量与高阶张量

在设计等变注意力之前,先分清楚手里的特征属于哪一类。三维旋转下,特征变换行为可以分成几个层次:

特征类型常见维度旋转下的行为分子表示里的例子
标量1完全不变原子类型、电荷、距离、RBF编码
向量3随旋转矩阵旋转坐标差、单位方向、偶极方向
高阶张量/球谐系数5、7或更高按SO(3)不可约表示混合角动量投影、高阶方向描述

分子表示最常用的是“标量通道+向量通道”搭配。标量通道负责承载元素、电荷这类细节信息,向量通道负责传递方向。更高阶的张量特征表达能力更强,但实现复杂度明显增加,通常需要球谐投影和张量积操作,不是简单配置一个MLP就能搞定。等变注意力计算权重时,只用标量特征和不变量;更新节点时,可以同时更新标量通道和向量通道。

2.3 打分函数:只用旋转不变量决定权重

等变注意力的打分函数,核心原则是:让logits只依赖旋转不变量。比较常见的几项包括:

第一,节点标量特征之间的相似度。把标量特征用MLP映射成query和key,然后做点积。因为输入都是标量,输出也是标量,旋转不变性天然成立。

第二,距离偏置。用径向基函数(RBF)把原子间距离 (d_{ij}) 展开成一组基函数,再经过线性层变成标量偏置,加到logits上。距离是旋转不变量,所以这一步安全。

第三,角度偏置。比如方向向量内积 (\hat{r}{ij} \cdot \hat{r}{ik}),旋转后两个方向向量同时旋转,内积保持不变。这种量可以携带三原子夹角信息,对分子键角敏感的任务很有帮助。

需要特别注意,不要直接把方向向量作为key或value来计算相似度。除非你已经把它投影到一组旋转不变的基函数上,否则方向向量会转,直接点积的结果并不总是保持不变。一个可行方案是,把方向向量作为向量通道输入,但用于打分时必须先构造旋转不变的标量组合。

2.4 输出聚合:如何让向量特征跟着旋转

注意力权重 ( \alpha_{ij} ) 计算出来之后,节点特征更新分两条线走。标量通道可以这样更新:

[ h_i^{s} = h_i^{s} + \sum_j \alpha_{ij} \cdot W_{s}([h_i^{s}, h_j^{s}, \phi(d_{ij})]) ]

其中 (\phi(d_{ij})) 是距离编码,整体是标量,旋转不变。

向量通道的更新要小心得多。一种常见的正确写法是:

[ h_i^{v} = h_i^{v} + \sum_j \alpha_{ij} \left[ g_{ij}^{\text{dir}} \cdot \hat{r}{ij} + g{ij}^{\text{vec}} \cdot h_j^{v} \right] ]

这里 (\hat{r}{ij}) 是从原子 (j) 指向原子 (i) 的单位方向向量,旋转后会跟着转。(g{ij}^{\text{dir}}) 和 (g_{ij}^{\text{vec}}) 是由MLP产生的门控标量,输入是距离、标量特征等旋转不变量,所以它们自身也不变。一个旋转不变的系数乘以一个会旋转的向量,结果还是合理等变的。因此加权求和之后,输出向量通道能正确跟随旋转。

这里有个高频踩坑点:不要对向量特征使用普通线性层做任意变换。比如写成 (W_v h_j^{v}),其中 (W_v) 是一个普通矩阵,就不满足与旋转矩阵交换的条件。除非那层只是逐通道的标量相乘,或者你使用张量积做更复杂的高阶变换,否则向量通道的等变性会被破坏。

3. 分子表示落地:特征初始化、几何嵌入与掩码设计

3.1 输入准备:原子特征、坐标与边表

真正写分子数据的等变注意力时,第一步是准备三样东西:节点标量特征、原子坐标、边表。

节点标量特征一般包括原子类型embedding、部分电荷、是否是芳香环原子、可能带的自旋极化信息等。这些特征在旋转下不会改变。原子坐标则单独存放,不直接拼进MLP输入。边表可以来自化学键,也可以通过距离截断构造。对于长程相互作用,很多人会在一个半径阈值内连接所有原子对,比如4到6埃,以保证非成键作用也能进入注意力范围。

方向向量的计算比较直接:用相邻原子的坐标差归一化。用公式表示:

[ \hat{r}_{ij} = \frac{x_i - x_j}{|x_i - x_j|}

]

这个量是单位向量,旋转下会等变。距离则单独用 (d_{ij} = |x_i - x_j|) 保存,作为标量不变量。

3.2 几何嵌入:距离RBF与方向向量

距离不能直接当标量用。原因很简单,物理相互作用随距离衰减是有平滑变化的,直接把距离数字喂给网络,模型往往学不出合适的锐利度。更常用的做法是使用一组高斯基函数:

[ \phi_k(d) = \exp\left(-\beta_k \left(d - \mu_k\right)^2\right) ]

(\mu_k) 是中心位置,通常在0到10埃之间均匀分布,(\beta_k) 控制带宽。这样距离就被展开成一个固定长度的向量,可以安全地作为MLP输入或logits偏置。

方向向量的处理方式有两种。一种简单粗暴:直接把单位方向向量放进向量通道,让网络通过门控机制决定每个维度用多少。另一种更细致:把方向向量之间做内积,形成类似角度的不变量,再拼进标量通道。后者的好处是打分函数能得到更丰富的角度信息,而且不会破坏旋转不变性。

有个细节容易忽略:不要用序列建模里的sinusoidal位置编码套到3D坐标上。那是给一维序列长度设计的,旋转一下坐标,编码结果完全不是你想要的不变量关系。3D分子表示里的位置信息,应该使用距离RBF和方向向量这类几何量来表达。

3.3 注意力掩码:连接性、距离阈值与连续化

在分子图里,注意力掩码几乎是必须的。如果所有原子对都允许参与注意力,计算量会随原子数平方增加,而且很多相距很远的原子对物理意义不大。

常见的几种设计:

  • 根据化学键掩码:只允许成键原子、或者一到三键范围的原子参与注意力。这样计算快,但会丢掉一些非键接触的远程作用。
  • 根据距离阈值掩码:在一个半径范围内连接所有原子对,常用于蛋白口袋或力场截断场景。
  • 连续掩码:把距离作为负偏置加入logits,让远距离权重自然变小。这样既保留了长程信息的可能性,又避免硬截断带来的梯度突变。

我在实际项目中通常使用距离阈值加连续衰减的组合:先设一个硬性边界防止计算爆炸,再在边界内部根据距离给一个可学习的衰减偏置。这样既能照顾到局部作用,又能让模型自己决定长程信息的权重尺度。

3.4 一段概念实现:等变注意力前后对比

下面给一段概念性代码,重点展示等变注意力层的结构,省略了多头、维度变换和优化细节。代码不一定直接能跑,但思路是完整的。

import torch import torch.nn.functional as F def equivariant_attention(h_s, h_v, x, mask, rbf_emb, Wq, Wk, gate_net, eps=1e-6): # h_s: [N, F_s] 标量节点特征 # h_v: [N, C, 3] 向量节点特征,初始可为0 # x: [N, 3] 原子坐标 # mask: [N, N] 0/1掩码 N = x.shape[0] # 1. 距离与方向 d = torch.cdist(x, x, p=2) # [N, N] direction = x[:, None, :] - x[None, :, :] # [N, N, 3] direction = direction / (d[..., None] + eps) # 单位方向向量,随旋转等变 # 2. 距离RBF rbf = rbf_emb(d) # [N, N, K] rbf_bias = rbf_to_bias(rbf).squeeze(-1) # [N, N] # 3. 标量注意力打分 q = Wq(h_s) # [N, d] k = Wk(h_s) # [N, d] logits = q @ k.transpose(0, 1) / (q.shape[-1] ** 0.5) logits = logits + rbf_bias logits = logits.masked_fill(mask == 0, -1e9) alpha = F.softmax(logits, dim=-1) # [N, N] # 4. 标量通道更新 h_s_new = h_s + alpha @ (Wout(h_s) + Wr(rbf)) # 5. 向量通道更新 gate = gate_net(h_s_new, rbf) # [N, N, 1],旋转不变 h_v_new = h_v + (alpha[..., None] * gate * direction).sum(dim=1) return h_s_new, h_v_new

这段代码的关键点就在最后一行:direction是单位方向向量,alpha是旋转不变的注意力权重,gate也是MLP在旋转不变量上生成的标量。三者相乘后,每个被加项都随旋转旋转,最后求和自然满足等变约束。如果这里的direction换成普通坐标差,或者把h_v用普通线性层处理一下,结果就会在旋转下出错。

4. 训练与调参中的关键细节:稳定性、温度和常见bug排查

4.1 向量特征的初始化与等变归一化

等变注意力模型里,向量通道的初始化往往比标量通道更敏感。如果你的向量特征初始化为随机值,前向传播初期方向信息会被随机噪声污染,模型很难快速学到合理的方向组合。最常见的做法是把向量通道初始化为零,让方向信息主要由坐标差和门控网络逐步建立起来。

归一化也是个坑。标准LayerNorm是在特征维度上做减均值、除标准差,如果直接对[N, C, 3]里的向量维度做归一化,方向就会被破坏。正确做法是使用“等变层归一化”:先计算每个特征向量的L2范数,得到一个标量,再对这个标量做归一化,最后用归一化后的标量去缩放对应的向量。因为缩放系数是旋转不变的,向量方向不会被改变,整体依然保持等变。

4.2 残差连接与坐标更新:单位问题

构象生成或坐标预测类的任务里,模型经常要更新坐标。常见更新方式写成:

[ x_i \leftarrow x_i + \sum_j \alpha_{ij} \cdot \hat{r}{ij} \cdot \phi(d{ij}) ]

其中 (\phi(d_{ij})) 是一个标量门控。这类更新保持等变,因为每个更新项都指向一个会随旋转旋转的方向,乘以旋转不变的系数后求和,更新量也会随旋转旋转。

但这里有一个很实际的问题:坐标通常以埃为单位,范数可能是几埃,而网络特征一般在一个很小的尺度附近。如果直接把坐标差作为特征加到向量通道里,数值scale会被拉爆。我在调试中经常遇到这种问题:loss一开始正常,几十步后直接变NaN。最后发现是坐标更新权重设得太大,每一步都把原子推出合理范围。

建议在坐标更新前先对坐标差做归一化,或者给更新权重设一个非常小的初始值,比如0.05甚至0.01,让模型慢慢学习更新幅度。数值稳定性比看起来更影响收敛质量。

4.3 注意力温度与几何偏置的尺度

距离RBF偏置加入logits后,注意力会倾向于集中在近距离原子。这是好事,但如果偏置scale设置太大,注意力会变得非常尖锐,几乎只看最近邻,模型就退化成局部消息传递了。这会让远距离相互作用完全消失,很多需要长程连接的分子任务会变差。

可以给logits加一个温度参数:

[ \text{logits}{ij} \leftarrow \frac{\text{logits}{ij}}{\tau} ]

(\tau) 初始值可以设为1,然后在验证集上调,经验上0.5到2之间比较常见。也可以把RBF偏置乘一个可学习的缩放因子,让网络自己学会应该多依赖几何偏置。我做过一组实验,固定偏置scale=1时模型在短程数据集上表现不错,换成长程相互作用更重要的数据集后注意力过于局部,把偏置缩放到0.3之后,效果明显提升。

4.4 一份排错清单:从旋转测试到训练loss

训练等变模型时,最容易踩的问题往往是等变性被不经意破坏。下面是一份我经常拿来对照的排错清单:

现象可能原因处理方式
同一分子不同旋转输出差异大某些线性层对向量特征做了普通变换检查所有向量处理路径,改用门控或张量积
训练初期loss崩溃向量通道噪声太大、坐标更新权重过大向量初始化置零,更新权重调小
注意力权重过于集中距离偏置scale太大或温度太低调小偏置scale,调高温度
小分子指标还行,大分子差长程依赖没有被有效建模扩大距离阈值或把硬mask换成连续衰减
标量输出没问题,向量输出错读出层或池化把向量特征重新打散了检查最后的向量读出和坐标更新链路

我特别建议在训练脚本里写一个旋转一致性检查:取同一批分子,随机旋转多个角度,看标量输出是否一致,向量输出对齐后是否一致。这段代码花不了多少时间,却能立刻暴露出等变实现里的结构性bug。很多时候模型指标看着还行,实际旋转一致性一测就碎,这种模型放到真实应用里非常危险。

5. 三种实际任务中的设计取舍:性质预测、构象生成与结合场景

5.1 分子性质预测:内部等变,输出不变

分子性质预测是最常见的任务,比如预测能级、自由能、溶解度、毒性等。这类任务的最后输出是标量,所以网络整体要求SE(3)不变性,但内部层依然可以使用等变注意力和向量通道。

为什么内部要保留向量通道?因为方向信息对能量有真实影响。以简单例子来说,三个原子之间键角不同,空间张力和电子相互作用也不同。如果只用距离和标量特征,虽然能近似用距离表示一部分三体关系,但方向通道能把键角、二面角这些信息更高效地传递出来。等变注意力更新向量通道时,本质上是在让模型“感知”局部结构的朝向和构型,最终再把这些信息汇入标量读出层。

读出层建议把所有节点标量特征聚合,再经过几个MLP映射成标量预测。向量通道通常不直接进最终预测,但它们影响中间表示的质量。

5.2 构象生成:坐标更新与手性问题

构象生成任务输出的是3D坐标,所以网络需要SE(3)等变性。等变注意力非常适合这类任务:注意力决定哪些原子之间相互作用,方向向量决定原子应该往哪里移动,门控标量决定移动幅度。你可以把等变注意力层反复堆叠,最后输出坐标的更新量,再迭代生成构象。

这类任务有一个绕不开的问题:手性。SE(3)等变不处理反射对称,只有旋转和平移对称。一个分子和它的镜像分子,在纯SE(3)等变模型眼里看起来是一样的。如果你要做左旋、右旋构象的区分,或者某类手性中心的构型判定,单靠距离、方向向量这些旋转不变量无法区分镜像关系。需要额外输入手性符号,或者使用带反射信息的伪标量特征,比如二面角混合积。

实操上,我会把整个分子的手性中心标记和局部二面角符号作为附加标量特征输入,让模型在等变约束之外再获得反射不对称信息。这样既保住了旋转等变,又能处理手性。

5.3 蛋白-配体结合:大图怎么用等变注意力

最后看更复杂的场景:蛋白-配体结合。把口袋残基和配体原子放到同一张图里做等变注意力,整体计算量会很大。常见做法是限定参与范围,以配体原子为中心,距离5到6埃以内的蛋白原子参与注意力,其余蛋白原子通过一个额外的池化向量做全局补充。

等变注意力在这个场景里的优势在于方向感。蛋白-配体结合很多作用力是有方向性的,例如氢键供体和受体之间的方向、芳香环堆积的相对角度。普通分子图模型把原子当成无方向节点,等变注意力却可以通过方向向量和距离偏置自然地建模接触面上的几何关系。

另外,这类任务通常空间金字塔比较深,适当加入多个尺度的注意力掩码会更好。我常用的组合是:一个短距离掩码处理局部相互作用,一个长距离连续衰减掩码处理远程静电和疏水作用,两个掩码共享同一套等变注意力参数,但分别控制logits偏置。


如果现在让我只留一条经验,我会说:等变注意力不是万能药,但它非常符合分子世界的对称性规律。实现时反复检查两件事,注意力权重是不是旋转不变,几何信息是不是按等变规则更新。只要这两点守住,模型在3D分子任务上的稳定性和泛化能力通常都会比普通图神经网络好一个台阶。我在自己的模拟项目里就吃过没有检查线性层处理向量特征的亏,后来把每个实验都配上随机的SE(3)增强和一致性测试代码,训练和部署都省心很多。刚开始接触这类模型的朋友,可以先从标量加向量的最小等变注意力开始,跑通旋转一致性检查,再去折腾高阶球谐或张量积。希望这篇能帮后来的同学少走一些我走过的弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询