0%

FastText 的原理与实现

Fasttext 特点是模型比较简单,只有三层结构(输入,隐藏和输出)。因此训练速度和推理速度都相当快而且精度不差。FastText 模型和 Word2Vec 的 CBOW 有些类似。相同点是隐藏层都有求均值的运算,不同点是 CBOW 模型是通过上下文来预测中心词,而 FastText 预测的是分类标签。

1. FastText 原理过程

如上图所示,FastText 由三部分构成分别是输入层、隐藏层和输出层。它运算过程是这样的:

  • 首先输入 inputs 经过 Embedding 层转化为词向量矩阵,
  • 然后对每个词的词向量求平均,得到文本的向量表达(得到的结果是 \(M*1\) 的矩阵,其中 \(M\) 代表 \(M\) 个单词)
  • 再经过线性分类器输出每个类别的概率

输入的词向量可以是预先训练好的,也可以随机初始化跟着分类任务一起训练。

2. FastText 的优点

  • FastText 在保持高精度的情况下,加快了训练过程和测试速度
  • FastText 不需要预训练好的词向量,它会自己训练词向量
  • FastText 两个重要的优化:
    • 使用层级 softmax 提升效率
    • 采用了 char-level 的 n-gram 作为附加特征

2. 代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class FastText(nn.Module):
def __init__(self, vocab_size, embedding_size, output_shape):
super(FastText, self).__init__()
self.embedding_1 = nn.Embedding(
num_embeddings=vocab_size,
embedding_dim=embedding_size,
padding_idx=vocab_size - 1
)

self.embedding_2 = nn.Embedding(
num_embeddings=vocab_size,
embedding_dim=embedding_size,
padding_idx=vocab_size - 1
)

self.embedding_3 = nn.Embedding(
num_embeddings=vocab_size,
embedding_dim=embedding_size,
padding_idx=vocab_size - 1
)

self.dropout = nn.Dropout(0.2)
self.fc1 = nn.Linear(embedding_size * 3, 256)
self.fc2 = nn.Linear(256, output_shape)

def forward(self, x):
out_1 = self.embedding_1(x.long())
out_2 = self.embedding_2(x.long())
out_3 = self.embedding_3(x.long())
out = torch.cat((out_1, out_2, out_3), -1)

out = torch.mean(out, dim=1)
out = self.dropout(out)
out = self.fc1(out)
out = F.relu(out)
out = self.fc2(out)
return out