【DST系列】DST模型介绍
上两篇我们介绍了DST的基本概念,DST挑战,以及DST的模型分类,这一部分我们主要介绍有哪些模型能够解决DST存在的问题,以及能够解决哪些问题,不能解决哪些问题,对应的优缺点,深入理解模型设计的思想。
1.规则+模型介绍
参考论文:Deep Neural Network Approach for the Dialog State Tracking Challenge
本文使用深度学习的方法解决DST问题,通过构造人工特征,输入到DNN网络,最终学习出状态分布。本文的核心是使用了n-gram滑动窗口,统计T轮内的特征,T轮以外的直接加和。模型对历史对话的信息重点放在前T轮,也就是t-T+1到当前轮次t,对于每个轮次都根据特征函数抽取了信息。此外T轮之前的信息,作者可能认为参考意义不是很大,因此直接将t-T+1轮之前的特征直接做了一个总和,单独作为一个输入。如果当前轮次t<T,那么该输入的所有特征值都为0。同时手工构造了12个领域无关的特征函数。随后将构造的特征输入到一个3层的神经网络中,计算出的概率。最后通过一个归一化的操作,得出的分布。模型结构如下:
归一化操作如下:
其中表示轮以内槽位s可能在NLU中出现的,没有出现的不在该集合里面。其中是一个超参数,与槽值无关,与槽位类型有关。
12个特征如下图所示,我们可以看出,这个特征都是与领域无关的。抽取到的特征涵盖了NLU的槽值对输出、系统上一时刻动作、多轮对话历史。所以总体上还是满足了DST对历史对话及当前输入的考量。
从上面的描述中,我们可以看出该模型主要有以下三个优点:
领域无关(主要是构造的特征与领域无关); 无需知道所有可能的集合(主要是因为最后的归一化只是对出现的槽位值进行的归一化,没有出现的不处理); 泛化性好。
当然,该模型需要对每一个槽位建立一个模型,因此有多少个槽位类型,就会对应多少个模型。当然也可以共享参数,因为,模型并没有与槽位绑定。
最后,本文作者还调整了一些超参数。从上面的描述中,我们知道T、特征数、网络结构,以及初始化化方法,都是该方法的超参数。通过实验,作者发现,T=10,特征越多越好(实际使用可以结合数据,再多增加一些特征,效果应该还可以),三层的网络结构[20,10,2]效果最好。最后参数的初始化方法:
对每个槽位训练一个模型(见下图Separate);
所有的槽位共享一个模型(见下图Single Model);
先小批量的训练一个模型,然后用这个模型的参数初始化第一种方式的每个模型(见下图Shared Init)。
可以看出基本上分开训练是比较好,第三种方式虽然有提高但是很小。整个结果如下。
2.统计模型介绍
参考论文:Neural Belief Tracker: Data-Driven Dialogue State Tracking
上面的论文是用NLU的结果作为输入,本篇论文将ASR和NLU合并一起,直接使用ASR的结果作为DST的输入,那这样做的结果有什么好处呢?主要有两个优点:
1)NLU单独作为一个子模块的时候,也会产生误差,这样ASR+NLU的误差传递会导致在进入到DST的时候就已经存在较大误差了,因此合并NLU和DST可以减少这种误差传递的影响。
2)在对任务型对话系统做评测时,无法判断整个系统产生的错误来源于哪个子模块,也就无法有效的定位错误的来源,因此减少子模块可以提高错误定位的准确率。
本论文提出的模型不需要人工规则,直接使用预训练的词向量。将系统的输出和用户的输入作为输入,表征上下文,然后再和槽位值匹配。优点如下:
NBT模型性能优于基于规则的模型; 无需按照NLU那样完整配置; 扩展性、灵活性好; 预训练的方式能够处理词的形态的变化; 能够共享参数。
模型结构如下,模型的输入主要来自三个方面,系统的输出、用户的输入以及槽值对,将这三个输入进行表征学习转为一个向量,分别为 ,, 。随后,将学习到的向量表示通过上下文建模和语义解码子模块进行交互,以获得中间向量dr,dc和d。作为最终决策模块的输入,该最终决策模块决定用户是否表达了候选槽值对。
下面让我们详细说一下这四个模块的内容。首先是表征模块,作者提出了两种表征方式,一种是DNN的方法,一种是CNN的方法,如下图,这两种方式都是提取n-gram的信息,最后通过加和方法得出统一的长度表示,其实现在我们有更好的特征提取的方法,比如transformer等。
其次是语义解析模块,第一张图显示,用户输入表示r和候选槽值对表示c通过语义解码模块直接交互。该组件决定用户是否明确表达了当前候选槽值对(没有考虑对话上下文)。NBT模型学习将槽值候选对映射到与用户表征r相同维的向量c中。然后,必须强制这两种表示进行交互,以学习相似度度量。
其中,分别为槽位和值的编码,⊗表示逐元素矢量乘法。点积看起来像是更直观的相似性度量,可以将d中丰富的特征集减少为单个标量。通过学习r和c中的特征集之间的非线性相互作用,逐元素乘法允许下游网络更好地利用其参数。
其次是上下文模块,解码模块只是关注了用户表达过哪些槽位和值,但是没有关注系统的输出。因此这个模块主要是结合系统输出。系统主要有两个动作,表示系统询问用户想要槽位的哪个值,比如“你想要什么价格的呢”,表示系统询问用户对于是否想要,比如“你是想要贵一点的吗?”,交互如下:
其中*表示点积,所计算的相似性项充当门控机制,仅当系统询问当前候选槽或者槽值对时,才会通过。这种交互方式对于确认系统动作特别有用:如果系统要求用户进行确认,则用户可能不会提及任何槽值,而只是做出肯定或否定的回应。这意味着模型必须考虑候选槽值对和系统提供的槽值对之间的交互作用。如果后两个相同时,模型在做出后续的二元决策时应考虑用户的肯定或否定。
最后是决策模块,由如下表达式决定,因为候选槽值对每次只选一个,因此最后做一个二分类的决策:
下标2和100表示向量的维度。其中, dim表示输出的维度。
上面只是更新了单个槽位,所有槽位应该怎么更新呢,这涉及到对话状态更新机制,本文定义了一个基于规则的更新机制。
在轮对话时,用表示ASR的N-best集合,表示第i条句子,表示第i个句子的置信度,表示系统在上一时刻的动作。则对于槽位更新当前所有的值的概率分布,将所有的N-best加和:
结合之前所有的对话历史,通过参数控制不同时刻的重要性,可以表示为:
之后取概率大于0.5的槽值对来更新当前的状态值,没有的话就依然保留上一时刻的值。
最终的结果如下,在两个数据集的结果,和不同预训练的词向量的结果。
当然本文的缺点在于最后状态的合并和更新机制使用了规则,基于规则机制迁移到新的任务时需要大量的修改,作者又提出了Fully Statistical Neural Belief Tracking,有兴趣的可以去看一下,基本是解决这个问题的。
3.深度模型介绍
参考论文1:SUMBT: Slot-Utterance Matching for Universal and Scalable Belief Tracking
传统的DST方法,对词汇和词形变化很敏感,因为它们依赖人工构造的语义字典。随着近期深度学习在NLP的应用,NBT出现了,它们通过学习神经语义词表示大幅提高了性能。但是,可扩展性依然没有被解决。以往的方法,要么对每一个领域/槽分别建模,要么难以集成本体中未定义的新值,建模的跟踪器都是领域/槽位依赖的,所以欠缺领域本体设置的灵活性。本文提出模型叫做SUMBT,该方法基于预定义的本体和候选槽值列表,寻找合适的value,该方法是基于词的,是独立于领域/槽位的,因此通用性和扩展性更强,可以增加槽位和值。该方法可以看成一个阅读理解的方式,把聊天消息当做文章,槽位对应的值是什么当做问题。
SUMBT模型的思想简单归纳为两点:
通过bert提取上下文信息,使用阅读理解的方法匹配槽-值; 模型以一种非参数的方式预测slot-value标签(该方法除了预训练的参数,其他参数几乎没有)。
模型结果如下,也是比较简单的。
该方法主要分成三个方面:
1)首先是编码,使用了目前效果最好的BERT系列模型,将系统的输出和用户的输入,以及期望槽值对的一个文本话,通过bert提取丰富的上下文信息。
2)其次是槽-话的匹配,参考阅读理解的方式,这里使用transformer里面的multi-head方法,如下:
其中是上面的,K和V是,这一步相当提取了问题的答案,比如问题是“你想要什么价格的食物呢”,用户可能说“我想要便宜点的”,因此通过上面的multi-head可能就提取出“便宜”这个槽值,因此整个过程其实就是槽位和槽值的一个匹配过程。
3)最后就是状态追踪,随着对话继续,对话状态不仅由当前轮决定,也由以往对话历史决定,作者使用了一个rnn的方式,如下:
因为是bert输出的,是做过归一化的,因此这里我们对最终的结果也归一化:
最后计算提取的答案和我们给出的答案的距离或者相似度,如下:
数据集是woz 2.0和multiwoz。前者包含一个领域,三种槽位。后者包含七个领域,35种槽位,结果如下:
本文提出的模型都是基于现有的方法,我猜主要还是使用BERT这种强有力的预训练模型,作者后面也对注意力机制做了一个分析,可以看出multi-head的作用。
参考论文2:Transferable Multi-Domain State Generator for Task-Oriented Dialogue Systems
对领域本体的过度依赖和跨域知识共享的缺乏是对话状态追踪的两个实际存在但很少研究的问题。现有方法通常无法在推理过程中追踪未知槽值,并且在适应新领域时通常会遇到困难。为了处理这些新的挑战,本文认为DST模型在追踪的过程中需要能够在领域之间共享知识,以便更好地处理领域之间共享槽值的槽位。同时,领域之间的知识迁移对于追踪未知领域中的槽位也同样十分必要。在本文中,作者提出了一种可迁移的对话状态生成器(TRADE),利用复制机制从对话文本生成对话状态,从而预测在训练期间未遇到的(领域,槽位,槽值)三元组时促进知识转移。该模型由编码器,槽位门和状态生成器组成,它们在不同领域之间共享。实证结果表明,对于人与人对话数据集MultiWOZ的五个域,TRADE的最新联合目标准确度达到48.62%。此外,通过zero -shot和few-shot对话状态追踪(没有出现过的领域)来显示其迁移能力。TRADE在zero -shot中达到了60.58%的联合目标精度,并且能够适应few-shot的情况而不会忘记已经训练过的领域。
下图是作者给的一个例子,该对话涉及到三个不同的领域,而且领域之间有槽位共享。
模型结构如下,主要分成三个部分,下面一一来介绍:
我们这里先定义一下符号,表示T轮内用户和系统的聊天消息,表示每一轮的对话状态,表示三元组(领域Dn,槽位Sm,槽值),表示所有的领域,表示不同的槽位,假定共有J个(领域、槽位)对,为第j个领域-槽位对的值。
1)首先是utterance encoder ,和上面的一样,需要对文本消息进行编码,作者使用了gru进行编码(这个其实使用transformer编码可能更好),这个地方就很简单了,在l轮以内,将所有的消息拼接在一起。生成每个词的向量表示。
2)然后是State Generator (状态生成器),生成器这部分,也是使用了GRU作为其基本模型,基本过程如上图右半部分,选择J个对里面的一个domain-slot对,对其向量化,然后相加,当做gru的第一输入,然后依次将词向量当做gru的输入,得出, 整体如下:
这整个过程其实就是以领域-槽位对作为gru的初始化,然后依次解码并且把解码后的值映射到全局词典和当前的上下文上面,因此这一步主要是判断哪些词是领域-槽位对的槽位值。这样做的好处是,如果这个词没有出现在对话上下文中,我们也可以将其召回回来。最后合并这个两个。
其中是一个可训练的参数。
3)最后就是 Slot Gate ,这个地方其实就是一个很简单的3分类器,把映射成这个三个类别ptr(有相关的槽位), none(没有)和 dontcare (不关心),对于第二部生成的槽位值,如果slot gate判断是none和dontcare时,则会抛弃该值,因此这里其实就是相对于一个控制门。
最终的是要优化State Generator和 Slot Gate,前者使用如下方式:
后者使用如下方式,都是交叉熵,只不过维度不一样。
最后,毫无疑问,将两个损失函数相加:
整个过程还是比较容易理解的,比较重要的是State Generator这部分,这个过程是一个解码的过程,并且将解码的向量映射到整个词向量上,可以解决未见词的问题。
为了验证模型的领域迁移能力,分别针对对话领域设定zero-shot和few-shot两种场景。在zero-shot设定下,训练集中不包含目标领域的训练样本。假设源领域和目标领域具有相同的槽位,而训练集仅包含源领域的训练样本。当输入目标领域和对应槽位时,模型应当可以输出通过源领域学习到的槽值序列。few-shot设定考察模型在目标领域只有极少量样本的情况下,从已知领域迁移学习到的知识到目标领域的能力。由于模型迁移到新领域时,在使用新领域样本进行fine-tune时,可能存在灾难性遗忘的问题(源领域所学习到的知识被遗忘),few-shot场景所检测的实际是模型在新领域只有少量样本且只能利用目标领域样本进行fine-tune的情况下,对于已学习到的知识进行保留和迁移的能力。
结果如下:
该论文的整体贡献如下:
为了克服多轮映射问题,TRADE利用其上下文增强的slot gate 和copy机制来正确跟踪对话历史记录中任何地方提到的槽值; 通过跨域共享其参数,而无需预定义的本体,TRADE可以在领域之间共享知识以追踪未出现的槽值,从而实现多域DST的最新性能; TRADE通过利用在训练过程中已经看到的域来实现zero-shot DST。如果有一些来自未知领域的训练样本可用,那么TRADE可以适应新领域; 当然该模型的复杂度还是有点高的,估计也只能离线操作了。
4.总结
本篇我们介绍了四个模型,基本上是按照DST发展顺序来介绍了,每个模型都有优缺点,每个模型也是为了解决之前模型存在的问题而提出的。下一篇我们会结合小贝助手相关的业务,探索下DST在小贝助手中的应用。
作者介绍
王文彬,2018年毕业于中国科学院大学。毕业后加入贝壳找房人工智能中心业务智能部,主要从事NLP、强化学习和搜索推荐相关工作。
由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:
(1)点击页面最上方'AINLP',进入公众号主页。
(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。
感谢支持,比心
。