(三)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)
《文本嵌入式表示方法实战》系列文章是基于2017年我于研一下半学期做的两场长时间的组会汇报ppt上形成的文章(学习和实验长达3个月,因为当时主要以上课为主,实验都是课余时间做的。。),由于当时我正处于入门阶段,理解和表述定有不当之处,还请各位同学老师批评指教。。。
《文本嵌入式表示方法实战》系列文章全部链接如下:
(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)
(二)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)
(三)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)
(。。。。。。书接上一期。。。。。。)
所以我们建立词汇表
![]()
然后就是训练模型和保存模型:

值得注意的是,模型如果在每次训练期间,输入的数组都是随机排序的话,可以训的更好。
我们这里训练50次,随机排序有sentences_perm实现。训练时间很长,可以打5盘王者荣耀。

接下来是读取模型,事实上可以调用d2v的一些方法,如model.most_similar(‘good’)查看词向量情况,还可以调用model.syn0(这代表的是千层神经网络的输出层,这样可以得到包含着单词向量和句子向量),如果只想看句子向量的话,调用model[‘TRAIN_NEG_0’]就是训练集消极评价的第一句话。可以看标签的作用。
然后如上图所示我们可以用得到的向量训练一个分类器,但这些向量还不合适直接作为输入,还应该做一些处理,首先应该知道我们一共有25000条训练数据,12500积极12500消极。因此我们可以创建numpy数组,需要两个平行的数组,一个是train_array另一个是train_label,然后用一个for循环,将向量赋值给两个数组。
测试数组一样。

然后就是调用分类器进行训练

6 FastText
6.1 原理解析
fasttext是facebook于2016年提出来的,其实应该包括两个部分,一个是词向量,另一个是文本分类。
基于两篇论文:
Enriching Word Vectors with Subword Information
这篇论文提出了用 word n-gram 的向量之和来代替简单的词向量的方法,以解决简单 word2vec无法处理同一词的不同形态的问题。fastText 中提供了 maxn 这个参数来确定 word n-gram的 n 的大小。
Bag of Tricks for Efficient Text Classification
这篇论文提出了 fastText 算法,该算法实际上是将目前用来算 word2vec 的网络架构做了个小修改,原先使用一个词的上下文的所有词向量之和来预测词本身(CBOW 模型),现在改为用一段短文本的词向量之和来对文本进行分类。
这两篇奠定了facebook的fasttext的基础。
fastText的架构和word2vec中的CBOW的架构类似,因为它们的作者都是Facebook的科学家Tomas Mikolov,而且确实fastText也算是words2vec所衍生出来的。
fastText的模型架构类似于CBOW,两种模型都是基于Hierarchical Softmax,都是三层架构:输入层、 隐藏层、输出层。其中x1,x2,...,xN−1,xNx1,x2,...,xN−1,xN表示一个文本中的n-gram向量,每个特征是词向量的平均值。这和前文中提到的cbow相似,cbow用上下文去预测中心词,而此处用全部的n-gram去预测指定类别。
CBOW模型又基于N-gram模型和BOW模型,此模型将W(t−N+1)……W(t−1)作为输入,去预测W(t) 。
fastText的模型则是将整个文本作为特征去预测文本的类别。
将输入层中的词和词组构成特征向量,再将特征向量通过线性变换映射到隐藏层,隐藏层通过求解最大似然函数,然后根据每个类别的权重和模型参数构建Huffman树,将Huffman树作为输出。

Huffman树中每一叶子结点代表一个label,在每一个非叶子节点处都需要作一次二分类,走左边的概率和走右边的概率,这里用逻辑回归的公式表示
正类别的概率:

负类别的概率:
![]()
其中,每个label都会又有一条路径,对于训练样本特征向量Xi和对应的labelYi,预测出来的Xi的样本属于所对应的label是Yi的概率为:
![]()
其中:

很明显,是不是觉得很熟悉?是的你没有看错,目前感觉和w2v没什么差别,就是预测变成了类别。
在用n个训练样本进行训练时,根据每个类别出现的次数作为权重来建Huffman树,出现次数多的类别的样本,路径就短,出现次数少的类别的样本,路径就长。经过计算,单个样本在经过训练时所需的时间复杂度应该是 hlog2(k) 。
但fastText在预测时,计算复杂度仍然是O(kh),因为预测时计算量确实很小,所以这可能也不是fastText的初衷所在。
在作者的paper中讲到,当类别的数量巨大时,计算线性分类器的计算量相当高,更准确的说,计算复杂度是 O(kh) ,k 是类别的数量,h 是文本特征的维度数。基于 Huffman 树的hierarchical softmax,可以将计算复杂度降到 O(hlog2(k)) 。
6.2 FastText实战
Facebook声称fastText比其他学习方法要快得多,能够训练模型“在使用标准多核CPU的情况下10分钟内处理超过10亿个词汇”,特别是与深度模型对比,fastText能将训练时间由数天缩短到几秒钟。
关于fastText具体实现原理,Facebook(2016)另外发表了两篇相关论文。
fastText 方法包含三部分:模型架构、层次 Softmax 和 N-gram 特征。
6.2.1 模型架构
fastText 模型架构如下图所示。fastText 模型输入一个词的序列(一段文本或者一句话),输出这个词序列属于不同类别的概率。序列中的词和词组组成特征向量,特征向量通过线性变换映射到中间层,中间层再映射到标签。fastText 在预测标签时使用了非线性激活函数,但在中间层不使用非线性激活函数。

fastText 模型架构和 Word2Vec 中的 CBOW 模型很类似。不同之处在于,fastText 预测标签,而 CBOW 模型预测中间词。
6.2.2 层次 Softmax
在某些文本分类任务中类别很多,计算线性分类器的复杂度高。为了改善运行时间,fastText 模型使用了层次 Softmax 技巧。层次 Softmax 技巧建立在哈弗曼编码的基础上,对标签进行编码,能够极大地缩小模型预测目标的数量。这个部分应该借鉴了word2vec的层次softmax思想。
其实fasttext使用的模型与word2vec的CBOW模型在结构上是一样的,不同的在于,word2vec CBOW的目标是通过当前词的前后N个词来预测当前词,在使用层次softmax的时候,huffman树叶子节点处是训练语料里所有词的向量。
而fasttext在进行文本分类时,huffmax树叶子节点处是每一个类别标签的词向量,在训练的过程中,训练语料的每一个词也会得到对应的词向量,输入为一个window内的词对应的词向量,hidden layer为这几个词的线性相加,相加的结果作为该文档的向量,再通过层次softmax得到预测标签,结合文档的真实标签计算loss,梯度与迭代更新词向量。
6.2.3 N-gram 特征
fastText 可以用于文本分类和句子分类。不管是文本分类还是句子分类,我们常用的特征是词袋模型(CBOW)。但词袋模型不能考虑词之间的顺序,因此 fastText 还加入了 N-gram 特征。“我 爱 她” 这句话中的词袋模型特征是 “我”,“爱”, “她”。这些特征和句子“她 爱 我” 的特征是一样的。如果加入 2-Ngram,第一句话的特征还有 “我-爱” 和“爱-她”,这两句话 “我 爱 她” 和 “她 爱 我” 就能区别开来了。当然啦,为了提高效率,我们需要过滤掉低频的 N-gram。
fasttext其实是由两部分组成的,一部分是文本分类,另一部分是词嵌入学习,接下来将分别从文本分类和词嵌入学习的实战来见识fasttext的能力。
6.2.4 对比fastext和word2vec的词嵌入能力
两者同样使用text8预料进行训练,同样使用default参数。

评测结果如下图所示。

该次测试用到了questions-words.txt,在网上找了好久,没有找到,于是利用glove提供的question-data文件夹自己合成了一个。
源码如下:

从前辈们使用fasttext 的经验总结上我可以学习到:fasttext模型简单,训练速度快,做出来的结果可以达到上线使用的标准。
nfasttext的作者之一,mikolov tomas是word2vec的作者,fasttext可以认为是word2vec的一种升级,速度更快,那么人们不禁要问这两者该如何选择呢?
n这里得提到一场评测,是word rank算法出来论文上作者对word2vec、fasttext、word rank进行的评测。wordrank是16年提出的一种基于排序算法的得到词向量的算法。不在本次学习内容之列。



左图布朗语料,右图text8语料 上的结果。
1.在语义类比中,三种模型在低频词语上表现相对较差,在高频词语上表现效果较好;
2.在语法类比中,FastText优于Word2Vec和WordRank 。FastText模型在低频词语上表现的相当好,但是当词频升高时,准确率迅速降低,而WordRank和Word2Vec在很少出现和很频 繁出现的词语上准确率较低;
3. FastText在综合类比中表现更好,最后一幅图说明整体类比结果与语法类比的结果比较相似,因为语法类比任务的数量远远多于语义类比,所以在综合结果中语法类比任务的结果占有更大的权重;
综上,WordRank更适合语义类比,FastText更适合不同语料库下所有词频的语法类比。
6.2.5 FastText用作文本分类
首先pip安装python接口的fasttext。

获取分类文本,直接使用清华大学的新闻文本。
数据格式:样本+样本标签。
如有自己的新闻文本可以按照以下代码,在py27环境下运行,同时当前目录必须有几个类别的文件夹,并且文件夹内有对应的新闻文本。(源码没了,就剩了个截图。。。以后我会注意的)

使用命令行的方式训练:

其测试结果:(p和r)

python写的话在fasttext的api上都有写该如何用。
对于同样的文本分类问题,有人用LSTM+MLP与fasttext进行了对比,即使使用了gpu,训练速度慢很多,并且无论怎么调参,准确率比fasttext的结果还要略低一点。综上所述,fasttext在文本分类的问题上简单又实用。
7 DSSM(sent2vec)
sent2vec是将一对短文本串映射到一对连续、低维度空间的特征向量,在该向量空间中文本串的语义相似度由cosine相似度计算。sent2vec通过使用2013年黄提出的dssm模型或2014年gao和shen提出的cdssm模型实现这种映射。微软官网给出了一个包含了源码及样例的压缩包,包中内容如下图所示,下载地址是:
https://www.microsoft.com/en-us/download/details.aspx?id=52365&from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fdownloads%2F731572aa-98e4-4c50-b99d-ae3f0c9562b9%2Fdefault.aspx

7.1 原理简析
Dssm原理
微软提出的DSSM有很强的针对工业应用性,是用来做BING搜索网页文档排序的。CDSSM只是加入了卷积-池化层,

DSSM将高维度离散文本特征映射到低维度密集语义空间,使用深度神经网络。第一个隐藏层有3w个单元,完成了单词的哈希。被哈希后的词特征接着被多层的非线性映射层映射,最后一层神经活动形成了语义空间的特征。
DSSM被用来做网页文档排序:1映射检索词向量到与题目相应的语义概念向量,然后计算文档和查询向量的cos相似度。
这部分公式很好理解,结合前面的DSSM结构图。接下来就好理解了。又是计算损失函数。

单词哈希化也是一个很重要的理解点。

原文是这么说的。但这么做有可能会产生词表示冲突(collision不知道咋翻译。。。),大意就是n-gram表示的单词有可能两个不同的单词用这样的表示会一样,然后傻傻分不清楚。。。。

基于字母3gram的单词n-gram方法

在他们的实现中,基于n-gram哈希化可以被视为一个固定的(即非自适应的)线性变换。前面DSSM的结构图,通过这个变化,一个检索词向量在输入层被映射成字母n-gram向量到更高一层。向量维度更低,DNN学习起来更有效。
其实由微软给的已训练好的模型的vocab我们能直观的看到哈希化。


nCDSSM论文中对词哈希的描述。CDSSM也是微软基于DSSM模型提出的,就是加入了卷积池化层。


7.2 样例测试
Sample/sent2vec中有一个例子的脚本程序run.bat。

里面包含着已经写好的操作,下面让我们来看看这些参数都是什么意思。
使用方法(参数设置):
/inSrcModel: 源模型,即,要嵌入源字符串的神经网络
/inTgtModel: 目标模型,即,要嵌入目标字符串的神经网络
/inSrcVocab: 源模型所用的词汇表
/inTgtVocab: 目标模型所用的词汇表
/inSrcModelType: 源模型类型,可选DSSM或CDSSM
/inTgtModelType: 目标模型类型,可选DSSM或CDSSM
/inSrcMaxRetainedSeqLength: 当使用卷积层提取局部特征时,源文本串开始的n个单词作为一个单词序列(gao2014称之为焦点),其余的作为词袋。通常n=10-20是推荐的,只有在相关模型是CDSSM时这个参数才有效。
/inTgtMaxRetainedSeqLength: t当使用卷积层提取局部特征时,目标文本串开始的n个单词作为一个单词序列(gao2014称之为焦点),其余的作为词袋。通常n=10-20是推荐的,只有在相关模型是CDSSM时这个参数才有效。
/inFilename: 输入句子对文件,每一行时一对短文本串,由缩进隔开
/outFilenamePrefix: 输出每对句子对的相似分值和语义向量。
这个包中的DSSM和CDSSM模型使用(查询和被点击的标题)对,从Bing查询日志文件中抽样得到的,如huang2013描述的一样。模型所在的路径是sample/sent2vec/dssm_model和cdssm_model。
作者提供了用来载入的源码和用来做语义映射的训练好的模型。代码由c#写成。同时也提供了DSSM模型的训练代码,该代码使用了CUDA6.5的GPU加速线性代数库实现的。
运行run.bat后生成了几个文件

这是作者给提供的句子对。

文件会生成cdssm和dssm两个模型生成的结果


同时,从run.bat文件中写的两个测试例子可以看出,一个是源模型、目标模型都用的dssm;另一个都用的cdssm。
7.3 训练一个DSSM模型
关于训练dssm给出的样例脚本是训练一个cdssm匹配qa(问答中)问题和谓词序列,正如(yih2015年)。我们需要几个步骤来处理训练数据训练cdssm。
1将训练文件中的句子对洗牌(顺序打乱),这些句子对是QA任务中的问题模式和推理链的对。
2生成句子的三元字母向量,使用单词哈希技术。我们定义前20个单词维每个文本串的焦点。需要注意的是如果要训练dssm,焦点的长度定义为一个单词。相应的训练脚本在sample/training/dssm_train.bat
3生成dssm训练的min-batch文件(用于批处理训练),在本例中,每个批包含1024个训练对。
4计算训练数据的噪声分布,为了噪声对比估计训练
5依据配置文件训练cdssm
6使用训练好的cdssm
其中在第5步,所需要的配置文件详细的描述了一个模型和训练时的参数。一些常用的参数如下:
BATCHSIZE // 最小批的大小,必须同第三步一致。
MAX_ITER // 最大迭代次数。
LEARNINGRATE // 随机梯度下降时用到的学习率,依据经验设定。
VALIDATEPROCESS // 一个客户提供的可执行的(或批处理的)拿到输入对和预测分值,然后生成特定任务的评估结果。
DEVICE // 当多gpu使用时要明确的gpu的编号,0代表第一个gpu,1代表第二个。
SOURCE_LAYER_DIM // 源模型隐藏层和输出层向量的维数,例如, "300,300,128" 代表前两个隐藏层都是300个节点,输出层是128。需要注意的是源模型输出层维数应与目标模型输出层维数相同。
TARGET_LAYER_DIM // 目标模型隐藏层和输出层向量的维数。
SOURCE_ARCH // 源模型的网络结构,例如 “1,0,0” 代表了一个第一层卷积,后两层全链接的三层网络结构,注意1代表卷积曾,0代表全链接层。
TARGET_ARCH // 目标模型的结构
MIRROR_INIT // 如果源和目标边由完全相同特征词汇表及网络结构,设置为1,并且两个网络使用相同初始数值初始化,如果不同则设置为0。
BIDSSM // 0代表源和目标模型使用同一个模型,1代表使用了不同模型
MATH_LIB // 选择使用GPU还是CPU训练模型
CPU_MATH_LIB_THREAD_NUM // 训练时的线程数,只有在使用cpu训练时有效
因为dssm或者cdssm都是神经网络对模型,其中一个作源模型另一个做目标模型,用户可以使用相同或不同的网络结构设计源模型和目标模型。
其中一些案例训练脚本已经被提供在sample/training/文件中,例如使用全链接多层网络做源模型和目标模型(对应文件是dssm_train.bat和dssm.config.txt),或者源模型和目标模型都用卷积网络(对应文件是cdssm.train.bat和cdssm.config.txt),或者目标模型使用全链接、源模型使用卷积(对应文件是mix_train.bat和mix.config.txt)
更多推荐



所有评论(0)