写在开头

已经关注Retrieval-Based Chatbots一段时间了,期间也看了不少这方面的论文,以及在这些论文里面又发现了一些很不错的论文。这段时间一直在做相关的实验,现在实验效果也出来了,准备将自己的成果写成一篇论文,并且总结下这段时间看过的论文。

目前计划先讲SMN、DAM、IMN和MRFN这四篇论文,其中SMN和DAM的作者已经将代码放出,都是提供Tensorflow版本,为了方便实验,我自己将两份代码用Pytorch改写了,SMN的代码我放到了自己的github上,不过感觉自己放上去的版本还需要修改下,后续将会做下补充再重新上传代码~(感觉给自己挖了挺多坑的,希望自己有毅力将每个坑填好)

第二篇讲DAM的文章出来了,有兴趣想了解DAM模型的可以看下:

LeonMao:来谈谈那些很棒的检索式Chatbots论文(二)?

zhuanlan.zhihu.com
图标

SMN(Sequential Matching Network)

讲回正题,Retrieval-Based Chatbots即检索式的聊天机器人,在人机的多轮对话中(多轮的QA)从多个候选回复中选出最优的回复,这便是我们的目标。这次讲的论文是SMN,其论文全名为Sequential Matching Network: A New Architecture for Multi-turn Response Selection in Retrieval-Based Chatbots

这篇论文是吴俣大佬的,这个结构影响了后续相关的论文,不少论文都采用了这种结构,首先放出论文地址及其源码:

https://arxiv.org/pdf/1612.01627v2.pdf?

arxiv.org

MarkWuNLP/MultiTurnResponseSelection?

github.com
图标

Introduction

在这论文之前,有关Retrieval-Based Chatbots的做法是将context里所有的utterances都连接在一起,将这个长长的context做处理然后和response作匹配。而正如论文的名称,该论文提出了一个新的框架,不再将utterances拼接起来,而是每个utterance都和response做匹配,然后再用RNN去构建utterance间的关系,最后的匹配分数通过RNN的隐藏层计算得出。除了提出这个新的框架外,作者还在论文里提出了一个新的数据集,这个数据集(豆瓣对话语料库)也被后续相关的论文所使用。

关于多轮对话的例子,通过图一可以很直观的看出:

多轮对话的一个例子

在论文中作者也谈到,不同於单轮的对话,多轮对话需要考虑到前几轮对话中的信息,而不单单只关注于最近的那个对话,所以如何识别出context中重要的信息(例如单词、短语、句子),哪些信息是对选择合适的回复起关键作用;如何构建utterances之间的关系,这些都是需要考虑的问题。

Model Overview

SMN的结构

上面的图就是SMN的模型结构,可以很清楚的看到,SMN让response和每个utterance做匹配,形成2D的response-utterance相似度矩阵(similarity matrix),除了从单词层面(word embedding)做匹配外,还在子序列层面(经过一层GRU后的隐藏状态)做匹配,这样就能得到两种粒度(granularity)的匹配表示了,这也是图中 M_{1}、M_{2} 的来源。

接著将这两个相似度矩阵做卷积和池化操作,以抽取匹配信息。经过前面的操作,抽取出response和每个utterance的匹配信息,紧接著就是将这些信息积累起来,作者这里用GRU,对所有的匹配信息按时间顺序(chronological order)进行积累,最后用得到的隐藏状态计算匹配程度。

文章中将模型分为三层,接下来将详细的介绍每一层的公式:

  • Utterance-Response Matching
  • Matching Accumulation
  • Matching Prediction

Utterance-Response Matching

模型的输入是response和context里面的utterances,接下来用 r 代表response,用 u 代表utterance。ru 经过word embedding后,变成:

R=[e_{r,1},...,e_{r,n_{r}}]

U=[e_{u,1},...,e_{u,n_{u}}]

其中 R 的维度是 d	imes n_{r}U 的维度是 d	imes n_{u}d 就是word embedding的维度大小,在具体实验中,作者用了word2vec方法生成词向量, d 的大小是200。

RU 在经过一层GRU后,其隐藏状态表示成:

H_{r}=[h_{r,1},...,h_{r,n_{r}}]

H_{u}=[h_{u,1},...,h_{u,n_{u}}]

其中 H_{r} 的维度是 t	imes n_{r}H_{u} 的维度是 t	imes n_{u}t 就是隐藏层的维度大小,在具体实验中,作者将GRU的隐藏层大小设置为200。

在拿到了两种表示后,就可以计算相似度矩阵了。 RU 形成的相似度矩阵 M_{1}H_{r }H_{u }形成的相似度矩阵M_{2}的元素计算如下:

e_{1,i,j}=e_{u,i}^{	op}cdot e_{r,j}M_{1} 矩阵的元素)

e_{2,i,j}=h_{u,i}^{	op} A  h_{r,j}M_{2} 矩阵的元素)

注意到 M_{1} 里面只是普通的两个向量相乘,而 M_{2} 中则是加入了一个线性变换的矩阵 A

得到两个相似度矩阵后,进行卷积和池化的操作,具体公式如下:

在具体的实验中,输入的通道数量是2(因为有 M_{1}M_{2} ),输出的通道数为8,用了3*3的卷积核,激活函数用了RELU。在做完最大池化后,作者还做了碾平操作,池化后张量的维度是 (B,H,W,C) ,将其转变成 (B,H*W*C),然后经过一层线性层加tanh激活函数后,再送入另一个GRU,这个细节是在阅读了作者的源码获知的。

Matching Accumulation

经过上面的处理,我们得到 [v_{1},...,v_{n}] ,n的值等于输入的utterance的数量。然后经过一层GRU得到 H_{m}=[h_{1}^{},...,h_{n}^{}]H_{m} 的维度是q	imes nq 是GRU隐藏层的维度,在具体实验中为50。

这层的作用是用于构建utterances之间的依赖和时间上的联系。

Matching Prediction

在得到H_{m}=[h_{1}^{},...,h_{n}^{}]后,应该如何利用这些信息呢?作者提出了三种方法:

1、直接用最后的隐藏状态,即L[h_{1}^{},...,h_{n}^{}]=h_{n}^{}

2、给予每个隐藏状态一个权重然后加和,即 L[h_{1}^{},...,h_{n}^{}]=Sigma_{i=1}^{n}w_{i}h_{i}^{}

3、参考了论文Hierarchical attention networks for document classification,具体公式为:

最后用下面的公式得到匹配分数:

上面公式就是用线性层将维度降为2,再用softmax归一化,即将其转化成二分类问题,表示这个候选的response是否可选。


论文还详尽的介绍了豆瓣对话语料库,并且做了实验去研究应该在context中取多少个utterance,即取多少轮对话,实验证明轮数取10的时候效果最好。

感觉除了读论文,好好研究作者开源的代码对自己提升也很大,因为很多细节只有看了代码后才会清楚,后续应该会放出自己复现的pytorch代码,下一篇文章将会写DAM~

推荐阅读:

相关文章