您的当前位置:首页正文

Seq2Seq 模型详解

2024-11-08 来源:个人技术集锦

在NLP任务中,我们通常会遇到不定长的语言序列,比如机器翻译任务中,输入可能是一段不定长的英文文本,输出可能是不定长的中文或者法语序列。当遇到输入和输出都是不定长的序列时,可以使用编码器-解码器(encoder-decoder)模型或者seq2seq模型。其基本思想是编码器用来分析输入序列,解码器用来生成输出序列。

首先,来简单介绍下RNN(循环神经网络)结构:

1. RNN 结构

RNN结构

RNN中,每个单元接受两个输入,一个是当前时间步输入的信息 X t X_t Xt,另一个是上一个单元的隐藏层状态 H t − 1 H_{t-1} Ht1。为什么这种结构的RNN适合用于做文本等序列型数据的任务,主要是因为隐藏状态的存在使得模型具有记忆性。针对不同的任务,根据输入和输出的数量,通常对RNN结构进行调整。

2. Seq2Seq 模型

经过上面对几种RNN结构的分析,不难发现RNN结构大多对序列的长度比较局限,对于类似于机器翻译的任务,输入和输出长度并不对等,为N to M的结构,简单的RNN束手无策,因此便有了新的模型,Encoder-Decoder模型,也就是Seq2Seq模型。

模型一般由两部分组成:第一部分是Encoder部分,用于对输入的N长度的序列进行表征;第二部分是Decoder部分,用于将Encoder提取出的表征建立起到输出的M长度序列的映射。

1. 编码器 Encoder

  • c = h N c=h_N c=hN
  • c = f ( h N ) c=f(h_N) c=f(hN)
  • c = f ( h 1 , h 2 , ⋯   , h N ) c=f(h_1, h_2, \cdots, h_N) c=f(h1,h2,,hN)
2. 解码器 Decoder

相对于编码器而言,解码器的结构更多,下面介绍三种:

第一种

  • 隐藏状态的更新:
    h 1 ′ = σ ( W c + b 1 ) h t ′ = σ ( W h t − 1 ′ + b 1 ) \mathbf {h'_1}=\sigma(\mathbf {Wc+b_1})\\ \mathbf {h'_t}=\sigma (\mathbf{Wh'_{t-1}+b_1}) h1=σ(Wc+b1)ht=σ(Wht1+b1)
  • 输出的计算: y t ′ = σ ( V h t ′ + b 2 ) \mathbf{y'_{t}} = \sigma(\mathbf{Vh'_t+b_2}) yt=σ(Vht+b2)

第二种

  • 隐藏状态: h t ′ = σ ( U c + W h t − 1 ′ + b 1 ) \mathbf {h'_t}=\sigma(\mathbf{Uc+Wh'_{t-1}+b_1}) ht=σ(Uc+Wht1+b1)
  • 输出: y t ′ = σ ( V h ′ t + b 2 ) \mathbf{y'_{t}} =\sigma(\mathbf{Vh't+b_2}) yt=σ(Vht+b2)

第三种

  • 隐藏状态: h t ′ = σ ( U c + W h t − 1 ′ + V y t − 1 ′ + b 1 ) \mathbf{h'_t}=\sigma(\mathbf{Uc+Wh'_{t-1}+Vy'_{t-1}+b_1}) ht=σ(Uc+Wht1+Vyt1+b1)
  • 输出: y t ′ = σ ( V h t ′ + b 2 ) \mathbf{y'_{t}} =\sigma(\mathbf{Vh'_t+b_2}) yt=σ(Vht+b2)
3. Seq2Seq中的Trick
1. Teacher Forcing

主要针对第三种Decoder应用。当某一个单元输出出错时,如果将其输出传递给下一个单元,可能导致错误传递下去。这时候,需要在一定程度上减少这种传递,就采用按一定的比例决定是否对神经单元采用上一个上一个单元的输出作为输入。即:
h t ′ = I ( 采用 ) σ ( U c + W h t − 1 ′ + V y t − 1 ′ + b 1 ) + I ( 不采用 ) σ ( U c + W h t − 1 ′ + b 1 ) \mathbf{h'_t}=I(采用)\sigma(\mathbf{Uc+Wh'_{t-1}+Vy'_{t-1}+b_1})+I(不采用)\sigma(\mathbf{Uc+Wh'_{t-1}+b_1}) ht=I(采用)σ(Uc+Wht1+Vyt1+b1)+I(不采用)σ(Uc+Wht1+b1)

2. Attention 机制(很重要)

提出Attention机制之前,我们先来看下之前的结构有什么问题:

Attention 机制是怎样的?

Attention 机制其实是参考了人在翻译文章时候的注意力机制,它会将模型的注意力放在当前翻译的单词上,换句话说,它并不像前面提到的Encoder的结构一样对整个句子用一个表征,它对于每个单词都有一个以单词为中心的表征。Encoder结构如下:

  • 首先计算上一个神经元隐藏状态 h t − 1 h_{t-1} ht1与Encoder每一个神经元隐藏状态的相似度,用 e t e_t et表示。 e t = [ a ( h t − 1 ′ , h 1 ) , ⋯   , a ( h t − 1 ′ , h N ) ] e_t=[a(h'_{t-1}, h_1), \cdots, a(h'_{t-1},h_N)] et=[a(ht1,h1),,a(ht1,hN)],其中 a ( ⋅ ) a(\cdot) a()为某种相似度计算函数。
  • “集中注意力”。对以上 e t e_t et使用softmax函数,得到Decoder每个隐藏状态在处理第 t 个词的时候的“注意力” α t \alpha_{t} αt。计算得到各个上下文向量: c t = ∑ i = 1 N α t i h i c_t=\sum_{i=1}^N\alpha_{ti}h_i ct=i=1Nαtihi
  • 后面Decoder对 y 的计算与上面提到的第三种Decoder的计算方式几乎一致,区别就在于上下文向量 c 的变化。
3. 束搜索(Beam Search)

注意:Beam Search只用于测试,不用于训练过程。
当模型训练好后,给其输入一段话,其输出的每个单元的 y 给的是各个词的概率,我们如何根据概率选词且如何判断是否句子终止呢?

采取的方法是在每个时间步,选取当前时间步条件概率最大的k个词,作为该时间步的候选输出序列。如下图,k选择2,第一步p(A|c)和p(C|c)最大;第二步 P(AB|c),P(CE|c)最大;第三步P(ABD|c),P(CED|c)最大。

这样,得到的最终候选序列就是各个时间步的得到的序列的集合,下图种即为6个 {A, C, AB, CE, ABD, CED}。那么最终预测结果就是要从这6个中选出分最高的。这时候,可能有小伙伴会发现,那按概率算的话,序列越长的概率肯定越小呀,所以一般最后分数计算会有一个和序列长度有关的惩罚系数,如下:
1 L α log ⁡ P ( y 1 , y 2 , ⋯   , y L ) = 1 L α ∑ t ′ = 1 L log ⁡ P ( y t ′ ∣ y 1 , ⋯   , y t ′ − 1 , c ) \frac{1}{L^\alpha}\log P(y_1,y_2,\cdots, y_L)=\frac{1}{L^\alpha} \sum_{t'=1}^L\log P(y_{t'}|y_1, \cdots, y_{t'-1}, c) Lα1logP(y1,y2,,yL)=Lα1t=1LlogP(yty1,,yt1,c)

其中L为候选序列的长度, α \alpha α 一般选0.75. 这样一来,序列长的对应的系数更小,而由于取了对数,概率的对数是负数,如此变化后会使得长序列和短序列处于一个可比的情形。

显示全文