深度学习解决NLP问题:语义相似度计算

在NLP领域,语义相似度的计算一直是个难题:搜索场景下query和Doc的语义相似度、feeds场景下Doc和Doc的语义相似度、机器翻译场景下A句子和B句子的语义相似度等等。本文通过介绍DSSM、CNN-DSSM、LSTM-DSSM等深度学习模型在计算语义相似度上的应用,希望给读者带来帮助。

1.背景

以搜索引擎和搜索广告为例,最重要的也最难解决的问题是语义相似度,这里主要体现在两个方面:召回和排序。

在召回时,传统的文本相似性如BM25,无法有效发现语义类query-Doc结果对,如"从北京到上海的机票"与"携程网"的相似性、"快递软件"与"菜鸟裹裹"的相似性。

在排序时,一些细微的语言变化往往带来巨大的语义变化,如"小宝宝生病怎么办"和"狗宝宝生病怎么办"、"深度学习"和"学习深度"。

DSSM(Deep Structured Semantic Models)为计算语义相似度提供了一种思路。

本文的最后,笔者结合自身业务,对DSSM的使用场景做了一些总结,不是所有的业务都适合用DSSM。

2. DSSM

DSSM(Deep StructuredSemantic Models)的原理很简单,通过搜索引擎里Query和Title的海量的点击曝光日志,用DNN把Query和Title表达为低纬语义向量,并通过cosine距离来计算两个语义向量的距离,最终训练出语义相似度模型。该模型既可以用来预测两个句子的语义相似度,又可以获得某句子的低纬语义向量表达。

DSSM从下往上可以分为三层结构:输入层、表示层、匹配层

2.1输入层

输入层做的事情是把句子映射到一个向量空间里并输入到DNN中,这里英文和中文的处理方式有很大的不同。

(1)英文

英文的输入层处理方式是通过word hashing。举个例子,假设用letter-trigams来切分单词(3个字母为一组,#表示开始和结束符),boy这个单词会被切为#-b-o, b-o-y,o-y-#

这样做的好处有两个:首先是压缩空间,50万个词的one-hot向量空间可以通过letter-trigram压缩为一个3万维的向量空间。其次是增强范化能力,三个字母的表达往往能代表英文中的前缀和后缀,而前缀后缀往往具有通用的语义。

这里之所以用3个字母的切分粒度,是综合考虑了向量空间和单词冲突:

以50万个单词的词库为例,2个字母的切分粒度的单词冲突为1192(冲突的定义:至少有两个单词的letter-bigram向量完全相同),而3个字母的单词冲突降为22效果很好,且转化后的向量空间3万维不是很大,综合考虑选择3个字母的切分粒度。

(2)中文

中文的输入层处理方式与英文有很大不同,首先中文分词是个让所有NLP从业者头疼的事情,即便业界号称能做到95%左右的分词准确性,但分词结果极为不可控,往往会在分词阶段引入误差。所以这里我们不分词,而是仿照英文的处理方式,对应到中文的最小粒度就是单字了。(曾经有人用偏旁部首切的,感兴趣的朋友可以试试)

由于常用的单字为1.5万左右,而常用的双字大约到百万级别了,所以这里出于向量空间的考虑,采用字向量(one-hot)作为输入,向量空间约为1.5万维。

2.2表示层

DSSM的表示层采用BOW(Bag of words)的方式,相当于把字向量的位置信息抛弃了,整个句子里的词都放在一个袋子里了,不分先后顺序。当然这样做会有问题,我们先为CNN-DSSM和LSTM-DSSM埋下一个伏笔。

紧接着是一个含有多个隐层的DNN,如下图所示:

用Wi表示第i层的权值矩阵,bi表示第i层的bias项。则第一隐层向量l1(300维),第i个隐层向量li(300维),输出向量y(128维)可以分别表示为:

用tanh作为隐层和输出层的激活函数:

最终输出一个128维的低纬语义向量。

2.3匹配层

Query和Doc的语义相似性可以用这两个语义向量(128维)的cosine距离来表示:

通过softmax函数可以把Query与正样本Doc的语义相似性转化为一个后验概率:

其中r为softmax的平滑因子,D为Query下的正样本,D-为Query下的负样本(采取随机负采样),D为Query下的整个样本空间。

在训练阶段,通过极大似然估计,我们最小化损失函数:

残差会在表示层的DNN中反向传播,最终通过随机梯度下降(SGD)使模型收敛,得到各网络层的参数。

2.4优缺点

优点:DSSM用字向量作为输入既可以减少切词的依赖,又可以提高模型的范化能力,因为每个汉字所能表达的语义是可以复用的。另一方面,传统的输入层是用Embedding的方式(如Word2Vec的词向量)或者主题模型的方式(如LDA的主题向量)来直接做词的映射,再把各个词的向量累加或者拼接起来,由于Word2Vec和LDA都是无监督的训练,这样会给整个模型引入误差,DSSM采用统一的有监督训练,不需要在中间过程做无监督模型的映射,因此精准度会比较高。

缺点:上文提到DSSM采用词袋模型(BOW),因此丧失了语序信息和上下文信息。另一方面,DSSM采用弱监督、端到端的模型,预测结果不可控。

3. CNN-DSSM

针对DSSM词袋模型丢失上下文信息的缺点,CLSM(convolutionall atent semantic model)应运而生,又叫CNN-DSSM。CNN-DSSM与DSSM的区别主要在于输入层和表示层。

3.1输入层

(1)英文

英文的处理方式,除了上文提到的letter-trigram,CNN-DSSM还在输入层增加了word-trigram

如上图所示,word-trigram其实就是一个包含了上下文信息的滑动窗口。举个例子:把 online auto body ... 这句话提取出前三个词 online auto,之后再分别对这三个词进行letter-trigram映射到一个3万维的向量空间里,然后把三个向量concat起来,最终映射到一个9万维的向量空间里。

(2)中文

英文的处理方式(word-trigramletter-trigram)在中文中并不可取,因为英文中虽然用了word-ngram把样本空间拉成了百万级,但是经过letter-trigram又把向量空间降到可控级别,只有3*30K(9万)。而中文如果用word-trigram,那向量空间就是百万级的了,显然还是字向量(1.5万维)比较可控。

3.2表示层

CNN-DSSM的表示层由一个卷积神经网络组成,如下图所示:

(1)卷积层——Convolutional Layer

卷积层的作用是提取滑动窗口下的上下文特征。以下图为例,假设输入层是一个302*90000(302行,9万列)的矩阵,代表302个字向量(query的和Doc的长度一般小于300,这里少了就补全,多了就截断),每个字向量有9万维。而卷积核是一个3*90000的权值矩阵,卷积核以步长为1向下移动,得到的feature map是一个300*1的矩阵,feature map的计算公式是(输入层维数302-卷积核大小3步长1)/步长1=300。而这样的卷积核有300个,所以形成了300个300*1的feature map矩阵。

(2)池化层——Max poolinglayer

池化层的作用是为句子找到全局的上下文特征。池化层以Max-over-time pooling的方式,每个feature map都取最大值,得到一个300维的向量。Max-over-pooling可以解决可变长度的句子输入问题(因为不管feature map中有多少个值,只需要提取其中的最大值)。不过我们在上一步已经做了句子的定长处理(固定句子长度为302),所以就没有可变长度句子的问题。最终池化层的输出为各个feature map的最大值,即一个300*1的向量。这里多提一句,之所以Max pooling层要保持固定的输出维度,是因为下一层全链接层要求有固定的输入层数,才能进行训练。

(3)全连接层——Semantic Layer

最后通过全连接层把一个300维的向量转化为一个128维的低维语义向量。全连接层采用tanh函数:

3.3匹配层

CNN-DSSM的匹配层和DSSM的一样,这里省略。

3.4优缺点

优点:CNN-DSSM通过卷积层提取了滑动窗口下的上下文信息,又通过池化层提取了全局的上下文信息,上下文信息得到较为有效的保留。

缺点:对于间隔较远的上下文信息,难以有效保留。举个例子,I grew up in France... I speak fluent French,显然France和French是具有上下文依赖关系的,但是由于CNN-DSSM滑动窗口(卷积核)大小的限制,导致无法捕获该上下文信息。

4. LSTM-DSSM

针对CNN-DSSM无法捕获较远距离上下文特征的缺点,有人提出了用LSTM-DSSM(Long-Short-Term Memory)来解决该问题。不过说LSTM之前,要先介绍它的"爸爸""RNN。

4.1 RNN

RNN(Recurrent Neural Networks)可以被看做是同一神经网络的多次复制,每个神经网络模块会把消息传递给下一个。如果我们将这个循环展开:

假设输入xi为一个query中几个连续的词,hi为输出。那么上一个神经元的输出h(t-1)与当前细胞的输入Xt拼接后经过tanh函数会输出ht,同时把ht传递给下一个细胞。

不幸的是,在这个间隔不断增大时,RNN会逐渐丧失学习到远距离信息的能力。因为RNN随着距离的加长,会导致梯度消失。简单来说,由于求导的链式法则,直接导致梯度被表示为连乘的形式,以至梯度消失(几个小于1的数相乘会逐渐趋向于)。

4.2 LSTM

LSTM ((Long-Short-Term Memory)是一种RNN特殊的类型,可以学习长期依赖信息。我们分别来介绍它最重要的几个模块:

()细胞状态

细胞状态这条线可以理解成是一条信息的传送带,只有一些少量的线性交互。在上面流动可以保持信息的不变性。

(1)遗忘门

遗忘门由Gers提出,它用来控制细胞状态cell有哪些信息可以通过,继续往下传递。如下图所示,上一层的输出h(t-1) concat上本层的输入xt,经过一个sigmoid网络(遗忘门)产生一个从到1的数值ft,然后与细胞状态C(t-1)相乘,最终决定有多少细胞状态可以继续往后传递。

(2)输入门

输入门决定要新增什么信息到细胞状态,这里包含两部分:一个sigmoid输入门和一个tanh函数。sigmoid决定输入的信号控制,tanh决定输入什么内容。如下图所示,上一层的输出h(t-1) concat上本层的输入xt,经过一个sigmoid网络(输入门)产生一个从到1的数值it,同样的信息经过tanh网络做非线性变换得到结果Ct,sigmoid的结果和tanh的结果相乘,最终决定有哪些信息可以输入到细胞状态里。

(3)输出门

输出门决定从细胞状态要输出什么信息,这里也包含两部分:一个sigmoid输出门和一个tanh函数。sigmoid决定输出的信号控制,tanh决定输出什么内容。如下图所示,上一层的输出h(t-1) concat上本层的输入xt,经过一个sigmoid网络(输出门)产生一个从到1的数值Ot,细胞状态Ct经过tanh网络做非线性变换,得到结果再与sigmoid的结果Ot相乘,最终决定有哪些信息可以输出,输出的结果ht会作为这个细胞的输出,也会作为传递个下一个细胞。

4.2 LSTM-DSSM

LSTM-DSSM其实用的是LSTM的一个变种——加入了peephole的LSTM。如下图所示:

看起来有点复杂,我们换一个图,读者可以看的更清晰:

这里三条黑线就是所谓的peephole,传统的LSTM中遗忘门、输入门和输出门只用了h(t-1)和xt来控制门缝的大小,peephole的意思是说不但要考虑h(t-1)和xt,也要考虑Ct-1和Ct,其中遗忘门和输入门考虑了Ct-1,而输出门考虑了Ct。总体来说需要考虑的信息更丰富了。

好了,来看一个LSTM-DSSM整体的网络结构:

红色的部分可以清晰的看到残差传递的方向。

5.后记

介绍完了DSSM及其几个变种,还要给大家泼点冷水,DSSM就一定适合所有的业务吗?

这里列出DSSM的2个缺点以供参考:

1. DSSM是端到端的模型,虽然省去了人工特征转化、特征工程和特征组合,但端到端的模型有个问题就是效果不可控。对于一些要保证较高的准确率的场景,用有监督人工标注的query分类作为打底,再结合无监督的word2vec、LDA等进行语义特征的向量化,显然比较可控(至少query分类的准确率可以达到95%以上)。

2. DSSM是弱监督模型,因为引擎的点击曝光日志里Query和Title的语义信息比较弱。举个例子,搜索引擎第一页的信息往往都是Query的包含匹配,笔者统计过,完全的语义匹配只有不到2%。这就意味着几乎所有的标题里都包含用户Query里的关键词,而仅用点击和曝光就能作为正负样例的判断,显然不太靠谱,因为大部分的用户进行点击时越靠前的点击的概率越大,而引擎的排序又是由pCTR、CVR、CPC等多种因素决定的。从这种非常弱的信号里提取出语义的相似性或者差别,那就需要有海量的训练样本。DSSM论文中提到,实验的训练样本超过1亿。笔者和同事也亲测过,用传统CTR预估模型千万级的样本量来训练,模型无法收敛。可是这样海量的训练样本,恐怕只有搜索引擎才有吧?普通的搜索业务query有上千万,可资源顶多只有几百万,像论文中说需要挑出点击和曝光置信度比较高且资源热度也比较高的作为训练样本,这样就过滤了80%的长尾query和Title结果对,所以也只有搜索引擎才有这样的训练语料了吧。另一方面,超过1亿的训练样本作为输入,用深度学习模型做训练,需要大型的GPU集群,这个对于很多业务来说也是不具备的条件。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181023B1JSG600?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券