前置废话:感觉实习这两个月真是顶得上实验室半年,想想对不起我的导师,跟现在相比之前天天像是在打酱油啊。
相关文献
- Huang, Po-Sen, et al. “Learning deep structured semantic models for web search using clickthrough data.” Proceedings of the 22nd ACM international conference on Conference on information & knowledge management. ACM, 2013.
- Palangi, Hamid, et al. “Deep sentence embedding using long short-term memory networks: Analysis and application to information retrieval.” IEEE/ACM Transactions on Audio, Speech, and Language Processing 24.4 (2016): 694-707.
DSSM一撇
DSSM了解的不是很多,但是这两篇文章有几处是类似的,隐隐地感觉后面这篇是借鉴前面的写出来的。
文章中DSSM的最终目标是实现一个神经网络模型,使得给定输入文档(片段)可以输出一个对应的向量,而通过向量之间的余弦相似度可以判断两个Query-Document的相似性[latex]R(Q,D)=cosine(y_Q,y_D)[/latex],然后拿这个就能做搜索排序了。
Word-Hashing
DSSM中用到了一个奇淫巧术,就是所谓的Word Hashing方法。我们知道,要将文字拿来处理,首先要表示成向量的形式(数值化),最普通的方法是做One-Hot Vector, 即每个单词对应一个feature值,出现就是1,没出现就是0. 但是单词表实在是太大了,这篇论文用到了一个叫Letter-N-Gram的技术,即将一个单词强行分成几个n-gram. 例如单词Hello做Letter-3-Gram,就会变成#HE, HEL, ELL, LLO, LO# 这样的表示方法(其中#代表开头或结尾)。由于处理的Query/Doc对中特殊字符会在数据预处理阶段被过滤,因此抛开单词大小写,a-z0-9#一共就26+10+1=37个字符,37*37*37=50653种可能性,相比词典来说小多了!
这个办法初看不是很靠谱,但是实验结果却是不错的。
正例/反例
训练神经网络需要给正例以及反例。不出意外地,这里用的是用户的click stream,即用户的点击数据。假设[latex]D[/latex]表示对于一个查询Q的所有候选文档,那么[latex]D^+[/latex]表示用户点击的文档作为正例,[latex]D^-[/latex]表示没有点击的作为负例。再根据上面提到的相似度[latex]R(Q,D)[/latex],可以做出一个softmax的后验概率:
[latex]P(D|Q)=\frac{exp(\gamma R(Q,D))}{\sum_{D’ \in D}exp(\gamma R(Q,D’))}[/latex]
通俗易懂,对吧。
神经网络结构
想要实战的,可以看看CNTK里面有一个类似的例子:网络定义文件在这里,不过这个文件里面已经是Word Hashing过之后的了,而且参数设置和论文里的不大一样。
上面Figure1可以根据每一列来看。输入的最底层是Query/Doc的高纬度的词向量(Term Vector),然后进入了Word Hashing阶段把高维词向量弄成了L3G之类的向量,维度大概在30k~50k之间,然后加了两个隐藏层后输出了最终的128维向量y。这个向量y在训练结束之后就是传说中的词向量了。然后两个词向量之间可以算出相似度,最终给出一个softmax算的后验概率[latex]P(D_i|Q)[/latex]。
训练整一坨神经网络要给一个优化目标,文中定义了一个loss function:
[latex]L(\Lambda)=-log\prod_{(Q,D^+)}P(D^+|Q)[/latex]
其中[latex]\Lambda[/latex]表示训练神经网络时的一堆参数。然后使用梯度下降之类的方法,把梯度一层层往回传就能调整参数了。
RNN与LSTM
RNN/LSTM具体是怎么工作的?要详细理解可以看这篇文章,讲得很透彻。这里只提到论文中的一些实现。
RNN
RNN的结构特点是下一个平行节点状态的信息是基于之前节点的。如上图,在本文的环境中,底下的x0,x1,x2,…可以看做一个个单词的输入,这一长串的节点连在一起就变成了一个句子。上面做DSSM时,一整句(段)话的词都拿来一起做Word Hashing,结果就是词汇之间的信息从一开始就会被忽略掉,如果换成了RNN,虽然最后拿到的还是个句子的向量,但是理论上训练出的模型会更加准确一些。中间层是Word Hashing之后的层,用的应该是和DSSM一样的Hashing方法。在最右侧(最后一个词)的激活输出就是Embedding好的句子,一个句子向量:)
但是RNN的引入会引出“梯度爆炸”或“梯度消失”的问题。数学原理不多说,考虑这个句子:I grew up in France… I speak fluent French. 假设我的任务是要训练一个RNN,根据之前的所有单词信息“猜”最后一个词汇French。在这句话中,显然最适合用来参考的是句子开头的那个词France,但是中间还隔了一大堆的“没卵用”词。在根据标签判断loss函数做梯度下降的时候,梯度一层层往回传,但由于中间隔的比较远,等轮到France这个词的时候已经几乎没有影响了。
LSTM-DSSM
LSTM处于什么位置呢?我把两个文章的对比图放在这边,基本上就能看出来了。左图里面用橙色圈出的结构,他的作用和右侧黑色虚线框里的东西是一样的,只是LSTM结构取代了原本比较“单纯”的多层网络的地位。所以这个论文的方法似乎可以叫做LSTM-DSSM.
所以对于怎么做学习,这个新文章的方法也是与它的前身很类似的:根据用户点击的Query-Doc来确定正例及反例(右图中的[latex]D^+[/latex]与[latex]D^-[/latex]),求一个最大似然,它等同于最小化下面这个公式中的参数[latex]\Lambda[/latex]。
[latex]L(\Lambda)=-log\prod_{(Q,D^+)}P(D^+|Q)=\sum_{r=1}^{n}l_r(\Lambda)[/latex]
其中,r对应第r条Query, j是这条Query对应的一条Document。
多说一句,这个Query-Doc的匹配过程有点像做Translation Model,只不过Translation Model有Encoding和Decoding两步,而这里只有Encoding的过程。
LSTM结构
简单来说,LSTM是一种RNN结构,里面通过一些Gate来实现“要不要记住/考虑XXX”的选择。LSTM根据需要有不同的具体实现,下图是论文中用到的结构:
这个结构分成了几个关键部位:Input Gate, Output Gate 和 Forget Gate. 可以看到这些Gate的实现是Sigmoid输出的(图中[latex]\sigma(.)[/latex]),所以值都在0-1之间;然后和前面的h(.)去做一个pointwise multiple(X),实现了“门”的功能。
- Input Gate决定了在这个LSTM结构中哪些值是要更新的,即是否要把当前的输入信息加入到隐藏层的状态;
- Output Gate决定了是否把当前这个LSTM的输出传到下一层去;
- Forget Gate决定了是否要保留当前一个节点的历史状态c(t-1),可以看到图中有一个圈状的结构