基于问答对的chatbot我们已经讨论过,不过,这种简单的模型用来玩玩是可以的,真要是更强的场景是不适用的,因为实际场景中,我们的对话轮次是多轮的,比如下面的对话场景:
…
上面的场景需要多次的对话才能确定意图,其意图的确定也是有依赖关系的,而简单的问答对则显然不会捕捉到这种依赖关系,所以其表达能力也弱。
现在,是时候进入更高层次的chatbot中了!
多轮对话聊天机器人,作为人工智能的典型应用场景,也是一项极具挑战的任务,不仅涉及多方面异构知识的表示、抽取、推理和应用(如语言知识、领域知识、常识知识等),**还涉及包括自然语言理解在内的其他人工智能核心技术(如用户画像、对话管理等)的综合利用,**所以还是比较复杂的。
该模型提出于2015年,基于seq2seq而有超脱于seq2seq。
回忆一下普通的seq2seq的特点,
对于这种encoder-decoder结构,由于其encoder的串行特点,要用来建模多轮对话的话,只能通过将句子依次输入,并用前个句子的final state作为下个句子的init state来实现多轮会话的处理,通过这种方式,将句子信息不断传递下去,这样的话 context vector 里的信息会在 propagation 的过程中会被新句子的词语逐步稀释,对信息/梯度的传播极不友好;或者采用更好一点的做法,将每个句子的final state进行拼接或者某种非线性处理,依次实现信息的揉合。然而,不论怎么样,都没有很好的捕获到句子间的时序关系。
这时候,看到句子间的时序关系,你看到了什么?没错,就是关键的“时序”两个字,我们该想到,既然句子是短语的时序组合,而会话是句子的时序组合,那么如果可以用RNN建模句子,那么同样用RNN建模会话也是自然而然的吧?基于这种想法,HERD应运而生。
上图便是HERD的流程,相比于只有单个encoder-decoder的seq2seq结构,该模型引入了一个被称为context encoder的中间层,通过该层实现对句子级的建模,具体做法是:
encoder RNN
该encoder就是seq2seq中的encoder,用来对单个句子进行建模,其建模出的向量被称为utterance vector,它也是该encoder的 last hidden state,这个encoder记忆的是句子的细节。
context RNN
n个句子的会话级建模,其输入是n个句子的utterance vector,通过该RNN实现了对句子间时序的建模。该RNN的hidden会作为decoder的init hidden
decoder RNN
通过接受context RNN的hidden来对当前句子进行建模,这时候的hidden不仅包括了句子级的信息,也包括了会话的时序信息。
应该说该模型的想法还是挺不错的,它能够丰富编码信息,使得编码信息不仅仅包含当前输入句子的语义信息,还包含了历史输入句子的语义信息,这种丰富的上下文编码信息对解码器来说更能准确地解码出相应的response。不过 实际来看,效果并没有超过传统的seq2seq多少。
RNNLM和HERD,以及其他基于RNN结构的模型,在生成有意义的会话方面存在比较严重的问题,VHERD(variable hierarchical recurrent encoder-decoder)作者认为这个问题的根源在于对于输出分布的参数化过程,因为这个过程会生成过程施加一个强约束:唯一的变化来源是通过条件输出分布来建模(the only source of variation is modelled through the conditional output distribution.),而这从两个方面来说是不利的:
注解:作者这里写的十分理论,我的理解是模型产生的输出是通过decoder来建模的,而decoder在输出第一个token以后,其后续的输出都是已经确定的了(因为参数已经固化了),那么增加多样性的一个方法就是噪音来扩大input在语义空间的范围,比如针对一个句子“你好啊”,如果不加噪音,那么通过encoder编码以后,如果直接decoder,这时该句子便对应了语义空间的一个点,添加噪音以后,由于强迫decoder从一定波动范围内还原encoder,所以这时候该句子便被编码为了一段范围,这样的话就大大缓解了数据的稀疏性,有利于生成多样性的句子。不过这个噪音如果添加的比较低层,比如word层面,那么由于模型本身被强约束于与输出word一致,模型便会倾向于捕捉局部结构,对于整体结构的约束便不是那么强。
从上面的讨论中,作者提出了一种新的结构,叫做Latent Variable Hierarchical Recurrent Encoder-Decoder (VHRED),VHRED 针对上面的问题引入了全局(语义层面)的随机因素,一是能增强模型的 robustness,二是能捕捉 high level concepts。Latent variable 使得 response 不再和一个/几个固定的句子绑定,鼓励了回复的多样性。它的主要流程包括两步:
随机采样latent variables
这是论文的核心,其思想来自于VAE。在VAE领域,其目标专注于通过隐变量来生成目标数据,其最初应用于图像领域,可以通过采样的方式生成多种多样的图像。
VAE的推导略微复杂,不过其思想却十分精妙,大概可以分为以下的步骤来理解:
生成输出序列
注意上图的prior parameterization和posterior parameterization,在VHRED模型中,在测试时,不存在当前时间步的sentence,使用prior parameterization来采样z;在训练的时候,需要聚合更多的信息来辅助训练,使用posterior parameterization来采样z。
t e s t : P θ ( z n ∣ w 1 , . . . , w n − 1 ) = N ( μ p r i o r ( w 1 , . . . , w n − 1 ) , ∑ p r i o r ( w 1 , . . . , w n − 1 ) ) test: P_{\theta }(z_{n}|w_{1},...,w_{n-1})=N(\mu_{prior}(w_{1},...,w_{n-1}),\sum_{prior}(w_{1},...,w_{n-1})) test:Pθ(zn∣w1,...,wn−1)=N(μprior(w1,...,wn−1),prior∑(w1,...,wn−1))
t r a i n : P θ ( z n ∣ w 1 , . . . , w n ) = N ( μ p o s t e r i o r ( w 1 , . . . , w n ) , ∑ p o s t e r i o r ( w 1 , . . . , w n ) ) train: P_{\theta }(z_{n}|w_{1},...,w_{n})=N(\mu_{posterior}(w_{1},...,w_{n}),\sum_{posterior}(w_{1},...,w_{n})) train:Pθ(zn∣w1,...,wn)=N(μposterior(w1,...,wn),posterior∑(w1,...,wn))
通过上面的采样以后,将其与context RNN的输出进行cat来生成decoder的initial hidden来解码,后续的过程就是普通的RNN操作了。
公式流程为:
h t − 1 e n c = f θ e n c ( x t − 1 ) h_{t-1}^{enc} = f_{\theta}^{enc}(x_{t-1}) ht−1enc=fθenc(xt−1)
h t c x t = f θ c x t ( h t − 1 c x t , h t − 1 e n c ) h_{t}^{cxt} = f_{\theta}^{cxt}(h_{t-1}^{cxt},h_{t-1}^{enc}) htcxt=fθcxt(ht−1cxt,ht−1enc)
p θ ( z t u t t ∣ x < t ) = N ( z ∣ μ t , σ t I ) p_{\theta}(z_{t}^{utt}|x_{
w h e r e : μ t = M L P θ ( h t c x t ) where:\ \mu_{t}=MLP_{\theta}(h_{t}^{cxt}) where: μt=MLPθ(htcxt)
σ t = S o f t p l u s ( M L P θ ( h t c x t ) ) \sigma_{t}=Softplus(MLP_{\theta}(h_{t}^{cxt})) σt=Softplus(MLPθ(htcxt))
p θ ( x t ∣ x < t ) = f θ d e c ( x ∣ h t c x t , z t u t t ) p_{\theta}(x_{t}|x_{
其中, z t u t t z_{t}^{utt} ztutt的posterior可以用如下公式求出:
q ϕ ( z t u t t ∣ x ≤ t ) = N ( z ∣ u t ′ , σ t ′ I ) q_{\phi}(z_{t}^{utt}|x_{\leq t}) = N(z|u_{t}^{'},\sigma_{t}^{'}I) qϕ(ztutt∣x≤t)=N(z∣ut′,σt′I)
w h e r e : μ t ′ = M L P ϕ ( x t , h t c x t ) where: \mu_{t}^{'} = MLP_{\phi}(x_{t},h_{t}^{cxt}) where:μt′=MLPϕ(xt,htcxt)
σ t ′ = S o f t p l u s ( M L P ϕ ( x t , h t c x t ) ) \sigma_{t}^{'}=Softplus(MLP_{\phi}(x_{t},h_{t}^{cxt})) σt′=Softplus(MLPϕ(xt,htcxt))
从HRED到VHRED,它们的想法是美好的,不过从模型本身来看,个人感觉是不怎么样的,它们更像是基于纯研究的背景,而非基于落地的背景,因为context RNN在实际应用中要面临很多问题,比如如果确定一轮会话的终结,会话过长建模等等,所以个人而言,这些方法的实用价值并不大。
VHCR(Variational Hierarchical Conversation RNN)是提出于2018年的一篇论文,论文作者肯定了VAE在会话生成过程中的重要性,不过其也提出了VAE存在的缺陷:
VAE degeneration
VAE优化的目标函数为:
l o g p θ ( x ) ⩾ L ( θ , ϕ ; x ) = E q ϕ ( z ∣ x ) [ − l o g q ϕ ( z ∣ x ) + l o g p θ ( x , z ) ] = − D K L ( q ϕ ( z ∣ x ) ∣ ∣ p ( z ) ) + E q ϕ ( z ∣ x ) [ l o g p θ ( x ∣ z ] log p_{\theta }(x) \geqslant L(\theta ,\phi ;x)\\=E_{q_{\phi }(z|x)}[-log q_{\phi}(z|x) + log p_{\theta }(x,z)]\\=-D_{KL}(q_{\phi}(z|x)||p(z))+E_{q_{\phi}(z|x)}[log p_{\theta}(x|z] logpθ(x)⩾L(θ,ϕ;x)=Eqϕ(z∣x)[−logqϕ(z∣x)+logpθ(x,z)]=−DKL(qϕ(z∣x)∣∣p(z))+Eqϕ(z∣x)[logpθ(x∣z]
其中,各公式含义如下:
公式右侧第一项为KL散度项,如果缺失这一项,VAE就退化为普通的AE,而在优化过程中,一个容易出现的现象就是KL散度会被优化为0,这时候只有第二项的重构项,这种现象就是KL散度消失*(KL Vanishing)。发生这种现象的时候,VAE的latent space中,就不能有效接受来自encoder的信息,因为这时候有:
q ϕ ( z ∣ x ) ≃ p ( z ) = N ( μ , σ ) q_{\phi}(z|x)\simeq p(z)= N(\mu,\sigma) qϕ(z∣x)≃p(z)=N(μ,σ)
这时候的 μ \mu μ与 σ \sigma σ基本上与x脱钩,所以z*便被忽略掉了。
从公式8可以看出,context RNN也可以看作是一个高层的decoder,他和decoder RNN一起构建了一个层级的RNN decoders,层级 RNN decoders 足够强大,以至于它只使用编码输出分布来不使用latent variables来建模数据,虽然可以通过一些heuristics比如KL 退火(annealing)或者word drop regularization来缓解,不过无法完全解决。
数据稀疏性
conditional VAE结构中,一个语句的生成是以context为条件的,即之前的语句序列,这会诱发严重的数据稀疏性。即使是大规模的训练语料,当以context为条件时,也只存在很少的目标语句。因此,分层RNNs可以很容易地记忆上下文与语句之间的关系,而不依赖于latent variables,这时候,即便加上word drop regularization,不过它惩罚的只是decoder,context RNN本身也足够预测下一个utterance。
针对上面的问题,作者提出了自己的解决方案:
引入了一个全局对话latent variable以及局部语句latent variable来建立一个层次化的潜变量结构
针对一个会话 c = ( x 1 , x 2 , . . . , x n ) c=(x_{1},x_{2},...,x_{n}) c=(x1,x2,...,xn),引入全局会话latent variable z c o n v z^{conv} zconv负责生成该会话的utterances序列:
p θ ( c ∣ z c o n v ) = p θ ( x 1 , . . . , x n ∣ z c o n v ) p_{\theta}(c|z^{conv}) = p_{\theta}(x_{1},...,x_{n}|z^{conv}) pθ(c∣zconv)=pθ(x1,...,xn∣zconv)
其计算流程为:
h t e n c = f θ e n c ( x t ) h_{t}^{enc}=f_{\theta}^{enc}(x_{t}) htenc=fθenc(xt)
h t c x t = { M L P θ ( z c o n v ) i f t = 0 f θ c x t ( h t − 1 c x t , h t − 1 e n c , z c o n v ) o t h e r w i s e h_{t}^{cxt} = \begin{cases} & MLP_{\theta}(z^{conv}) \quad {if}\ t=0 \\ & f_{\theta}^{cxt}(h_{t-1}^{cxt},h_{t-1}^{enc},z^{conv}) \quad otherwise \end{cases} htcxt={MLPθ(zconv)if t=0fθcxt(ht−1cxt,ht−1enc,zconv)otherwise
p θ ( x t ∣ x < t , z u t t , z c o n v ) = f θ d e c ( x ∣ h t c x t , z t u t t , z c o n v ) p_{\theta}(x_{t}|x_{
p θ ( z c o n v ) = N ( z ∣ 0 , I ) p_{\theta}(z^{conv})=N(z|0,I) pθ(zconv)=N(z∣0,I)
p θ ( z t u t t ∣ x < t , z c o n v ) = N ( z ∣ μ t , σ t I ) p_{\theta}(z_{t}^{utt}|x_{
w h e r e : μ t = M L P θ ( h t c x t , z c o n v ) where: \mu_{t}=MLP_{\theta}(h_{t}^{cxt},z^{conv}) where:μt=MLPθ(htcxt,zconv)
σ t = S o f t l u s ( M L P θ ( h t c x t , z c o n v ) ) \sigma_{t}=Softlus(MLP_{\theta}(h_{t}^{cxt},z^{conv})) σt=Softlus(MLPθ(htcxt,zconv))
对于 z c o n v z^{conv} zconv,使用双向RNN,标记为 f c o n v f^{conv} fconv,其生成过程如下:
q ϕ ( z c o n v ∣ x 1 , . . . , x n ) = N ( z ∣ μ c o n v , σ c o n v I ) q_{\phi}(z^{conv}|x_{1},...,x_{n})=N(z|\mu^{conv},\sigma^{conv}I) qϕ(zconv∣x1,...,xn)=N(z∣μconv,σconvI)
w h e r e : h c o n v = f c o n v ( h 1 e n c , . . . h n e n c ) where: h^{conv}=f^{conv}(h_{1}^{enc},...h_{n}^{enc}) where:hconv=fconv(h1enc,...hnenc)
μ c o n v = M L P ϕ ( h c o n v ) \mu^{conv}=MLP_{\phi}(h^{conv}) μconv=MLPϕ(hconv)
σ c o n v = S o f t p l u s ( M L P ϕ ( h c o n v ) ) \sigma^{conv}=Softplus(MLP_{\phi}(h^{conv})) σconv=Softplus(MLPϕ(hconv))
对于局部变量 z t u t t z_{t}^{utt} ztutt的posteriors,其建立在 z c o n v z^{conv} zconv基础上:
q ϕ ( z t u t t ∣ x 1 , . . . , x n , z c o n v ) = N ( z ∣ μ t ′ , σ t ′ I ) q_{\phi}(z_{t}^{utt}|x_{1},...,x_{n},z^{conv})=N(z|\mu_{t}^{'},\sigma_{t}^{'}I) qϕ(ztutt∣x1,...,xn,zconv)=N(z∣μt′,σt′I)
w h e r e : μ t ′ = M L P ϕ ( x t , h t c x t , z c o n v ) where:\mu_{t}^{'}=MLP_{\phi}(x_{t},h_{t}^{cxt},z^{conv}) where:μt′=MLPϕ(xt,htcxt,zconv)
σ t ′ = S o f t p l u s ( M L P ϕ ( x t , h t c x t , z c o n v ) ) \sigma_{t}^{'}=Softplus(MLP_{\phi}(x_{t},h_{t}^{cxt},z^{conv})) σt′=Softplus(MLPϕ(xt,htcxt,zconv))
通过对比可知,此时的context RNN以及decoder RNN生成都需要建立在 z c o n v z^{conv} zconv的基础上,而 z c o n v z^{conv} zconv则综合建模了所有的utterances,其起到的作用就是全局信息,再加上 z t u t t z_{t}^{utt} ztutt本身的分布,这就构成了一种层次的latent space,这便强迫模型去利用latent space信息,又由于 z c o n v z^{conv} zconv不依赖于条件结构,即最终的输出不是仅仅建立在它上面的,所以它也不会产生数据稀疏问题。
utterance drop regularization
虽然建立了层次的latent space,不过作者在实践中发现,层次RNN decoders仍然非常的expressive,导致模型仍然倾向于忽略 z c o n v z^{conv} zconv和 z t u t t z_{t}^{utt} ztutt,所以作者又提出了utterance drop regularization来缓解,具体做法就是在每个时间步, h t e n c h_{t}^{enc} htenc以概率p被替换为一个设定的未知向量 h u n k h^{unk} hunk,这个做法降低了层次RNN decoders的自适应表达能力,同时又因为为 h t c x t h_{t}^{cxt} htcxt引入了噪音,所以也缓解了数据稀疏性问题,
作为新时代的"老物"-RNN,尽管还有一些工作是基于其开展的,不过,现在其越来越边缘化了,在nlp领域引领风骚的是各种transformer的变体,比如大火的BERT,GPT,T5等等,这些最新的模型把nlp推到了一个非常高的程度,后续会记录一些这类模型的细节。