在NLP领域,语义类似度的计算一直是个难题:搜索场景下query和Doc的语义类似度、feeds场景下Doc和Doc的语义类似度、机器翻译场景下A句子和B句子的语义类似度等等。本文经过介绍DSSM、CNN-DSSM、LSTM-DSSM等深度学习模型在计算语义类似度上的应用,但愿给读者带来帮助。网络
1. 背景
以搜索引擎和搜索广告为例,最重要的也最难解决的问题是语义类似度,这里主要体如今两个方面:召回和排序。函数
在召回时,传统的文本类似性如 BM25,没法有效发现语义类 query-Doc 结果对,如"从北京到上海的机票"与"携程网"的类似性、"快递软件"与"菜鸟裹裹"的类似性。学习
在排序时,一些细微的语言变化每每带来巨大的语义变化,如"小宝宝生病怎么办"和"狗宝宝生病怎么办"、"深度学习"和"学习深度"。搜索引擎
DSSM(Deep Structured Semantic Models)为计算语义类似度提供了一种思路。翻译
本文的最后,笔者结合自身业务,对 DSSM 的使用场景作了一些总结,不是全部的业务都适合用 DSSM。3d
2. DSSM
DSSM [1](Deep Structured Semantic Models)的原理很简单,经过搜索引擎里 Query 和 Title 的海量的点击曝光日志,用 DNN 把 Query 和 Title 表达为低纬语义向量,并经过 cosine 距离来计算两个语义向量的距离,最终训练出语义类似度模型。该模型既能够用来预测两个句子的语义类似度,又能够得到某句子的低纬语义向量表达。日志
DSSM 从下往上能够分为三层结构:输入层、表示层、匹配层code

2.1 输入层
输入层作的事情是把句子映射到一个向量空间里并输入到 DNN 中,这里英文和中文的处理方式有很大的不一样。blog
(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)使模型收敛,获得各网络层的参数{Wi,bi}。
2.4 优缺点
优势:DSSM 用字向量做为输入既能够减小切词的依赖,又能够提升模型的范化能力,由于每一个汉字所能表达的语义是能够复用的。另外一方面,传统的输入层是用 Embedding 的方式(如 Word2Vec 的词向量)或者主题模型的方式(如 LDA 的主题向量)来直接作词的映射,再把各个词的向量累加或者拼接起来,因为 Word2Vec 和 LDA 都是无监督的训练,这样会给整个模型引入偏差,DSSM 采用统一的有监督训练,不须要在中间过程作无监督模型的映射,所以精准度会比较高。
缺点:上文提到 DSSM 采用词袋模型(BOW),所以丧失了语序信息和上下文信息。另外一方面,DSSM 采用弱监督、端到端的模型,预测结果不可控。
3. CNN-DSSM
针对 DSSM 词袋模型丢失上下文信息的缺点,CLSM[2](convolutional latent semantic model)应运而生,又叫 CNN-DSSM。CNN-DSSM 与 DSSM 的区别主要在于输入层和表示层。
3.1 输入层
(1)英文
英文的处理方式,除了上文提到的 letter-trigram,CNN-DSSM 还在输入层增长了word-trigram

如上图所示,word-trigram其实就是一个包含了上下文信息的滑动窗口。举个例子:把<s
> online auto body ... <s
>这句话提取出前三个词<s
> online auto,以后再分别对这三个词进行letter-trigram映射到一个 3 万维的向量空间里,而后把三个向量 concat 起来,最终映射到一个 9 万维的向量空间里。
(2)中文
英文的处理方式(word-trigram letter-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 pooling layer
池化层的做用是为句子找到全局的上下文特征。池化层以 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[3](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 的数相乘会逐渐趋向于 0)。
4.2 LSTM
LSTM[4]((Long-Short-Term Memory)是一种 RNN 特殊的类型,能够学习长期依赖信息。咱们分别来介绍它最重要的几个模块:

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

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

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

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

4.2 LSTM-DSSM
LSTM-DSSM 其实用的是 LSTM 的一个变种——加入了peephole[6]的 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 集群,这个对于不少业务来讲也是不具有的条件。