深度学习笔记之Seq2seq(二)基于Seq2seq注意力机制的动机

news2024/11/24 14:36:56

深度学习笔记之Seq2seq——基于Seq2seq注意力机制的动机

引言

上一节介绍了 Seq2seq \text{Seq2seq} Seq2seq网络常用的基本结构以及在机器翻译任务中,关于目标函数预测概率的描述。本节依然以机器翻译任务为例,对 Seq2seq \text{Seq2seq} Seq2seq中的注意力机制 ( Attention ) (\text{Attention}) (Attention)进行描述。

回顾:基于机器翻译任务的 Seq2seq \text{Seq2seq} Seq2seq网络结构

关于机器翻译任务的 Seq2seq \text{Seq2seq} Seq2seq网络结构表示如下:

Seq2seq网络结构(机器翻译)
该结构包含编码器 ( Encoder ) (\text{Encoder}) (Encoder)解码器 Decoder \text{Decoder} Decoder两部分。并且它们均是循环神经网络的网络结构。已知在编码器中输入的序列数据 X \mathcal X X表示如下:
X = ( x ( 1 ) , x ( 2 ) , ⋯   , x ( T ) ) T \mathcal X = (x^{(1)},x^{(2)},\cdots,x^{(\mathcal T)})^T X=(x(1),x(2),,x(T))T
通过循环神经网络我们可以得到最终 T \mathcal T T时刻的序列信息 Context \text{Context} Context向量,记作 C \mathcal C C。其中 C \mathcal C C记录了序列数据 X \mathcal X X所有时刻的序列信息

解码器的执行过程中,初始状态下,给定一个初始标识符 ⟨ Start ⟩ \left\langle\text{Start}\right\rangle Start,基于 Encoder \text{Encoder} Encoder读取的序列信息 C \mathcal C C,我们可以求解翻译过程中初始时刻 y ( 1 ) y^{(1)} y(1)的条件概率结果:
其中‘初始标识符’ ⟨ Start ⟩ \left\langle\text{Start}\right\rangle Start本身不包含任何语义信息。这里将其忽略;
y ( 1 ) ⇒ P ( y ( 1 ) ∣ C , ⟨ Start ⟩ ) = P ( y ( 1 ) ∣ C ) y^{(1)} \Rightarrow \mathcal P(y^{(1)} \mid \mathcal C,\left\langle\text{Start}\right\rangle) = \mathcal P(y^{(1)} \mid \mathcal C) y(1)P(y(1)C,Start)=P(y(1)C)
在得到概率分布 P ( y ( 1 ) ∣ C ) \mathcal P(y^{(1)} \mid \mathcal C) P(y(1)C)的同时,我们同样可以得到解码器初始时刻的序列信息 h D ; 1 h_{\mathcal D;1} hD;1

  • 这里以 RNN \text{RNN} RNN为例, LSTM,GRU \text{LSTM,GRU} LSTM,GRU同理。只不过 RNN \text{RNN} RNN的表述能够简单一些。
  • 由于 ⟨ Start ⟩ \left\langle\text{Start}\right\rangle Start中不包含语义信息,因而不希望其对应的权重 W C ⇒ h D ; 1 \mathcal W_{\mathcal C \Rightarrow h_{\mathcal D;1}} WChD;1学习到任何有用的信息,这里将其忽略。
    h D ; 1 = Tanh ( W C ⇒ h D ; 1 ⋅ C + W Start ⇒ h D ; 1 ⋅ ⟨ Start ⟩ ⏟ Delete + b h D ) = Tanh ( W C ⇒ h D ; 1 ⋅ C + b h D ) \begin{aligned} h_{\mathcal D;1} & = \text{Tanh} \left(\mathcal W_{\mathcal C \Rightarrow h_{\mathcal D;1}} \cdot \mathcal C + \underbrace{\mathcal W_{\text{Start} \Rightarrow h_{\mathcal D;1}} \cdot \left\langle\text{Start}\right\rangle}_{\text{Delete}} + b_{h_{\mathcal D}}\right) \\ & = \text{Tanh}( \mathcal W_{\mathcal C \Rightarrow h_{\mathcal D;1}} \cdot \mathcal C + b_{h_{\mathcal D}}) \end{aligned} hD;1=Tanh WChD;1C+Delete WStarthD;1Start+bhD =Tanh(WChD;1C+bhD)

同理,根据 Seq2seq \text{Seq2seq} Seq2seq结构,我们同样可以得到下一时刻 y ( 2 ) y^{(2)} y(2)后验概率分布以及对应时刻的序列信息 h D ; 2 h_{\mathcal D;2} hD;2
y ( 2 ) ⇒ P ( y ( 2 ) ∣ C , y ( 1 ) ) h D ; 2   = Tanh ( W h D ; 1 ⇒ h D ; 2 ⋅ h D ; 1 + W y ( 1 ) ⇒ h D ; 2 ⋅ y ( 1 ) + b h D ) \begin{aligned} y^{(2)} & \Rightarrow \mathcal P(y^{(2)} \mid \mathcal C,y^{(1)}) \\ h_{\mathcal D;2} \ & = \text{Tanh} \left(\mathcal W_{h_{\mathcal D;1} \Rightarrow h_{\mathcal D;2}} \cdot h_{\mathcal D;1} + \mathcal W_{y^{(1)} \Rightarrow h_{\mathcal D;2}} \cdot y^{(1)} + b_{h_{\mathcal D}} \right) \end{aligned} y(2)hD;2 P(y(2)C,y(1))=Tanh(WhD;1hD;2hD;1+Wy(1)hD;2y(1)+bhD)
以此类推。而最终关于生成序列 Y \mathcal Y Y基于 Context \text{Context} Context向量 C \mathcal C C条件下的联合概率分布 P ( Y ∣ C ) \mathcal P(\mathcal Y \mid \mathcal C) P(YC)可表示为:
P ( Y ∣ C ) = P ( y ( 1 ) , y ( 2 ) , ⋯   , y ( T ′ ) ∣ C ) = P ( y ( 1 ) ∣ C ) ⋅ ∏ t = 2 T ′ P ( y ( t ) ∣ C , y ( 1 ) , ⋯   , y ( t − 1 ) ) \begin{aligned} \mathcal P(\mathcal Y \mid \mathcal C) & = \mathcal P(y^{(1)},y^{(2)},\cdots,y^{(\mathcal T')} \mid \mathcal C) \\ & = \mathcal P(y^{(1)} \mid \mathcal C) \cdot \prod_{t=2}^{\mathcal T'} \mathcal P(y^{(t)} \mid \mathcal C,y^{(1)},\cdots,y^{(t-1)}) \end{aligned} P(YC)=P(y(1),y(2),,y(T)C)=P(y(1)C)t=2TP(y(t)C,y(1),,y(t1))

注意力机制的动机

循环神经网络作为 Encoder \text{Encoder} Encoder产生 Context \text{Context} Context向量的缺陷

如果将解码器各输出的条件概率看做是一个复杂函数 f ( ⋅ ) f(\cdot) f(),各条件概率可表示为如下形式:
除了第一项,虽然后续函数中没有体现出 C \mathcal C C的参与,但实际上,解码器每一个时刻关于 y ( t ) ( t = 1 , 2 , ⋯   , T ′ ) y^{(t)}(t=1,2,\cdots,\mathcal T') y(t)(t=1,2,,T)的生成过程均有 C \mathcal C C的参与,因为 h D ; 1 , h D ; 2 , ⋯ h_{\mathcal D;1},h_{\mathcal D;2},\cdots hD;1,hD;2,内均有 C \mathcal C C参与运算。
y ( 1 ) ⇒ P ( y ( 1 ) ∣ C ) = f ( C ) y ( 2 ) ⇒ P ( y ( 2 ) ∣ y ( 1 ) , C ) = f ( y ( 1 ) , h D ; 1 ) ⇒ f ( y ( 1 ) , C ⏟ from  h D ; 1 ) y ( 3 ) ⇒ P ( y ( 3 ) ∣ y ( 1 ) , y ( 2 ) , C ) = f ( y ( 2 ) , h D ; 2 ) ⇒ f ( y ( 2 ) , y ( 1 ) , C ⏟ from  h D ; 2 ) ⋮ \begin{aligned} y^{(1)} & \Rightarrow \mathcal P(y^{(1)} \mid \mathcal C) = f(\mathcal C) \\ y^{(2)} & \Rightarrow \mathcal P(y^{(2)} \mid y^{(1)},\mathcal C) = f(y^{(1)},h_{\mathcal D;1}) \Rightarrow f(y^{(1)},\underbrace{\mathcal C}_{\text{from } h_{\mathcal D;1}}) \\ y^{(3)} & \Rightarrow \mathcal P(y^{(3)} \mid y^{(1)},y^{(2)},\mathcal C) = f(y^{(2)},h_{\mathcal D;2}) \Rightarrow f(y^{(2)},\underbrace{y^{(1)},\mathcal C}_{\text{from } h_{\mathcal D;2}})\\ & \quad \quad \quad \quad \quad \vdots \end{aligned} y(1)y(2)y(3)P(y(1)C)=f(C)P(y(2)y(1),C)=f(y(1),hD;1)f(y(1),from hD;1 C)P(y(3)y(1),y(2),C)=f(y(2),hD;2)f(y(2),from hD;2 y(1),C)
因此,有:在生成 y ( t ) ( t = 1 , 2 , ⋯   , T ′ ) y^{(t)}(t=1,2,\cdots,\mathcal T') y(t)(t=1,2,,T)的每一个时刻中,都需要对原始的原始的输入数据 X \mathcal X X进行读取,并生成 Context \text{Context} Context向量 C \mathcal C C
这里描述的重点是:每生成一个 y ( t ) y^{(t)} y(t),都要重新从 Encoder \text{Encoder} Encoder中生成一遍 C \mathcal C C,再对 y ( t ) y^{(t)} y(t)进行翻译。

遗忘问题:但是这个过程的问题在于:由于循环神经网络梯度消失的问题,导致我们从 X \mathcal X X学习的 C \mathcal C C并不准确。这种不准确主要体现在: C \mathcal C C X \mathcal X X初始时刻信息存在遗忘现象

  • 由于梯度消失,导致 C \mathcal C C仅能有效地描述最后‘若干个’时刻的序列信息,对 X \mathcal X X初始时刻的序列信息,它并不能有效地记忆——长距离依赖问题。
  • 我们不否认 LSTM , GRU \text{LSTM},\text{GRU} LSTM,GRU能够缓解这种问题,以 GRU \text{GRU} GRU为例。以时间、空间复杂度的代价,通过‘路径’量的堆积以及‘更新门、重置门’结构的调节,使其有更多的可能将梯度传递给更深(更初始)的时刻。但是随着序列的增长,每一条路径的‘梯度消失现象’是客观存在的。

基于这种现象,可能导致:翻译出来的句子结果仅与 X \mathcal X X后半段信息存在更多关联

对齐问题:在正常的翻译逻辑中,翻译结果与被翻译句子之间,某些词之间存在映射关系。例如:
中文:早上好
英文: Good morning \text{Good morning} Good morning.
很明显,有:
早上 ⇒ morning \Rightarrow \text{morning} morning;
⇒ good \Rightarrow \text{good} good.
但是在 Context \text{Context} Context向量 C \mathcal C C作为解码器的输入,并不能很好地描述这个映射关系。换句话说:由于 C \mathcal C C仅仅描述的是最终时刻的序列信息,如果 C \mathcal C C描述的是早上好这句话的序列信息,无法将早上这两个词从 C \mathcal C C中挑选出来
相当于这个‘固定大小的序列向量’ Context \text{Context} Context将每个词在句子中的序列信息‘混在一起’,单个词相关的序列信息无法‘单独拎出来’。

注意力机制处理上述两种问题

我们基于序列数据 X \mathcal X X学习到的序列信息,如何避免上述两种情况 ? ? ?
一种直观的想法是:在学习过程中,将每一时刻的序列信息 h ( t ) ( t = 1 , 2 , ⋯   , T ) h^{(t)}(t=1,2,\cdots,\mathcal T) h(t)(t=1,2,,T)都存储下来
x ( t ) → h ( t ) ⇒ X → H = ( h ( 1 ) , h ( 2 ) , ⋯   , h ( T ) ) T x^{(t)} \rightarrow h^{(t)} \Rightarrow \mathcal X \rightarrow \mathcal H = (h^{(1)},h^{(2)},\cdots,h^{(\mathcal T)})^T x(t)h(t)XH=(h(1),h(2),,h(T))T
此时在解码过程中不再使用最终 T \mathcal T T时刻序列信息作为 Context \text{Context} Context向量 C \mathcal C C了,因为上述两种问题 C \mathcal C C无法解决。随之而来的是各时刻序列信息组成的矩阵 H \mathcal H H,新的问题随之出现:如何使用 H \mathcal H H取描述/确定 Context \text{Context} Context向量 C ? \mathcal C ? C?

例如如下的翻译例子:
中文:我 是 一名 演员
期望的翻译结果
英文: I am an actor \text{I am an actor} I am an actor.

首先观察 am \text{am} am这个词,它在编码前的中文对应的这个词,也就是说:这个词对翻译结果 am \text{am} am的作用很大。另一个问题:翻译结果为 am \text{am} am,对这个翻译结果产生贡献的仅仅只有[]这一个词吗 ? ? ?

在这里明显不是。 am \text{am} am在英语中是 be \text{be} be动词的一种,一般用来表示[]这个意思, be \text{be} be动词有好多种( am,is,are,was,were , ⋯ \text{am,is,are,was,were},\cdots am,is,are,was,were,),为什么这里要选择 am ? \text{am}? am?因为:输入的序列数据 X \mathcal X X中是第一人称——[]

假设从重要程度的角度观察,翻译结果 am \text{am} am关于输入序列数据 X \mathcal X X中各词的重要程度表示如下:
这里的‘重要程度’ 0.3 , 0.7 0.3,0.7 0.3,0.7是假设的结果。

输入序列数据关于翻译结果的重要程度
这仅仅是从句子逻辑的角度考虑的,那换成向量 ? ? ?由于 h ( 1 ) , h ( 2 ) , ⋯ h ( T ) ∈ H h^{(1)},h^{(2)},\cdots h^{(\mathcal T)} \in \mathcal H h(1),h(2),h(T)H中, h ( t ) h^{(t)} h(t)所包含的序列信息也包含前面 t − 1 t-1 t1个时刻的序列信息,只不过因遗忘的因素存在, t t t越来越大,初始时刻保留的信息越来越少而已。将上述信息用向量进行表示,具体的重要程度分布表示如下:
这里比例设置得可能不太平衡,这仅是一个示例。

序列信息关于翻译结果的重要程度——示例
至此,可以认为:解码器预测的结果是基于编码器各时刻隐状态的共同结果,只不过不同隐状态对应的权重比率不同而已。从而针对这些向量进行加权求和
C 2 = C am ⇒ 0.2 ∗ h ( 1 ) + 0.7 ∗ h ( 2 ) + 0.05 ∗ h ( 3 ) + 0.03 ∗ h ( 4 ) + 0.02 ∗ h ( 5 ) \mathcal C_2 = \mathcal C_{\text{am}} \Rightarrow 0.2 * h^{(1)} + 0.7 * h^{(2)} + 0.05 * h^{(3)} + 0.03 * h^{(4)} + 0.02 * h^{(5)} C2=Cam0.2h(1)+0.7h(2)+0.05h(3)+0.03h(4)+0.02h(5)
这种基于加权求解解码器输出的方式相比于之前之前所有输出均基于 Context \text{Context} Context向量 C \mathcal C C的方式而言,能够得到更有注意力偏向的结果。
这里同样可以例举一个 an \text{an} an的例子。 an \text{an} an是不定冠词,为什么不选择 a \text{a} a而是选择 an \text{an} an——很明显,其后面第一个词是 actor \text{actor} actor,开头是元音字母。因此 an \text{an} an的生成从句子角度观察与[一名],[演员]两个词都有关联关系,这里就不展开描述了。

两者最明显的区别在于:每一个词均有不同的注意力偏向,即不同的 Context \text{Context} Context向量与其对应 ( C 1 , C 2 , ⋯   ) (\mathcal C_1,\mathcal C_2,\cdots) (C1,C2,)。从而不再共用同一个 Context \text{Context} Context向量 C \mathcal C C
这里两种方式做一个比对。
{ y ( 1 ) = f ( C ) y ( 2 ) = f ( y ( 1 ) , C ) y ( 3 ) = f ( y ( 1 ) , y ( 2 ) , C ) ⋮ ⟺ { y ( 1 ) = f ( C 1 ) y ( 2 ) = f ( y ( 1 ) , C 2 ) y ( 3 ) = f ( y ( 1 ) , y ( 2 ) , C 3 ) ⋮ \begin{aligned} \begin{cases} y^{(1)} & = f(\mathcal C) \\ y^{(2)} & = f(y^{(1)},\mathcal C) \\ y^{(3)} & = f(y^{(1)},y^{(2)},\mathcal C) \\ & \vdots \\ \end{cases} \Longleftrightarrow \begin{cases} y^{(1)} & = f(\mathcal C_1) \\ y^{(2)} & = f(y^{(1)},\mathcal C_2) \\ y^{(3)} & = f(y^{(1)},y^{(2)},\mathcal C_3) \\ & \vdots \\ \end{cases} \end{aligned} y(1)y(2)y(3)=f(C)=f(y(1),C)=f(y(1),y(2),C) y(1)y(2)y(3)=f(C1)=f(y(1),C2)=f(y(1),y(2),C3)

权重系数求解

针对上面描述,我们确定了针对不同的解码输出,从而对编码部分构建不同的注意力偏向。问题在于:这个偏向,也就是各时刻序列信息的权重系数/权重比例如何求解:

依然以上面的我 是 一名 演员 。 ⇒ I am an actor . \Rightarrow \text{I am an actor .} I am an actor .为例。假设 t = 2 t=2 t=2时刻要预测 am \text{am} am这个单词,如何给原始各时刻的序列信息 h ( 1 ) , h ( 2 ) , h ( 3 ) , h ( 4 ) , h ( 5 ) h^{(1)},h^{(2)},h^{(3)},h^{(4)},h^{(5)} h(1),h(2),h(3),h(4),h(5)分配权重 ? ? ?

一种朴素的想法:

  • 在解码过程的 t ( t = 1 , 2 , ⋯   , T ′ ) t(t=1,2,\cdots,\mathcal T') t(t=1,2,,T)时刻,选择该时刻的一个向量 Q t \mathcal Q_t Qt
  • Q t \mathcal Q_t Qt分别与编码器各时刻的序列信息 h ( i ) ( i = 1 , 2 , ⋯   , T ) h^{(i)}(i=1,2,\cdots,\mathcal T) h(i)(i=1,2,,T)进行比较,计算它们之间的相似度结果 Score ( Q t , h ( i ) ) \text{Score}(\mathcal Q_t,h^{(i)}) Score(Qt,h(i)),相似度高的 Score \text{Score} Score数值更大;
  • 最终将个 Score \text{Score} Score结果做一个归一化操作即可。

基于这种想法,关于解码器 t t t时刻,此时 y ( t ) y^{(t)} y(t)还没有被预测出来,那么选择哪一个向量作为 Q t \mathcal Q_t Qt h ( i ) ( i = 1 , 2 , ⋯   , T ) h^{(i)}(i=1,2,\cdots,\mathcal T) h(i)(i=1,2,,T)进行比较呢 ? ? ?

两种思路:

  • 解码器中当前 t t t时刻的上一时刻( t − 1 t-1 t1)的隐状态 h D ; t − 1 h_{\mathcal D;t-1} hD;t1作为 Q t \mathcal Q_t Qt
  • 解码器中当前 t t t时刻的隐状态 h D ; t h_{\mathcal D;t} hD;t作为 Q t \mathcal Q_t Qt

无论 Q t \mathcal Q_t Qt使用哪种选择方式,都被称作查询向量 ( Query ) (\text{Query}) (Query)。这里首先介绍 Score ( Q t , h ( i ) ) \text{Score}(\mathcal Q_t,h^{(i)}) Score(Qt,h(i))的计算方式。

Score \text{Score} Score函数的计算方式

计算两向量之间的相似度,最先想到的就是余弦相似度 ( Cosine Similarity ) (\text{Cosine Similarity}) (Cosine Similarity)。具体做法就是两向量之间做内积
M T N = ( m 1 , m 2 , ⋯ m k ) ( n 1 n 2 ⋮ n k ) = m 1 n 1 + m 2 n 2 + ⋯ + m k n k M , N ∈ R k × 1 \mathcal M^T\mathcal N = (m_1,m_2,\cdots m_k) \begin{pmatrix} n_1 \\ n_2 \\ \vdots \\ n_k \end{pmatrix} = m_1n_1 + m_2n_2 + \cdots + m_kn_k \quad \mathcal M,\mathcal N \in \mathbb R^{k \times 1} MTN=(m1,m2,mk) n1n2nk =m1n1+m2n2++mknkM,NRk×1
内积数值越大,意味着两向量的相似性程度越高;我们仅需要将解码器产生的查询向量 Q t \mathcal Q_t Qt(例如: h D ; t h_{\mathcal D;t} hD;t)与编码器各时刻产生的序列信息 h ( i ) ( i = 1 , 2 , ⋯   , T ) h^{(i)}(i=1,2,\cdots,\mathcal T) h(i)(i=1,2,,T)进行内积即可。

但这种操作的问题在于:需要 Q t \mathcal Q_t Qt h ( i ) h^{(i)} h(i)之间的张量格式相同,否则无法执行内积。这里的张量格式具体指什么 ? ? ?不可否认的是: Seq2seq \text{Seq2seq} Seq2seq模型结构中的 Encoder \text{Encoder} Encoder Decoder \text{Decoder} Decoder是两个独立的循环神经网络结构。这里以单层 GRU \text{GRU} GRU神经网络为例:

已知某 Batch \text{Batch} Batch的数据格式为: [ 100 , 10 , 8 ] [100,10,8] [100,10,8]。其中:

  • 100 100 100表示 BatchSize \text{BatchSize} BatchSize大小;
  • 10 10 10表示文本的序列长度
  • 8 8 8表示每个词的 Embedding \text{Embedding} Embedding维数;

关于 GRU \text{GRU} GRU的参数描述: EmbedSize = 8 \text{EmbedSize = 8} EmbedSize = 8;就是词语 Embedding \text{Embedding} Embedding维数; NumHiddens= 16 \text{NumHiddens= 16} NumHiddens= 16;(这里随意选择的值)表示神经元个数,但是这个参数和输出的序列长度,或者是 RNN \text{RNN} RNN循环次数之间没有任何关系

Seq2seq \text{Seq2seq} Seq2seq基本介绍中提到过,循环神经网络输入与输出的序列长度相同。这也是它无法直接做机器翻译的弊端。同理, NumLayers = 2 \text{NumLayers = 2} NumLayers = 2表示如果是深度循环神经网络,该参数描述神经网络堆叠的层数。观察上述格式数据,进入 GRU \text{GRU} GRU网络后的输出结果:

import torch
from torch import nn as nn

BatchSize = 100
SeqLength = 10
EmbedSize = 8
NumHiddens = 16
NumLayers = 2

x = torch.randn(BatchSize,SeqLength,EmbedSize).permute(1,0,2)
RNN = nn.GRU(EmbedSize,NumHiddens,NumLayers)
Output,State = RNN(x)
print(x.shape)
print(Output.shape,State.shape)

返回结果如下:

torch.Size([10, 100, 8])
torch.Size([10, 100, 16]) torch.Size([2, 100, 16])

可以看出,关于单个时刻的序列信息 State \text{State} State,影响它格式的有 NumLayers,NumHiddens \text{NumLayers,NumHiddens} NumLayers,NumHiddens,但绝对不会有序列长度相关的信息进行影响。
为什么要强调这个~是因为视频中存在一些偶然情况,导致理解错误。
由于是两个独立的循环结构,不同的网络参数也会影响各自 State \text{State} State输出的张量格式,从而导致无法直接求解内积。

这里介绍两种解决方式:

  • 既然 Q t \mathcal Q_t Qt h ( i ) h^{(i)} h(i)之间的张量格式不匹配,通过乘以一个参数矩阵 W Q t \mathcal W_{\mathcal Q_t} WQt,从而使他们的格式匹配,从而进行内积。例如:
    为简化起见,仅使用一个样本进行描述。即 BatchSize=1 \text{BatchSize=1} BatchSize=1并消掉维度;并且 NumLayers = 1 \text{NumLayers = 1} NumLayers = 1,主要观察 NumHiddens \text{NumHiddens} NumHiddens之间的区别。其中 N E n \mathcal N_{En} NEn表示编码器 Encoder \text{Encoder} Encoder NumLayers \text{NumLayers} NumLayers; N D e \mathcal N_{De} NDe表示 Decoder \text{Decoder} Decoder NumLayers \text{NumLayers} NumLayers
    { Q t ∈ R N E n × 1 , h ( i ) ∈ R N D e × 1 W Q t ∈ R N E n × N D e ⇒ [ W Q t ] T Q t ∈ R N D e × 1 \begin{cases} \mathcal Q_t \in \mathbb R^{\mathcal N_{En} \times 1},h^{(i)} \in \mathbb R^{\mathcal N_{De} \times 1} \\ \mathcal W_{\mathcal Q_t} \in \mathbb R^{\mathcal N_{En} \times \mathcal N_{De}}\Rightarrow [\mathcal W_{\mathcal Q_t}]^T \mathcal Q_t \in \mathbb R^{\mathcal N_{De} \times 1} \end{cases} {QtRNEn×1,h(i)RNDe×1WQtRNEn×NDe[WQt]TQtRNDe×1
    降维中介绍过,这实际上就是一种‘特征转换’:将原始向量(未丢失信息)从当前特征空间映射到高维/低维特征空间。基于映射情况来调整 W Q t \mathcal W_{\mathcal Q_t} WQt内向量间的关系。
    最终的内积结果可表示为如下形式:该结果就是编码器 t t t时刻的序列信息 Q t \mathcal Q_t Qt解码器 i i i时刻的生成序列信息 h ( i ) h^{(i)} h(i)相似度结果
    Score ( Q t , h ( i ) ) = [ [ W Q t ] T Q t ] T h ( i ) = [ Q t ] T W Q t h ( i ) \text{Score}(\mathcal Q_t,h^{(i)})= \left[[\mathcal W_{\mathcal Q_t}]^T \mathcal Q_t\right]^T h^{(i)} = [\mathcal Q_t]^T \mathcal W_{\mathcal Q_t} h^{(i)} Score(Qt,h(i))=[[WQt]TQt]Th(i)=[Qt]TWQth(i)
  • 另一种方式就是构建神经网络。将两向量拼接 ( Concatenate ) (\text{Concatenate}) (Concatenate)在一起作为神经网络的输入信息;根据神经网络的通用逼近定理 ( Universal Approximation Theorem ) (\text{Universal Approximation Theorem}) (Universal Approximation Theorem),使其结果返回 Score \text{Score} Score作为输出。
    需要训练的参数就是神经网络中神经元对应的权重信息。

两种方式的主要区别在于:

  • 内积方法是从余弦相似度的角度出发,虽然中间使用 W \mathcal W W执行特征转换,但其结果依然可以表达 Q t \mathcal Q_t Qt h ( i ) h^{(i)} h(i)之间的相关关系
  • 神经网络方法则全权交给通用逼近定理了,无法体现出 Q t \mathcal Q_t Qt h ( i ) h^{(i)} h(i)之间的相关关系

相关参考:
seq2seq与attention机制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/630558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python怎么从列表里随机抽取?

Python怎么从列表里随机抽取? 在编程中,我们常常需要从一个列表里面随机抽取一个元素来进行一些操作,比如说在一个游戏中随机抽取一个怪物来进行战斗。Python提供了一个内置模块——random模块,用于生成随机数。这个模块可以帮助…

(数组) 1207. 独一无二的出现次数 ——【Leetcode每日一题】

❓1207. 独一无二的出现次数 难度:简单 给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数。 如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false。 示例 1: 输入:arr [1,2,2,1,…

做一个比较有意思的条目选择动画 css

做一个比较有意思的条目选择动画 css 效果 如何实现 原理就是将母元素设置成 relative 然后在四边放四个 absolute 的色块。 初始状态是opacity 为 0 的&#xff0c;当母元素 hover 的时候&#xff0c;将四个边角色块设置 opacity: 1 并偏移指定量。 html <div class&qu…

English Learning - L3 作业打卡 Lesson5 Day32 2023.6.5 周一

English Learning - L3 作业打卡 Lesson5 Day32 2023.6.5 周一 引言&#x1f349;句1: What do you read when you are travelling by train or bus?成分划分弱读爆破语调 &#x1f349;句2: What are other passengers reading?成分划分弱读连读语调 &#x1f349;句3: Perh…

软考A计划-系统架构师-官方考试指定教程-(15/15)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

规则引擎--QLExpress:普通表达式的运行

目录 QLExpress普通表达式执行解析并转化为ExpressNode语法解析,得到如下的语法树根据 ExpressNode 树生成指令树执行指令树得到结果InstructionConstData 的指令执行InstructionOperator的指令执行 最后得到结果 再看一个in表达式设置参数的执行 QLExpress github: https://g…

【matlab】matlab算法封装成工具包提供给程序调用

说明&#xff1a; 1、非进程通讯协议&#xff0c;无需在电脑上安装完整版的matlab开发环境。 2、本项目以C#为案例&#xff0c;调用的语言不限&#xff0c;操作流程基本相同。 一、准备工作 1、安装MATLABWebAppServerSetup集成开发环境 2、安装Visual stdio 2017集成开发环…

Openharmony添加编译自己应用

介绍一下Openharmony如何在庞大的编译构建系统中&#xff0c;增添自己想编译的内容。不定期更新~&#x1f438; gn官方文档&#xff1a; https://gn.googlesource.com/gn//main/docs/quick_start.md https://gn.googlesource.com/gn//master/docs/reference.md openharmony官…

Salesforce退出市场后类似的CRM系统有哪些

Salesforce退出中国市场后&#xff0c;对很多使用Salesforce的国内企业来说是一个不小的打击。他们需要寻找与Salesforce功能相当、具有良好口碑的CRM客户管理系统来替代。本文就为大家推荐五款类似Salesforce的CRM系统。 1、Zoho CRM Zoho CRM是一款SaaS云端CRM系统&#xf…

005: vue中el-upload 组件添加token的方法

第005个 查看专栏目录: 按照VUE知识点 ------ 按照element UI知识点 echarts&#xff0c;openlayers&#xff0c;cesium&#xff0c;leaflet&#xff0c;mapbox&#xff0c;d3&#xff0c;canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏…

谈谈嵌入式开发中签名校验和加解密作用的理解

1、前言 本博文不是讲解可信加签和固件加密的具体原理&#xff0c;而是谈谈实际嵌入式开发中&#xff0c;可信加签和固件加密的应用场景&#xff0c;可以帮助从事嵌入式开发的人员快速理解加签和加密的作用。 2、嵌入式开发中可信加签和固件加密介绍 (1)各家公司都有自己的可信…

操作受限的线性表——栈

本文主要内容&#xff1a;本文主要讲解栈的基本概念、基本操作和栈的顺序、链式实现。 目录 栈一、栈的基本概念1、基本概念2、基本操作 二、栈的顺序存储结构1、顺序栈的实现2、顺序栈的基本运算1&#xff09;初始化2&#xff09;判栈空3&#xff09;进栈4&#xff09;出栈5&a…

【环境配置】C/C++第三方库管理工具vcpkg安装和使用

一&#xff0c;vcpkg简介 vcpkg是微软公司开发的一个开源C包管理工具&#xff0c;它可以很方便的帮助您在 Windows、 Linux 和 MacOS 上下载&#xff0c;编译和安装C 第三方库。它具有自动解决依赖关系的能力&#xff0c;并且支持多种目标架构和平台。提供了超过1500个C库的预…

【Ubuntu系统内核更新与卸载】

【Ubuntu系统内核更新与卸载】 1. 前言2. 内核安装2.1 系统更新2.2 官网下载 3. 内核卸载3.1 需求分析3.2 卸载方法 1. 前言 我们在搭建环境时常常遇到内核版本不匹配的问题&#xff0c;需要我们安装新的内核版本&#xff1b;有时又会遇到在安装软件时报错boot空间已满无法安装…

Python爬取影评并进行情感分析和数据可视化

Python爬取影评并进行情感分析和数据可视化 文章目录 Python爬取影评并进行情感分析和数据可视化一、引言二、使用requestsBeautifulSoup进行影评的爬取1、分析界面元素2、编写代码 三、情感分析1、数据预处理2、情感分析3、数据可视化 一、引言 前几天出了《航海王&#xff1…

N - Cthulhu

第三次题组 [Cloned] - Virtual Judge (vjudge.net) 【题目描述】 一个具有 n 个顶点和 m 条边的无向图。现在&#xff0c;世界上最好的头脑即将确定这张图是否可以被视为克苏鲁。 为了简单起见&#xff0c;让我们假设克苏鲁从空间里看起来就像一个附有触手的球形身体。从形式…

sqlserver存储过程中使用临时表的问题

2023年6月6日08:52:15 因为最近接触的his系统一些存储过程做数据统计&#xff0c;一个存储过程就要使用1-3个临时表&#xff0c;这些存储过程是零几年的写得&#xff0c;和我们这个时代的写的存储过程习惯不太一样&#xff0c;就好奇为什么要使用这么多的临时表 临时表的基本概…

结构型设计模式05-组合模式

&#x1f9d1;‍&#x1f4bb;作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 组合模式 1、组合模式介绍 组合模式&#xff08;Composite Pattern&#xff09;&#xff0c;又叫部分…

Generator-Evaluator重排模型在淘宝流式场景的实践

除了相关性&#xff0c;复杂信息流推荐场景还需要兼顾多样的业务需求&#xff0c;包括打散&#xff08;多样性&#xff09;&#xff0c;流量调控&#xff0c;多展示形态/多路供给融合等。传统推荐系统采用pipeline的形式&#xff0c;分步处理上述需求&#xff0c;缺少统筹优化&…

【博客650】irate适用于绘制细粒度灵敏图,但警惕用于告警

irate适用于绘制细粒度灵敏图&#xff0c;但警惕用于告警 1、irate解析 作用&#xff1a; irate(v range-vector) 函数用于计算区间向量的增长率&#xff0c;但是其反应出的是瞬时增长率。 原理&#xff1a; irate 函数是通过区间向量中最后两个两本数据来计算区间向量的增长…