注意力机制:Jointly Learning to Align and Translate中从双向RNN编码器到软对齐的完整流程

文章目录

前言:

论文标题"Jointly Learning to Align and Translate"点明了其核心贡献:模型在一个统一的框架内,同时学习翻译任务和源语言与目标语言之间的词语对齐关系 。这种对齐是通过注意力权重 αij 隐式学习得到的,它量化了在生成目标词 yi 时,对源词 xj 的关注程度。

(1)编码器工作机制

【1】普通RNN的局限

一个标准的循环神经网络RNN会从第一个符号 x_1 到最后一个符号 x_{T_x} 顺序地 读取输入序列
h t = f ( x t , h t − 1 ) \quad h_t = f(x_t, h_{t-1}) ht=f(xt,ht−1)

这种单向结构导致每个隐藏状态 h_t 主要包含了到当前时刻为止的历史信息 ,无法获取未来时刻的上下文

【2】双向RNN:获取完整上下文

为了克服这一局限,本文采用了双向RNN ,其核心思想是为每个词生成一个同时囊括了前文后文 信息的上下文表示

如图所示,双向RNN由两个独立的RNN组成:

  • 前向RNN ( RNN → \overrightarrow{\text{RNN}} RNN ):从 x_1x_{T_x} 顺序读取输入,生成隐藏状态 h j → \overrightarrow{h_j} hj ,它总结了第 j 个词之前的所有上文信息
  • 反向RNN ( RNN ← \overleftarrow{\text{RNN}} RNN ):从 x_{T_x}x_1 逆序读取输入,生成隐藏状态 h j ← \overleftarrow{h_j} hj ,它总结了第 j 个词之后的所有下文信息

最终,我们将每个位置 j 的前向与反向隐藏状态进行拼接 ,得到该词的最终注解向量 h_j

(2)解码器工作机制

下面我将按照训练阶段的逻辑顺序来讲解解码器的完整工作流程,这样能更好地理解各个组件如何协同工作。整个流程如图所示:

【1】输入准备

训练阶段采用Teacher Forcing策略:

  • 编码器输入:完整的源语言序列 x
  • 解码器输入:真实标签的前缀 y_1, ..., y_{i-1}
  • 目标输出:下一个真实标签 y_i

【2】能量分数计算

在生成目标词 y_i 时,计算解码器前一状态 s_{i−1} 与每个编码器标注 h_j 的匹配程度:
e i j = a ( s i − 1 , h j ) e_{ij} = a(s_{i-1}, h_j) eij=a(si−1,hj)


其中a是一个前馈神经网络,附录A.1.2补充了具体形式:
e i j = a ( s i − 1 , h j ) = v a T ⋅ t a n h ( W a ⋅ s i − 1 + U a ⋅ h j ) e_{ij} = a(s_{i-1}, h_j) = v_a^T · tanh(W_a · s_{i-1} + U_a · h_j) eij=a(si−1,hj)=vaT⋅tanh(Wa⋅si−1+Ua⋅hj)

其中:

  • W_a ∈ R^(d×d_s):解码器状态的权重矩阵(d_s为状态维度,d为对齐模型的隐藏层维度)

  • U_a ∈ R^(d×d_h):编码器标注的权重矩阵(d_h为标注维度)

  • v_a ∈ R^d:输出权重向量,将d维隐藏层映射到标量分数(一个值)

    理解:a作为一个对齐模型,里面有许多我们需要学习的参数,一旦学习到这个参数,我们就可以直接进行预测

【3】注意力权重计算

通过Softmax函数将能量分数转换为概率分布的注意力权重:

α i j = exp ⁡ ( e i j ) ∑ k = 1 T x exp ⁡ ( e i k ) \alpha_{ij} = \frac{\exp(e_{ij})}{\sum_{k=1}^{T_x} \exp(e_{ik})} αij=∑k=1Txexp(eik)exp(eij)

与能量分数意义相同,即在生成当前目标词 y_i时,编码器标注 h_j 相对于解码器状态 s_{i-1} 的重要性程度。

【4】注意力上下文向量计算

在获得注意力权重后,我们通过加权求和的方式生成上下文向量:
c i = α i 1 ⋅ h 1 + α i 2 ⋅ h 2 + . . . + α i T x ⋅ h T x ci = α_{i1}·h₁ + α_{i2}·h₂ + ... + α_{i{T_x}}·h_{T_x} ci=αi1⋅h1+αi2⋅h2+...+αiTx⋅hTx

对于当前输出 y_i ,编码器中重要的信息会被放大 ,不重要的被抑制

【5】解码器状态更新

整合三方面信息更新解码器状态:
s i = f ( s i − 1 , y i − 1 , c i ) s_i = f(s_{i-1}, y_{i-1}, c_i) si=f(si−1,yi−1,ci)

其中:

  • s_{i-1}:历史状态信息

  • y_{i-1}:前一个真实标签

  • c_i:注意力上下文

    理解:函数 f 通常实现为GRU或LSTM等RNN单元,同上面的a模型,f里面有许多我们需要学习的参数,一旦学习到这个参数,我们就可以直接进行预测

【6】目标词概率生成

基于所有可用信息生成目标词的概率分布:
p ( y i ∣ y 1 , ... , y i − 1 , x ) = g ( y i − 1 , s i , c i ) p(y_i | y_1, \ldots, y_{i-1}, \mathbf{x}) = g(y_{i-1}, s_i, c_i) p(yi∣y1,...,yi−1,x)=g(yi−1,si,ci)


函数 (g) 的典型实现流程:

python 复制代码
输入 = [y_{i-1}的嵌入向量, s_i, c_i]           # 向量拼接
隐藏层 = tanh(W_h · 输入 + b_h)            # 非线性变换
logits = W_o · 隐藏层 + b_o               # 输出层,得到词汇分数
p(y_i) = softmax(logits)                  # 转换为概率分布

【7】损失计算与反向传播

  • 计算交叉熵损失:loss = -log(p(y_i))
  • 累加所有时间步的损失
  • 一次性反向传播更新所有参数

训练过程示例:

python 复制代码
第1步:解码器输入<sos> → 预测"你好" (与真实标签"你好"计算交叉熵损失)
第2步:解码器输入真实标签"你好" → 预测"大家" (与真实标签"大家"计算交叉熵损失)  
第3步:解码器输入真实标签"大家" → 预测<eos> (与真实标签<eos>计算交叉熵损失)
第4步:累加所有步骤损失 → 反向传播更新参数

【8】从训练到预测

预测阶段采用自回归生成方式,与训练阶段的主要区别:

方面 训练阶段 预测阶段
输入来源 真实标签 y_{i-1} 模型预测 ŷ_{i-1}
目标 学习正确映射 生成完整序列
错误处理 避免错误累积 可能错误传播

预测过程示例:

python 复制代码
第1步:解码器输入<sos> → 预测ŷ₁ = "你好"
第2步:解码器输入上一步的预测结果ŷ₁ → 预测ŷ₂ = "大家"
第3步:解码器输入上一步的预测结果ŷ₂ → 预测ŷ₃ = <eos> (停止生成)

这两者的区别,如图所示:

相关推荐
IT古董15 小时前
【第七章:时间序列模型】2.时间序列统计模型与神经网络模型-(3)神经网络预测时间序列模型: 从RNN,LSTM到nbeats模型
rnn·神经网络·lstm
rengang662 天前
14-循环神经网络(RNN):分析RNN在序列数据中的表现和特点
人工智能·rnn·深度学习
文火冰糖的硅基工坊2 天前
[人工智能-大模型-125]:模型层 - RNN的隐藏层是什么网络,全连接?还是卷积?RNN如何实现状态记忆?
人工智能·rnn·lstm
文火冰糖的硅基工坊3 天前
[人工智能-大模型-122]:模型层 - RNN是通过神经元还是通过张量时间记录状态信息?时间状态信息是如何被更新的?
人工智能·rnn·深度学习
zhangfeng11334 天前
移动流行区间法(MEM)的原理和与LSTM、ARIMA等时间序列方法的区别
人工智能·rnn·lstm
文火冰糖的硅基工坊6 天前
[人工智能-大模型-117]:模型层 - 用通俗易懂的语言,阐述循环神经网络的结构
人工智能·rnn·深度学习
文火冰糖的硅基工坊6 天前
[人工智能-大模型-118]:模型层 - RNN状态记忆是如何实现的?是通过带权重的神经元,还是通过张量?
人工智能·rnn·深度学习
~kiss~8 天前
CNN(卷积神经网络)和 RNN(循环神经网络)
人工智能·rnn·cnn
天地之于壹炁兮9 天前
神经网络进化史:从理论到变革
人工智能·rnn·深度学习·transformer