Attention 模型机制详解
Attention 模型在自然语言处理(NLP)领域应用广泛,但其基本原理常被误解。本文旨在通过清晰的逻辑梳理 Attention 机制的核心概念、工作流程及数学原理,并补充完整的代码实现。
Encoder-Decoder 模型基础
Attention 模型的提出是为了解决 Seq2Seq(Sequence to Sequence)模型在处理长序列时的局限性。Seq2Seq 主要解决一个序列映射到另一个序列的问题,典型应用场景包括:
- 机器翻译:源语言文本序列 -> 目标语言文本序列
- 语音识别:声学特征序列 -> 识别文本序列
- 问答系统:问题描述单词序列 -> 生成答案单词序列
- 文本摘要:原文本序列 -> 摘要序列
基础的 Seq2Seq 模型包含 Encoder(编码器)、Decoder(解码器)以及固定长度的语义向量。Encoder 将输入序列编码为固定维度的向量,Decoder 基于该向量生成输出序列。
Encoder 结构
Encoder 通常由 RNN、LSTM 或 GRU 等循环神经网络构成。以 RNN 为例,其当前隐藏状态由上一个输入的隐藏状态和当前输入共同决定。
RNN 隐藏节点状态计算: $$h_t = f(W_{xh} x_t + W_{hh} h_{t-1} + b_h)$$
其中:
- $h_t$ 表示 RNN 当前隐藏状态
- $h_{t-1}$ 表示上一个输入的隐藏状态
- $x_t$ 表示当前的输入
在输入结束后,Encoder 生成最后的语义向量 $C$。对于简单的 Seq2Seq 模型,这个向量通常是最后一个时间步的隐藏状态 $h_T$。
$$C = h_T$$
语义向量 $C$ 是一个固定长度的向量,作为 Decoder 的唯一输入。然而,这种方式存在缺陷:由于 Encoder 编码输出的语义向量是固定长度,对于较长的输入序列,部分信息会在压缩过程中丢失,导致 Decoder 生成的结果质量下降,尤其是当输入句子很长时。
Decoder 结构
Decoder 同样可以是 RNN 或 LSTM。其输入包括 Encoder 输出的语义向量 $C$ 和已经生成的输出序列。在每一步预测下一个输出单词 $y_t$ 时,模型依赖之前的输出 $y_{t-1}$ 和隐藏状态 $s_{t-1}$。
$$s_t = g(s_{t-1}, y_{t-1}, C)$$
$$P(y_t | y_{<t}) = ext{softmax}(W s_t + b)$$
这种机制限制了 Decoder 只能从固定的 $C$ 中获取信息,无法动态关注输入序列的不同部分。
Attention 模型机制
为了解决固定长度语义向量导致的信息丢失问题,Bahdanau 等人提出了早期的 Attention 模型。其核心思想是模拟人类翻译时的注意力分配:在翻译某个词时,只关注源语句中相关的几个词。
工作原理
- 输入序列编码:使用 Encoder(如 RNN/LSTM)将输入序列 $X = (x_1, x_2, ..., x_n)$ 编码为隐藏状态序列 $H = (h_1, h_2, ..., h_n)$。
- 注意力权重计算:对于 Decoder 的每一个时间步 $t$,计算其与 Encoder 所有隐藏状态的关联程度,得到注意力权重 $eta_{t,i}$。
- 计算上下文向量:根据权重对 Encoder 的隐藏状态进行加权求和,得到当前时刻的上下文向量 $c_t$。
- Decoder 输出:结合上下文向量 $c_t$ 和 Decoder 的状态预测下一个输出。
注意力权重计算
定义注意力权重为 $eta_{t,i}$,其中 $i$ 为输入序列下标。对于当前需要解码的向量 $q_t$(通常取 Decoder 的上一步隐藏状态),其对应的注意力权重通过一个打分函数 $score(q_t, h_i)$ 计算,并经过 Softmax 归一化:
$$\alpha_{t,i} = \frac{\exp(score(q_t, h_i))}{\sum_{k=1}^{T_x} \exp(score(q_t, h_k))}$$


