Skip to content

Latest commit

 

History

History
59 lines (31 loc) · 4.61 KB

Fasttext解读(1).md

File metadata and controls

59 lines (31 loc) · 4.61 KB

我先说一个小问题,估计很多人也有疑惑。

看了很多文章,有的说是fasttext是CBOW的简单变种,有的说是Skip-gram的变种。究竟哪个是对的?

带着这个问题,我们来聊一聊Fasttext。首先Fasttext涉及到两个论文:

  1. 第一个是Bag of Tricks for Efficient TextClassification(201607)。它解决的问题是使用Fasttext进行文本分类
  2. 第二个是Enriching Word Vectors with Subword Information(201607) 。它解决的是使用Fasttext训练词向量。

今天这个文章,主要谈一下Bag of Tricks for Efficient Text Classification 这个论文 ,主要涉及到的就是文本分类的问题。

Fasttext用作文本分类,做到了速度和精读的一个平衡:标准多核CPU情况下,不到十分钟,可以训练超过十亿个单词。不到一分钟,可以对50万个句子在312千个类别中进行分类。

这么说,其实不太明显,简单算一下。假设每个句子含有20个单词,那么十亿个单词对应就是五千万个句子,换句话讲在多核CPU的条件下,一分钟左右可以训练500万个句子。

和Bert比较一下,在GPU条件下,8个小时训练300万条数据左右。相比之下Fasttext的这个速度是真的太快了。

在这个论文中,也就是使用做文本分类的Fasttext,使用的是CBOW的架构。

注意哦,强调一遍,Fasttext用在文本分类,模型架构使用的是CBOW的变种。(我这句话的意思不是说使用Skip-gram不可以,而是CBOW在理解文本分类的时候更加的容易理解)

这里和Word2vec的CBOW有两个区别:

  1. 第一,使用类别标签替换了中心词。
  2. 第二,使用句子中所有单词作为输入,而不再是单单的针对滑动窗口中的单词。

这两个点如果我们自己考虑,也很容易想到。

为什么这么说呢?先说第二点。我现在要做的是针对文本进行分类,所以对于我的输入需要转换到整体这个句子来看,才能使对一个句子的特征表达。

再说第一点,我们知道在Wrod2vec中,我们使用的是中心词作为输出,而且使用了霍夫曼作为输出层。

非叶子点上的向量为了我的二分类提供计算,叶子节点为整个词汇表中所有词汇的向量。两个向量都会随着模型而训练。

如果要做分类,我们可以想一下叶子节点和非叶子节点的变化。

首先叶子节点对应的是所有类别。如果说我们的类别有5000个,那么对应到Word2vec,我们就有着5000个词汇。想一下是不是这么对应。

非叶子节点其实没什么变化,因为它没有什么实际含义,只是为二分类提供计算。

在这里还想说一下,word2vec中的叶子节点也就是词向量更新之后我们最后是要的,但是对于fasttext其实不会用到这个,因为我们是对文本进行分类,只需要保存了模型权重在预测的时候可以预测就可以了。

还想谈一下词向量初始化的问题,模型训练开始的时候,词向量随机初始化就可以,模型训练结束之后,我们在预测阶段直接使用这个词向量就可以(就是随着模型训练而更新的这个词向量)。

对这个论文还有一个很有意思的点,就是N-gram就是fasttext的模型的输入不仅仅针对的是每个单词,为了加入词序信息,还加入了n-gram信息。

需要注意的一个细节是,这里的n-gram针对的是word,而不是char。对应到中文,应该对应的是分词之后的词,而不是字。但是我自己认为这么对应过来不太好理解。

中文的字做n-gram貌似也有词序信息。但是英文的char-level的n-gram很难说针对这个句子提供一个语序信息。大家理解一下就好。

还有一个问题想说一下,使用了n-gram信息之后,词表肯定是变大了的。你需要的n的内容越多,比如你想要n=1orn=2orn=3等等吧,n的取值范围越大,你的词表越大。

这就会出现一个问题训练非常缓慢。这点很容易理解,参数越多训练当然越慢。

针对这个问题,怎么解决呢?使用哈希。

我举个简单的例子,不一定准确,"我/爱/中国/共产党",我在更新的时候,把'我','爱','中国','共产党'我们都使用同一个参数来代表(这种情况很难遇见,理解一下就好),那么在更新训练参数的时候,我只需要更新一个参数就把这个四个词都更新了,当然会快一点。

但是会出现一个问题,就是精度的问题。这个过程,不知道大家有咩有想到和albert很类似。哈希这个过程我自己感觉有点共享参数的意思。