本文将简要介绍聊天机器人的四种构建方法:检索、seq2seq、Reinforcement Learning、seqGAN。
聊天机器人从应用领域分为:
从技术上分为:
目前聊天机器人在专业领域利用检索的效果较好,正朝着通用领域生成型发展。
检索方法的数据库是很多对话的pair,其原理是将query编码成vector,然后在数据库中找最接近的query,然后将最接近的query的回答输出。注意点如下:
seq2seq使用两个RNN,一个作为输入的encoder,一个作为输出的decoder。需要注意的大致包含以下几点:
seq2seq有一些缺点:
第一个缺点使seq2seq不容易理解文本,因为AI-requires being able to understand bigger things from knowing about small parts.
第二个缺点使seq2seq的对话不像真实的对话,只考虑当前对话最大似然忽略了对话对未来的影响,容易出现“I don’t know”(因为其概率最大,其他方向的相互抵消);对话重复(不考虑上下文的关系)等问题。
针对第二个缺点,我们了解到概率最高的输出不一定等于好的输出,好的对话需要考虑长久的信息。可以引入强化学习,人为设计相关的reward让机器更好地学习。
强化学习的本质是根据reward,使模型参数朝着reward增长最大的方向移动。
强化学习的聊天机器人架构设计如下:
其模型本质还是seq2seq,模型参数是 θ ,模型输入是 h ,输出是 x ,其与seq2seq不同的地方在于模型参数的更新方式:seq2seq按照cross entropy确定损失函数,然后最小化损失函数;DL最大化期望的reward。
期望reward的计算公式如下:
我们的优化目标是:
在上一节中,我们得到了目标函数与优化目标,这节中,我们考虑如何求目标函数的梯度 ∇Rθ 。
上一节中得到 Rθ 的方式是通过采样,通过采样的方法自然无法计算梯度实现梯度的传递。解决的思路是:将 Rθ 转化成梯度的采样。具体实现如下:
θ 的更新方式如下:
这样更新的物理含义如下:
采用强化学习的模型与传统的seq2seq对比如下,其区别主要是强化学习对不同的loss用reward当做权重:
训练的整体过程如下:
更新模型参数 θ 的时候,如果reward都是正的,理想情况下对于单一的 h , Pθ(xi|h) 根据 R(h,xi) 的大小进行更新,可是采样的 (h,xi) 不一定能覆盖所有的情况,所以对reward要做baseline的设置。最简单的baseline就是 1N∑R(h,xi) 。
加入baseline之后的梯度为:
强化学习中,如果有人提供reward那是再好不过的了,不过这样投入的时间精力物力财力都很大,如何设计reward是这里讨论的问题。这里,提供三种reward的设计思路。
核心是P(“I don’t know”|response)比较小。
虽然 S 不可能覆盖所有的null回答空间,不过类似的回答在空间的位置都是很接近的,所以可以抽样去模拟。
核心是希望agent在每一轮对话中都可以产生新的信息,因此对连续两轮相同的输出进行惩罚。
为了保证产生的answer是合乎语言模型的,语义连贯。
最终的reward如下图所示:
SeqGAN与传统GAN一样,包括generator、discriminator。不同的是网络是condition的,也就是使用了condition GAN,generator condition的是query(因为RNN网络本身有随机性,所以这里不加随机的输入),discriminator condition的也是query。
SeqGAN训练的大致思路与GAN一致,对generator、discriminator分别训练。
然而,若按上面传统GAN的架构设计,更新generator参数的时候梯度是无法传递的。原因是generator的输出是采样离散的,难以计算梯度进行梯度的反向传播。
简单的解决方案是采用WGAN,传递的不是采样离散的值而是分布。SeqGAN的解决方案借鉴了强化学习。
采用强化学习的思路,将discriminator当做人,将discriminator的输出当做reward。利用policy gradient可以得到generator参数的更新方向(详见之前的强化学习部分),这样便解决了离散采样值梯度更新的问题。
使用强化学习,利用policy gradient解决了离散值梯度传递的问题后,还会出现对句子不同长度reward的分配问题。详见下图。这个问题在数据量大并且采样足够的情况不严重,在采样较少的情况较严重。
解决这个问题的思路是对每个generator的step都设置reward,具体如下。其中, Q(h,x) 代表当前genetor出来的相对输入h的好坏,如何度量它是一个问题。
解决度量 Q(h,x) 的方法是蒙特卡洛,具体方法如下图。固定已知序列,用generator去生成未知序列,以已知序列为首的未知序列都可以用discriminator计算reward,最后取平均当做已知序列的reward。
生成模型的训练通常很难,seqGAN中,初始的generator生成的x效果不好,因此discriminator给的reward很低,这样模型很难训练,因为它一直看到比较低的reward,也就是不好的数据,并不知道好的数据长什么样,自然很难像好的数据学习。
解决初始训练的思路是训练的时候更多的见到reward高的pair对,具体实施方法有两种:
这里涉及到如何去评估模型的好坏,传统的方式是BLEU,这里提供一种合成data的新思路。
BLEU需要提供候选和参考集,采用n-gram计算:候选n-gram在参考集n-gram中出现的最大频数/候选n-gram的总数。需要注意的有两点:
其缺点如下:
对话长度一定程度上反应了对话的满意度。定义对话结束当且仅当产生”i dont know”这样的null response(方法参考ease to answer的reward设计)或者agent连着重复了两句同样的话(word overlapping的程度)。
对话应该是多样性的,这是检索模型的缺点,太固定了,而生成模型有一定的随机性。
方法是计算输出response中unigram、bigram的数量,同时用token长度做正则避免长句子分数较高。
生成数据的方法,是先用LSTM(可以是random)产生很多pair作为真实数据。generator利用LSTM的数据学习,然后利用generator生成fake的answer,与真实的answer计算negative log likelihoood即可。