数据输入:喂给 EvoFormer 的三种特征
咱们今天聊聊 EvoFormer 吃进去的到底是什么。说白了,就是三类原始数据——序列、MSA、模板。这是整个结构预测的原料,原料不好,后面模型再强也白搭。
我刚开始接触 AlphaFold 的时候,觉得输入不就是一条氨基酸序列吗?结果一看代码才明白,EvoFormer 的输入层远比想象中复杂。它把序列、多序列比对、同源模板结构分别编码成特征张量,然后再拼到一起。嗯,这里每一步都有讲究。
序列特征:最基础的那条线
单个蛋白质序列,我们一般叫它 target sequence。模型会把它编码成两个东西:一个是 one-hot 表示,一个是位置编码。
具体怎么做?我直接上代码示意,这是我从 AlphaFold 源码里摘出来的简化逻辑:
# 伪代码:序列特征构建
num_res = len(sequence)
aatype = one_hot_encoding(sequence, alphabet=20)
# shape: [num_res, 21] (20种AA + 未知)
position = positional_encoding(num_res, max_rel_pos=32)
# shape: [num_res, num_dim]
位置编码这个东西,你想想看,Transformer 本身是不感知顺序的,得靠它告诉模型“第5个残基在第10个残基前面”。AlphaFold 用的是相对位置编码,范围限制在 -32 到 32 之间。为什么要限制?因为远距离残基的位置信息其实不太重要,切一刀能省不少计算量。
MSA 特征:进化信息怎么编码
MSA(多序列比对)是 AlphaFold 的杀手锏。它把同源序列的进化保守性转换成模型能用的数值特征。这个过程我花了两周才完全吃透——它比看上去要复杂得多。
MSA 特征主要分两块:行注意力 和 列注意力。前者捕捉序列间的进化关系,后者捕捉每个残基位点的保守模式。
先看具体编码方式。MSA 中的每条序列都会被处理成一个 22 维的 one-hot 向量(20种氨基酸 + 缺口 + 未知),再加上一些辅助特征:
| 特征名称 | 维度 | 含义 |
|---|---|---|
| msa_aatype | 22 | 氨基酸类型 + 缺口/未知 |
| msa_deletion | 1 | 该位置是否缺失(gap) |
| msa_profile | 21 | 该位置氨基酸出现频率 |
| msa_has_deletion | 1 | 二进制标记是否曾发生缺失 |
| msa_deletion_value | 1 | 缺失概率(归一化后) |
有些同学会问:这些特征怎么得到的?其实大部分是从 MSA 原始比对里统计出来的。举个例子,profile 就是每列每个氨基酸的出现频率——你算一下总共有多少条序列,数一数 Aln 占了几个,Gln 占了几个,除一下就行。
模板特征:从已知结构中偷师
模板特征是最容易理解的部分——直接用已知的蛋白质结构去辅助预测目标结构。但这些已知结构不能直接用 PDB 坐标,得转成模型能理解的表示。
AlphaFold 用的模板特征主要有:
- 模板残基类型:one-hot 编码,20维
- 模板主链二面角:phi、psi,各一维,标准化到 [-π, π]
- 模板距离图:CB-CB 距离(Gly 用 CA),分 bin 编码
- 模板单位向量:描述主链方向,用于相对方位编码
其中距离图编码这步比较有意思。AlphaFold 不是直接丢距离值进去,而是先做分桶——从 2.0Å 到 20.0Å 分 15 个 bin,每个距离落在对应 bin 里就激活那个通道。这东西我一开始觉得多余,后来测试时发现,没有分桶的话模型对距离的泛化能力差很多。
# 伪代码:模板距离图编码
dist = cdist(CB_coords, CB_coords) # [N, N]
bins = [2.0, 2.5, 3.0, ..., 20.0]
dist_bin = digitize(dist, bins=bins) # 0~14 共15个bin
feat = one_hot(dist_bin, num_bins=15)
# shape: [N, N, 15]
三种特征的拼接方式
这三种特征不是简单堆叠的。EvoFormer 的输入层把它们分别嵌入到不同的子空间,然后在后面的 Attention 模块里通过 轴向注意力 交互。
具体流程看图:
你看,整个流程是从左到右,三种特征分别编码,然后在拼接层对齐到统一的 hidden size(256维)。我这里用了 S 表示 MSA 的序列数(deep 维度),N 表示目标序列的残基数。
维度的对齐在实际实现里是个坑。序列特征是 2D 的 [N, d],MSA 是 3D 的 [S, N, d],模板又是 3D 的 [N, N, d]——它们怎么拼?答案是:不拼!我一开始也以为会拼成一个超级张量,但实际 EvoFormer 用的是“保持各自维度,通过交叉注意力交互”。具体来说,MSA 特征做行注意力时,会 Query 序列特征的信息;模板特征则作为 pair representation 的初始化。
总结一下我对这三种特征的理解:序列是骨架,MSA 是肌肉,模板是参考线。模型没有骨架会乱跑,没有肌肉会软塌塌,没有参考线会找不到方向。三者缺一不可。