第一章:人工智能之不同数据类型及其特点梳理
第二章:自然语言处理(NLP):文本向量化从文字到数字的原理
第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码)
第四章:循环神经网络RNN、LSTM以及GRU 对比(附代码)
第五章:理解Seq2Seq的工作机制与应用场景中英互译(附代码)
第六章:深度学习架构Seq2Seq-添加并理解注意力机制(一)
第七章:深度学习架构Seq2Seq-添加并理解注意力机制(二)
本文主要是分析Seq2Seq 架构本身具有的缺点,并分析针对长序列输入时,导致信息丢失这一问题,造成这个问题的原因,以及针对这一问题,通过引入注意力机制,如何来解决这一问题。
一、Seq2Seq简介
Seq2Seq(Sequence to Sequence)模型是一种深度学习架构,主要用于处理输入和输出均为可变长度序列的任务,如机器翻译、文本摘要和语音识别等。其核心结构包含两部分,编码器(Encoder)和 解码器(Decoder),如下图所示,输入是英文单词 ‘like’ 翻译成中文 ‘喜欢’
- 编码器(Encoder):通常由RNN、LSTM或GRU等循环神经网络构成,负责将输入序列逐步编码为一个固定长度的上下文向量(Context Vector),该向量综合了输入序列的整体语义信息。
- 解码器(Decoder):同样基于循环神经网络,接收编码器生成的上下文向量作为初始输入,逐步生成输出序列的每个元素。训练时常用“教师强制”(Teacher Forcing)方法,即将前一步的真实输出作为当前步的输入以提高稳定性。
Seq2Seq模型的特点在于处理变长序列时无需严格对齐输入与输出的长度,例如将中文句子翻译为英文时,输出长度可灵活变化。
二、普通 Seq2Seq 的局限性
普通 Seq2Seq 模型将输入序列压缩为 单一的上下文向量(Encoder 的最后一个隐藏状态,就是上图中的Context Vector),存在以下问题:
- 信息瓶颈:长序列输入时,单一向量难以保留所有细节,即整个输入序列被压缩成一个固定大小的向量上下文向量,可能导致信息丢失。
- 长距离依赖丢失:解码器无法灵活关注输入序列的不同部分。
- 速度慢:训练速度较慢且难以并行化。
在Seq2Seq模型中,编码器将整个输入序列压缩成一个固定大小的向量(即上下文向量或语义向量),然后解码器使用这个向量来生成输出序列。这种做法存在几个潜在的问题,尤其是当处理较长的输入序列时,可能会导致信息丢失。
输入序列太长,为什么会导致信息丢失?
-
固定维度限制:无论输入序列有多长,上下文向量的维度都是固定的。这意味着如果输入序列非常长,编码器需要将大量信息压缩到一个有限维度的空间里。这就像试图将一本书的内容压缩进一句话中一样,不可避免地会丢失一些细节和细微差别。
-
信息覆盖问题:对于某些复杂的任务,如长文本翻译或对话系统,源序列可能包含多个主题、观点或重要细节。由于上下文向量的容量有限,编码器可能无法有效地表示所有这些信息,从而导致关键信息被忽略或覆盖。
举例说明
假设我们有一个中文句子“我喜欢吃鱼,特别是新鲜的鲑鱼,它富含Omega-3脂肪酸,对心脏健康有益”,我们要将其翻译成英文。
-
没有注意力机制的情况:编码器尝试将这句话的所有信息压缩成一个固定大小的向量。然而,这句话包含了多个部分的信息——个人偏好(喜欢)、食物类型(鱼)、具体种类(鲑鱼)、营养成分(Omega-3脂肪酸)以及健康益处(对心脏健康有益)。如果输入序列过长或者信息过于复杂,那么单一的上下文向量很可能无法承载这么多不同的信息点。结果,在解码阶段,解码器可能难以准确地再现原句的所有细节,可能会遗漏一些重要的内容,例如忘记提及“Omega-3脂肪酸”或是“对心脏健康有益”。
-
有注意力机制的情况:在这种情况下,每当解码器准备生成下一个单词时,它不仅依赖于前一时刻的状态,还能够通过注意力机制直接访问输入序列的不同部分。这样,即使输入序列很长,解码器也能够根据当前生成的内容需求,选择性地关注最相关的信息。比如,在生成关于鲑鱼营养价值的部分时,它可以特别关注与“Omega-3脂肪酸”相关的输入部分;而在提到饮食喜好时,则可以更侧重于“我喜欢吃鱼”这部分的信息。因此,注意力机制大大提高了模型处理长距离依赖关系的能力,并且减少了信息丢失的可能性。
固定大小的上下文向量在处理长或复杂序列时面临信息丢失的风险,因为它们不能完全捕捉并保留原始输入序列中的全部信息。引入注意力机制是解决这一问题的有效方法之一。
三、注意力机制的核心思想
注意力机制 允许解码器在每个时间步动态关注输入序列的 相关部分,而非依赖单一向量。其核心流程如下:
- 编码器输出 所有时间步的隐藏状态(而非仅最后一步)。
- 解码时,计算解码器当前状态与所有编码器状态的 相似度,生成注意力权重。
- 根据权重 加权求和编码器状态,生成动态上下文向量。
- 将动态上下文向量与解码器输入结合,预测当前输出。
四、实现步骤
4.1 编码器处理输入序列
- 输入序列: X = ( x 1 , x 2 , … , x T ) \mathbf{X} = (x_1, x_2, \dots, x_T) X=(x1,x2,…,xT)
- 编码器输出:所有时间步的隐藏状态 { h 1 , h 2 , … , h T } \{h_1, h_2, \dots, h_T\} {h1,h2,…,hT}
4.2 计算注意力权重
在解码器的第 t t t 步:
-
解码器当前隐藏状态: s t − 1 s_{t-1} st−1(上一步的隐藏状态)
-
编码器所有隐藏状态: { h 1 , h 2 , … , h T } \{h_1, h_2, \dots, h_T\} {h1,h2,…,hT}
-
计算相似度(注意力分数):
e t i = score ( s t − 1 , h i ) e_{ti} = \text{score}(s_{t-1}, h_i) eti=score(st−1,hi)
常用相似度计算方式:- 点积(Dot Product): e t i = s t − 1 ⊤ h i e_{ti} = s_{t-1}^\top h_i eti=st−1⊤hi
- 加性(Additive): e t i = v ⊤ tanh ( W s s t − 1 + W h h i ) e_{ti} = \mathbf{v}^\top \tanh(\mathbf{W}_s s_{t-1} + \mathbf{W}_h h_i) eti=v⊤tanh(Wsst−1+Whhi)
-
归一化为权重:
α t i = exp ( e t i ) ∑ j = 1 T exp ( e t j ) \alpha_{ti} = \frac{\exp(e_{ti})}{\sum_{j=1}^T \exp(e_{tj})} αti=∑j=1Texp(etj)exp(eti)
4.3 生成动态上下文向量
c t = ∑ i = 1 T α t i h i \mathbf{c}_t = \sum_{i=1}^T \alpha_{ti} h_i ct=∑i=1Tαtihi
4.4 结合上下文向量生成输出
- 拼接解码器状态与上下文向量:
s ~ t = tanh ( W c [ s t − 1 ; c t ] + b c ) \tilde{s}_t = \tanh(\mathbf{W}_c [s_{t-1}; \mathbf{c}_t] + \mathbf{b}_c) s~t=tanh(Wc[st−1;ct]+bc) - 预测输出概率分布:
p ( y t ∣ y < t , X ) = Softmax ( W o s ~ t + b o ) p(y_t | y_{<t}, \mathbf{X}) = \text{Softmax}(\mathbf{W}_o \tilde{s}_t + \mathbf{b}_o) p(yt∣y<t,X)=Softmax(Wos~t+bo)
4.5 数学公式总结
对于解码器的第
t
t
t 步:
Attention Weights:
α
t
i
=
Softmax
(
score
(
s
t
−
1
,
h
i
)
)
Context Vector:
c
t
=
∑
i
=
1
T
α
t
i
h
i
Decoder Output:
p
(
y
t
∣
y
<
t
,
X
)
=
Softmax
(
W
o
⋅
tanh
(
W
c
[
s
t
−
1
;
c
t
]
+
b
c
)
)
\begin{aligned} \text{Attention Weights:} \quad & \alpha_{ti} = \text{Softmax}(\text{score}(s_{t-1}, h_i)) \\ \text{Context Vector:} \quad & \mathbf{c}_t = \sum_{i=1}^T \alpha_{ti} h_i \\ \text{Decoder Output:} \quad & p(y_t | y_{<t}, \mathbf{X}) = \text{Softmax}(W_o \cdot \tanh(W_c [s_{t-1}; \mathbf{c}_t] + b_c)) \end{aligned}
Attention Weights:Context Vector:Decoder Output:αti=Softmax(score(st−1,hi))ct=i=1∑Tαtihip(yt∣y<t,X)=Softmax(Wo⋅tanh(Wc[st−1;ct]+bc))
4.6 理解点积(Dot Product)
点积(Dot Product),也被称为内积(Inner Product),是向量之间的一种二元运算,在数学、物理学以及工程学中有着广泛的应用。
对于两个维数相同的向量
a
=
[
a
1
,
a
2
,
.
.
.
,
a
n
]
\mathbf{a} = [a_1, a_2, ..., a_n]
a=[a1,a2,...,an] 和
b
=
[
b
1
,
b
2
,
.
.
.
,
b
n
]
\mathbf{b} = [b_1, b_2, ..., b_n]
b=[b1,b2,...,bn],
它们的点积定义为:
a
⋅
b
=
∑
i
=
1
n
a
i
b
i
=
a
1
b
1
+
a
2
b
2
+
.
.
.
+
a
n
b
n
\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1b_1 + a_2b_2 + ... + a_nb_n
a⋅b=∑i=1naibi=a1b1+a2b2+...+anbn
即,两个向量的点积等于对应元素相乘后的和。
几何解释
点积还有一个重要的几何意义,即两个向量的点积等于它们的模长乘积与它们之间夹角余弦值的乘积:
a ⋅ b = ∣ a ∣ ∣ b ∣ cos θ \mathbf{a} \cdot \mathbf{b} = |\mathbf{a}| |\mathbf{b}| \cos{\theta} a⋅b=∣a∣∣b∣cosθ
这里, ∣ a ∣ |\mathbf{a}| ∣a∣ 和 ∣ b ∣ |\mathbf{b}| ∣b∣ 分别表示向量 a \mathbf{a} a 和 b \mathbf{b} b 的长度(或称为模),而 θ \theta θ 是两向量之间的夹角。通过这个公式,我们可以看出点积可以用来计算两个向量之间的角度,或者判断它们是否正交(如果点积为零,则两向量垂直)。
在机器学习和深度学习领域,点积常用于衡量向量间的相似度。例如,在注意力机制中,它被用来计算查询向量与键向量之间的匹配程度。
4.7 理解加性(Additive)
在深度学习和自然语言处理的上下文中,“加性”(Additive)通常指的是“加性注意力机制”,这是一种用于序列到序列(Seq2Seq)模型中的注意力计算方法。与点积注意力(Dot-Product Attention)不同,加性注意力使用了一个小型的前馈神经网络来计算输入序列中每个位置的注意力分数。
加性注意力机制的工作原理
其主要思想是通过一个小型的两层前馈神经网络来计算注意力权重,这个过程可以分解为以下几个步骤:
-
输入准备:对于解码器中的每一个时间步 t t t,我们考虑编码器的所有隐藏状态 { h 1 , h 2 , . . . , h n } \{h_1, h_2, ..., h_n\} {h1,h2,...,hn} 和当前解码器的隐藏状态 s t − 1 s_{t-1} st−1。
-
能量计算:将编码器的每个隐藏状态 h i h_i hi 和解码器隐藏状态 s t − 1 s_{t-1} st−1 作为输入,传递给一个小的前馈神经网络。这个网络通常包含一层或多层,并使用tanh作为激活函数。具体来说,计算能量值 e t i e_{ti} eti 的公式如下:
e t i = v T tanh ( W [ h i ; s t − 1 ] ) e_{ti} = v^T \tanh(W[h_i; s_{t-1}]) eti=vTtanh(W[hi;st−1])
其中, W W W 是权重矩阵, v v v 是输出向量, [ h i ; s t − 1 ] [h_i; s_{t-1}] [hi;st−1] 表示向量拼接操作。
-
注意力权重计算:对上述得到的能量值进行Softmax变换,以确保所有注意力权重之和为1。即,
α t i = exp ( e t i ) ∑ j exp ( e t j ) \alpha_{ti} = \frac{\exp(e_{ti})}{\sum_j \exp(e_{tj})} αti=∑jexp(etj)exp(eti) -
上下文向量生成:根据计算出的注意力权重对编码器的所有隐藏状态进行加权求和,得到上下文向量 c t c_t ct:
c t = ∑ i α t i h i c_t = \sum_i \alpha_{ti} h_i ct=∑iαtihi
-
结合上下文向量与解码器状态:最后,上下文向量 c t c_t ct 被用来辅助解码器预测下一个词,通常会与当前解码器的状态结合起来。
加性注意力 vs 点积注意力
- 复杂度:加性注意力通常比点积注意力更复杂,因为它需要额外的参数和非线性变换(如tanh激活函数)。然而,它也提供了更大的灵活性来捕捉输入之间的复杂关系。
- 适用场景:点积注意力在高维度空间中更加高效,因为它的计算可以直接利用矩阵乘法加速;而加性注意力可能更适合于那些需要更多非线性处理的任务或数据集。
下一篇《深度学习架构Seq2Seq-添加并理解注意力机制(二)》使用中文翻译成英文的案例,“我喜欢吃鱼” 翻译为 “I like eating fish” 的简单例子,通过具体的数字,模拟模型推理过程,来辅助解释上面这一套公式。