Transformer架构回顾:自注意力机制、多头注意力、位置编码、编码器-解码器结构

讲ADMET分子表示学习之前,咱必须先搞定Transformer。这东西是地基。我这些年做药物发现项目,碰到过不少团队把分子扔进Transformer就跑,结果效果稀烂——说白了,就是没搞懂这四个核心组件在干什么。这一章咱们就把它们拆开,一个一个嚼碎。

2.1 自注意力机制:模型如何理解上下文?

自注意力(Self-Attention)是Transformer的魂。它的核心思想很简单:对于序列里的每个元素,让它跟所有其他元素算一遍“相关性”,然后根据这个相关性加权聚合信息。

我第一次看这篇论文时,觉得这玩意儿跟化学里的分子间作用力很像。你想,一个原子的性质不是自己决定的,而是被周围配位环境影响的。自注意力就是在干这件事——每个token都能“看到”整个序列。

数学上,它分三步走:

  1. 把每个输入token映射成三个向量:查询Q、键K、值V。
  2. 用Q和K的点积算注意力分数,然后过softmax归一化。
  3. 用归一化后的权重去加权求和V,得到输出。
组件符号维度我理解它的方式
查询(Query)QN × dₖ好比是“我想找什么”
键(Key)KN × dₖ好比是“我有什么特征”
值(Value)VN × dᵥ好比是“我能贡献什么”

公式长这样:

Attention(Q, K, V) = softmax(QKᵀ / √dₖ) V

那个除以√dₖ的操作,我刚开始觉得可有可无。直到有一次我在做分子性质预测时,注意力分数全炸了——因为dₖ大了之后点积的方差也跟着大,softmax就变成one-hot了,梯度直接消失。嗯,从那以后我再也不敢省略这个缩放因子。

2.2 自注意力机制的深度解析

咱们用个具体的例子。假设输入序列有3个分子SMILES:C、O、N。它们的embedding维度是4。自注意力过程就是:

  • 每个token的嵌入向量分别乘以三个权重矩阵Wq、Wk、Wv,生成Q、K、V。
  • Q的第一行跟K的所有行做点积,得到注意力分数[0.5, 1.2, -0.3]。
  • 缩放后变成[0.25, 0.6, -0.15],然后softmax得到[0.30, 0.45, 0.25]。
  • 最后用这个权重去加权V矩阵的各行。

输出就是所有token信息的加权混合。这不就是化学里的“离域π键”么?每个原子都掺了点邻居的电子云。

我个人经验:做ADMET预测时,自注意力的效果高度依赖初始化的好坏。我习惯用Xavier初始化,而不是默认的随机均匀。尤其是在分子序列比较短(比如10-50个原子)时,这个选择影响很明显。

2.3 多头注意力:从多个角度理解分子

单头自注意力有个局限——它只看一种“相关性”。就像分析分子,你可能同时关注:电负性差异、空间位阻、氢键供体/受体。这些是不同层面的交互模式。

多头注意力(Multi-Head Attention)就是解决这个问题的。它把Q、K、V分别切分成h个头,每个头独立算自注意力,然后把结果拼起来再投影一次。

MultiHead(Q, K, V) = Concat(head₁, ..., headₕ) Wₒ
其中 headᵢ = Attention(QWqⁱ, KWkⁱ, VWvⁱ)

我在项目中实测过,8个头对大多数分子任务已经够用。但要注意,头数越多参数也越多,过拟合风险跟着涨。药化数据本来就少,我有一次把头数从8调到16,验证集的R²直接掉了0.05。

注意力类型参数量感受野适用场景
单头注意力少全局但单一视角小数据集、快速验证
多头注意力中等全局且多视角大分子、多任务学习
局部窗口注意力少局部窗口超长序列(如蛋白)
稀疏注意力中等选择性全局长序列+效率优先

2.4 位置编码:给分子序列引入空间感

自注意力对序列顺序是天然不敏感的。你想想看,如果把SMILES中C和O换个位置,自注意力返回的结果在排列变换下是一致的——这在化学上就是灾难,CCC和CCO完全是不同的分子。

位置编码(Positional Encoding)就是给每个token打上一个“位置标签”。

Transformer原文用的是正弦余弦编码:

PE(pos, 2i) = sin(pos / 10000^(2i / d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i / d_model))

为什么是正弦余弦?我当时琢磨了很久。后来想通了:不同频率的正弦波能让模型区分不同尺度的位置关系。低频分量对应长期依赖,高频分量对应局部结构。就好比分子里,低频决定骨架,高频决定侧链构象。

避坑指南:我曾经尝试用可学习的位置编码替换正弦编码,发现效果差不多。但如果序列长度超出训练时的最大长度,可学习编码就会崩。所以做ADMET时,我建议至少把最大序列长度设到512,留够余量。

还有一种叫RoPE(旋转位置编码),它把位置信息直接编码到Q和K的旋转矩阵里,不占用额外的embedding维度。很多后来的分子大模型都在用它。

2.5 编码器-解码器结构:编码+生成的两阶段框架

原始Transformer是编码器-解码器架构。编码器把输入序列变成上下文表示,解码器基于这个表示逐步生成输出。

在ADMET预测任务里,我们通常只要编码器——输入分子SMILES,输出一个固定维度的分子表征向量。但理解解码器也很重要,因为分子生成任务(如逆合成分析)需要它。

编码器由多层堆叠而成,每层包含一个多头注意力和一个前馈网络。注意,这里有残差连接和层归一化:

sub_layer_output = LayerNorm(x + Sublayer(x))

残差连接解决了深层网络的退化问题。我调参时经常看到,层数从4加到8,训练损失还能继续降,就是残差连接的功劳。

解码器多了一层“交叉注意力”——它让解码器在生成每个token时都能“偷看”编码器的输出。这在分子属性预测中一般不出现,但在分子生成和序列到序列任务里是标配。

注意:解码器的自注意力必须加mask,防止看到未来的token。这个mask是对角线以下全为负无穷的上三角矩阵。我曾经忘了加这个mask,结果模型直接学会了复制粘贴输入——测试集上表现完美,换一个分子序列就崩了。

下面这张图总结了本章的核心逻辑:

Transformer架构核心组件 输入序列(Token Embedding) + 位置编码(PE / RoPE) 编码器层(×N) 多头自注意力(Multi-Head Self-Attention) 残差连接+LayerNorm 前馈神经网络(FFN) 残差连接+LayerNorm 解码器层(×N) 掩码多头自注意力 交叉注意力(与编码器) 前馈神经网络(FFN) K、V来自编码器输出 输出序列 / 分子表征 关键组件说明 • 自注意力:全局上下文建模 • 多头注意力:多视角交互 • 位置编码:序列顺序信息 • 编码器-解码器:编码+生成框架 ADMET相关 编码器输出 → 分子表示向量 用于下游分类/回归任务

这张图我把编解码器结构和内部子层都拆开了。从上往下看:输入经过位置编码后进入编码器,编码器通过多头自注意力和FFN提取特征。解码器则多了一层交叉注意力来融合编码器的信息。对ADMET任务来说,我们通常只取编码器最后一层的输出作为分子表示。

我的习惯:做分子性质预测时,我会取编码器CLS token的表示,或者对所有token的表示做平均池化。具体哪个好?我建议你在验证集上试一下——这没有银弹,不同的数据集最优策略差很多。