FastText原理及实践

FastText是Facebook于16年提出的一个轻量级的模型,Fasttext最大的特点是模型简单,只有一层的隐层以及输出层,因此训练速度非常快,在普通的CPU上可以实现分钟级别的训练。同时在多个标准的测试数据集上,Fasttext在文本分类的准确率上,和一些深度学习的方法接近。

一, 原理

1, 模型结构

​ FastText的网络结构与word2vec中的CBOW很相似,主要包含一个投影层和一个输出层,如下图所示。

image-20191028225220556

​ 对于一个有N个文本的集合,损失函数为交叉熵损失,及负对数极大似然函数。

\[-\frac{1}{N}\sum_{n=1}^Ny_n\log(f(BAx_n))\]

​ 其中 \(x_n\) 为第 \(n\) 个文本归一化之后的词袋特征,\(y_n\) 是类别,\(A\) 为隐藏层(投影层)的权重矩阵(a look-up table over the words),\(B\) 为输出层的权重矩阵。每个特征会首先根据 id 映射到 \(A\) 中对应的向量,然后,对计算 \(n\) 个特征向量的平均作为整个文本的向量表示,最后,将文本向量经过输出层,采用 \(softmax\) 函数 \(f\) 计算得到该文本在每个类别对应的概率表示。

\[w_i = Ax_i \\ h_{doc} = \frac{1}{n}\sum_{i=1}^nw_i \\ z = sigmoid(Bh_{doc})\]
2, 层次softmax

​ 标准softmax的复杂度为 \(O(kh), k\) 为总类别数,\(h\) 为文本向量的维度。当类别数很大时,模型的计算会耗费大量的时间和资源。为了提高速度,FastText将输出层的softmax改为基于哈夫曼树的层次softmax,计算时间复杂度可以缩减为 \(O(h\log_2k)\)。层次softmax会根据各个类别出现的频率进行排序,如下图所示,

11

​ 其中,每个叶节点表示一个类别,当叶节点的深度越深时,其概率将越低,假设一个叶节点的深度为 \(l+1\),其父节点列表为 \(n _ { 1 } , \ldots , n _ { l }\),则该叶节点的概率计算公式为:

\[P \left( n _ { l + 1 } \right) = \prod _ { i = 1 } ^ { l } P \left( n _ { i } \right)\]
3, N-gram

​ 由于隐层是通过简单的平均得到的,丢失了词顺序的信息,为了弥补这个不足,Fasttext增加了N-gram的特征。假设某篇文章只有3个词,\(w_1, w_2, w_3\),N-gram的N取2,则输入为 \(w_1, w_2, w_3\) 和 \(bigram: w_1w_2,w_2w_3\) 的embedding向量,文章的隐层可表示为:

\[h=\frac{1}{5}(w_1+w_2+w_3+w_{12}+w_{23})\]

​ 具体实现上,由于N-gram的量远比word大的多,完全存下所有的n-gram也不现实。由于N-gram表示的稀疏性(特别是对于短文本),Fasttext采用了Hash trick的方式,对n-gram进行哈希操作,哈希到同一个桶的所有N-gram共享一个embedding vector。如下图所示:

image-20191029175844736

4, FastText和Word2Vec的异同

​ fastText和word2vec的CBOW模型结构非常相似,都包含一个隐层和一个输出层,softmax都是用基于哈夫曼树的层次softmax;

不同处:

  • CBOW的目的是在输入层得到词向量,fastText的目的则是得到文本的分类标签。
  • CBOW使用窗口内的上下文预测中心词,因此得到的词向量可以表达词之间的相对位置,可以用于别的NLP任务;FastText使用一整个文本的词及N-gram预测文本标签,虽然输入层也可以产出词向量,更多包含的则是该词对类别标签的贡献信息,很少迁移到别的任务(个人理解)。

二, 实践

FaceBook FastText 工具的使用:https://github.com/facebookresearch/fastText