3、Bahdanau注意力:加性注意力机制,上下文向量的计算,对齐模型
好,咱们接着聊注意力机制。上一章我们讲了经典的Seq2Seq模型,那个结构有个硬伤——编码器必须把整个输入句子压缩成一个固定长度的向量。你想想看,如果句子长了,比如20个词、30个词,这个向量能装得下所有信息吗?显然不行。
我记得2015年刚接触机器翻译项目时,就遇到了这个问题。模型翻译短句还行,一遇到长句就崩,经常漏掉关键信息。后来我看到了Bahdanau等人的论文,豁然开朗。他们提出的注意力机制,说白了就是让模型在生成每个词时,能回头看看源句子的不同位置,而不是死盯着那个固定向量。
加性注意力机制
Bahdanau注意力也叫加性注意力。为什么叫「加性」?因为它计算注意力分数时,用的是加法操作,而不是点积或乘法。
具体来说,给定解码器的上一个隐藏状态 s_{t-1} 和编码器的所有隐藏状态 h_j,我们计算一个分数:
e_{tj} = v_a^T tanh(W_a * s_{t-1} + U_a * h_j)
这里 v_a、W_a、U_a 都是可学习的参数矩阵。你看,这个公式里有个加法操作 W_a * s_{t-1} + U_a * h_j,所以叫加性注意力。
我个人习惯把这个公式拆成三步理解:
- 把解码器状态和编码器状态分别做线性变换
- 把变换后的结果加起来
- 通过tanh激活,再用一个向量做内积得到标量分数
嗯,这里要注意,tanh激活函数很重要。它把输出限制在[-1, 1]之间,能帮助训练更稳定。我在项目中遇到过,如果换成ReLU,模型收敛会慢很多,甚至不收敛。
核心要点:加性注意力通过一个小型神经网络(单隐藏层)来学习两个向量之间的相关性。它不要求编码器和解码器的隐藏状态维度相同,灵活性更高。
上下文向量的计算
有了注意力分数 e_{tj},下一步就是算权重。这个步骤你应该很熟悉了——softmax归一化:
α_{tj} = exp(e_{tj}) / Σ_k exp(e_{tk})
这里的 α_{tj} 就是注意力权重,它表示在生成第t个目标词时,模型应该关注源句子第j个词的程度。所有权重加起来等于1。
然后,上下文向量就是编码器隐藏状态的加权平均:
c_t = Σ_j α_{tj} * h_j
你想想看,这个上下文向量 c_t 是动态计算的。生成每个目标词时,它都不一样。这就解决了固定向量的问题。
我曾经在做一个中文到英文的翻译系统时,发现模型对「把」字句的处理特别差。后来分析注意力权重才发现,模型在生成英文被动语态时,注意力分散到了源句子的多个位置。调整了注意力机制的初始化参数后,效果明显提升。
小技巧:训练初期可以观察注意力权重的分布。如果权重过于均匀(每个位置都差不多),说明模型还没学会聚焦;如果权重过于集中(只关注一个位置),可能有信息丢失的风险。理想状态是集中在2-4个相关位置上。
对齐模型
Bahdanau在论文里把注意力机制叫做「对齐模型」。为什么叫对齐?因为它在学习源语言和目标语言之间的词对齐关系。
传统的统计机器翻译需要显式地做词对齐,比如用GIZA++工具。但Bahdanau的模型把对齐融入到了训练过程中,端到端地学习。
对齐模型的核心思想是:
- 每个目标词应该关注源句子中相关的词
- 对齐关系是软性的,一个目标词可以关注多个源词
- 对齐权重通过反向传播自动学习
我举个例子。翻译「I love you」到中文「我爱你」:
| 目标词 | 源词注意力权重 | 解释 |
|---|---|---|
| 我 | I: 0.95, love: 0.03, you: 0.02 | 主要关注I |
| 爱 | I: 0.02, love: 0.92, you: 0.06 | 主要关注love |
| 你 | I: 0.01, love: 0.04, you: 0.95 | 主要关注you |
你看,这个对齐关系非常清晰。但实际项目中,对齐关系往往没那么完美。我记得有一次做英日翻译,英语的「I like cats」翻译成日语「私は猫が好きです」,注意力图显示「like」同时关注了「好き」和「が」两个位置。这是因为日语语法结构不同,一个英语词可能对应多个日语词。
避坑指南:我曾经在训练一个长文本摘要模型时,发现注意力权重出现了「对角线偏移」现象——模型总是关注源文本中位置相近的词,而不是语义相关的词。这是因为训练数据中源文本和目标文本的顺序高度相关。解决办法是增加dropout,或者使用双向编码器来打破这种位置偏差。
Bahdanau注意力的优缺点
说了这么多,总结一下Bahdanau注意力的特点:
优点:
- 不要求编码器和解码器维度相同,灵活性高
- 通过tanh激活,表达能力比简单的点积更强
- 在小数据集上表现稳定,不容易过拟合
缺点:
- 计算速度慢,因为每个时间步都要计算所有编码器状态
- 参数多,训练时需要更多数据
- 在长序列上,softmax的归一化计算开销大
我个人建议,如果你的任务数据量不大(比如少于10万条),或者编码器和解码器维度不同,优先考虑Bahdanau注意力。如果追求速度,可以试试后面要讲的Luong注意力(点积注意力)。
好,这一章就到这里。下一章我们讲Luong注意力,它和Bahdanau有什么不同?为什么后来Transformer选择了点积注意力?到时候咱们细聊。