NLP进阶之(一)Seq2Seq模型之Chatbot

1. 编码器—解码器(seq2seq)

NLP之前的章节中处理并分析了不定长的输入序列。但在很多应用中,输入和输出都可以是不定长序列。以机器翻译为例,输入可以是一段不定长的问题文本序列,输出可以是一段不定长的回答文本序列,例如

有 , 现在 我 在 努力学习 英文 , 我 想 成为 一名 翻译 。 嗯 , 你 是 大有 前途 的 。 追逐 你 的 梦想 , 永不 放弃 。

问题输入:“现在”、“我”、“在”、“努力学习”、“英文”、“,”、“我”、“想”、“成为”、“一名”、“翻译”、“。”

回输出:“嗯”、“,”、“你”、“是”、“大有”、“前途”、“的”、“。”、“追逐”、“你”、“的”、“梦想”、“,”、“永不”、“放弃”、“。”

解释

当输入输出都是不定长序列时,我们可以使用编码器—解码器(encoder-decoder)[1] 或者 seq2seq 模型 [2]。这两个模型本质上都用到了两个循环神经网络,分别叫做编码器和解码器。编码器用来分析输入序列,解码器用来生成输出序列。在训练数据集中,我们可以在每个句子后附上特殊符号“<eos>”(end of sequence)表示序列的终止。编码器每个时间步的输入依次为问题句子中的单词、标点和特殊符号“<eos>”。解码器在各个时间步中使用输入句子的编码信息和上个时间步的输出以及隐藏状态作为输入。
我们希望解码器在各个时间步能正确依次输出翻译后的问题单词、标点和特殊符号“<eos>”。
需要注意的是,解码器在最初时间步的输入用到了一个表示序列开始的特殊符号“<bos>”(beginning of sequence)。

接下来我们分别介绍编码器和解码器的定义。

1.1 编码器

编码器的作用是把一个不定长的输入序列变换成一个定长的背景变量 c \boldsymbol{c} c,并在该背景变量中编码输入序列信息。常用的编码器是循环神经网络。

让我们考虑批量大小为 1 的时序数据样本。假设输入序列是 x 1 , … , x T x_1,\ldots,x_T x1,,xT,例如 x i x_i xi 是输入句子中的第 i i i 个词。在时间步 t t t,循环神经网络将输入 x t x_t xt 的特征向量 x t \boldsymbol{x}_t xt 和上个时间步的隐藏状态 h t − 1 \boldsymbol{h}_{t-1} ht1 变换为当前时间步的隐藏状态 h t \boldsymbol{h}_t ht。我们可以用函数 f f f 表达循环神经网络隐藏层的变换:
h t = f ( x t , h t − 1 ) . \boldsymbol{h}_t = f(\boldsymbol{x}_t, \boldsymbol{h}_{t-1}). ht=f(xt,ht1).

接下来编码器通过自定义函数 q q q 将各个时间步的隐藏状态变换为背景变量

c = q ( h 1 , … , h T ) . \boldsymbol{c} = q(\boldsymbol{h}_1, \ldots, \boldsymbol{h}_T). c=q(h1,,hT).

例如,当选择 q ( h 1 , … , h T ) = h T q(\boldsymbol{h}_1, \ldots, \boldsymbol{h}_T) = \boldsymbol{h}_T q(h1,,hT)=hT 时,背景变量是输入序列最终时间步的隐藏状态 h T \boldsymbol{h}_T hT。以上描述的编码器是一个单向的循环神经网络,每个时间步的隐藏状态只取决于该时间步及之前的输入子序列。我们也可以使用双向循环神经网络构造编码器。这种情况下,编码器每个时间步的隐藏状态同时取决于该时间步之前和之后的子序列(包括当前时间步的输入),并编码了整个序列的信息。

1.2 解码器

刚刚已经介绍,编码器输出的背景变量 c \boldsymbol{c} c 编码了整个输入序列 x 1 , … , x T x_1, \ldots, x_T x1,,xT 的信息。给定训练样本中的输出序列 y 1 , y 2 , … , y T ′ y_1, y_2, \ldots, y_{T&#x27;} y1,y2,,yT,对每个时间步 t ′ t&#x27; t(符号与输入序列或编码器的时间步 t t t 有区别),解码器输出 y t ′ y_{t&#x27;} yt 的条件概率将基于之前的输出序列 y 1 , … , y t ′ − 1 y_1,\ldots,y_{t&#x27;-1} y1,,yt1 和背景变量 c \boldsymbol{c} c,即 P ( y t ′ ∣ y 1 , … , y t ′ − 1 , c ) \mathbb{P}(y_{t&#x27;} \mid y_1, \ldots, y_{t&#x27;-1}, \boldsymbol{c}) P(yty1,,yt1,c)

为此,我们可以使用另一个循环神经网络作为解码器。在输出序列的时间步 t ′ t^\prime t,解码器将上一时间步的输出 y t ′ − 1 y_{t^\prime-1} yt1 以及背景变量 c \boldsymbol{c} c 作为输入,并将它们与上一时间步的隐藏状态 s t ′ − 1 \boldsymbol{s}_{t^\prime-1} st1 变换为当前时间步的隐藏状态 s t ′ \boldsymbol{s}_{t^\prime} st。因此,我们可以用函数 g g g 表达解码器隐藏层的变换:

s t ′ = g ( y t ′ − 1 , c , s t ′ − 1 ) . \boldsymbol{s}_{t^\prime} = g(y_{t^\prime-1}, \boldsymbol{c}, \boldsymbol{s}_{t^\prime-1}). st=g(yt1,c,s

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值