目录
参考word2vec基本原理:https://daiwk.github.io/posts/nlp-word2vec.html
paper:
【提出fasttext的paper】Bag of Tricks for Efficient Text Classification
Enriching Word Vectors with Subword Information
website: https://fasttext.cc/【有pretrained-vectors可以下载】
在文本分类任务中,fastText(浅层网络)往往能取得和深度网络相媲美的精度,却在训练时间上比深度网络快许多数量级。在标准的多核CPU上, 能够训练10亿词级别语料库的词向量在10分钟之内,能够分类有着30万多类别的50多万句子在1分钟之内。
softmax回归被称作多项逻辑回归(multinomial logistic regression),是逻辑回归在处理多类别任务上的推广。
softmax中,我们需要对所有的K个概率做归一化,这在\(|y|\)
很大时非常耗时。分层softmax的基本思想是使用树的层级结构替代扁平化的标准Softmax,在计算\(P(y=j)\)
时,只需计算一条路径上的所有节点的概率值,无需在意其它的节点。
树的结构是根据类标的频数构造的霍夫曼树。
\(L(y_j)\)
。\[
p(y_j)=\prod _{l=1}^{L(y_j)-1}\sigma (\left \lfloor n(y_j,l+1)=LC(n(y_j,l)) \right \rfloor \cdot \theta _{n(y_j,l)} ^TX)
\]
其中,
\(l\)
表示第几层(从1开始);\(\sigma (\cdot )\)
表示sigmoid函数;\(LC(n)\)
表示n节点的左孩子;\(\left \lfloor \right \rfloor \)
是一个特殊的函数,定义如下:\[
\left \lfloor x \right \rfloor =\left\{\begin{matrix}
1, if x =true
\\ -1,otherwise
\end{matrix}\right.
\]
\(\theta _{n(y_j,l)}\)
是中间节点\(n(y_j,l)\)
的参数高亮的节点和边是从根节点到\(y_2\)
的路径,路径长度\(L(y_2)=3\)
,
\[
\\P(y_2)=P(n(y_2,1),left)P(n(y_2,2),left)P(n(y_2,3),right)
\\=\sigma (\theta _{n(y_2,1)}^TX) \cdot \sigma (\theta _{n(y_2,2)}^TX) \cdot \sigma (-\theta _{n(y_2,3)}^TX)
\]
于是,从根节点走到叶子节点\(y_2\)
,其实是做了3次二分类的lr。通过分层的Softmax,计算复杂度一下从\(|K|\)
降低到\(log_2|K|\)
。
似乎暂时没有tf的实现,有keras的实现:https://github.com/jmhessel/keras/blob/master/keras/layers/advanced_activations.py#L268-L395
基本思想是将文本内容按照字节顺序进行大小为N的滑动窗口操作,最终形成长度为N的字节片段序列。n-gram产生的特征只是作为文本特征的候选集,你后面可能会采用信息熵、卡方统计、IDF等文本特征选择方式筛选出比较重要特征。
CBOW模型的基本思路是:用上下文预测目标词汇。
\({x_1,...,x_c}\)
组成,\(x_i\)
是一个one-hot后的V维向量;权重:
因为词库V往往非常大,使用标准的softmax计算相当耗时,于是CBOW的输出层采用的是分层Softmax。
隐层的输出是C个上下文单词向量先求和,然后乘以W,再取平均,得到的一个N维向量:
\[
h=\frac{1}{C}W \sum ^C_{i=1}x_i
\]
然后计算输出层的每个节点:\(u_j=v'_{w_j}^T\cdot h\)
。
其中的\(v'_{w_j}\)
是矩阵W’的第j列(W’是N行V列,即,第j个词对应的N维向量),\(u_j\)
就是一个N维向量和N维向量的转置乘出来的一个值,
最后,\(u_j\)
作为softmax的输入,得到\(y_j\)
:
\[
y_j=p(w_{y_j}|w_1,...,w_C)=\frac {exp(u_j)}{\sum ^V_{j'=1}exp(u_{j'})}
\]
定义损失函数,objective是最大化给定输入上下文,target单词的条件概率如下:
更新W’:
更新W:
参考技术干货 | 漫谈Word2vec之skip-gram模型
word2vec把语料库中的每个单词当成原子的,它会为每个单词生成一个向量。这忽略了单词内部的形态特征,比如:“apple” 和“apples”,”xx公司”和”xx”,两个单词都有较多公共字符,即它们的内部形态类似,但是在传统的word2vec中,这种单词内部形态信息因为它们被转换成不同的id丢失了。
为了克服这个问题,fastText使用了字符级别的n-grams来表示一个单词。例如,apple的3-gram如下:
“<ap”, “app”, “ppl”, “ple”, “le>”
<表示前缀,>表示后缀。进一步,我们可以用这5个trigram的向量叠加来表示“apple”的词向量。
好处:
注:当然,最新的方法其实是BPE。
fastext的架构图如下:
相同点:
和CBOW一样,fastText模型也只有三层:输入层、隐含层、输出层(Hierarchical Softmax),输入都是多个经向量表示的单词,输出都是一个特定的target,隐含层都是对多个词向量的叠加平均。
不同点:
对于N篇文档,最小化针对所有文档的 negative loglikelihood(其实就是多分类的交叉熵):
\[
-\frac {1}{N}\sum ^N_{n=1}y_nlog(f(BAx_n))
\]
其中,\(x_n\)
是第n篇文档的normalized bag of features。A是基于word的look-up table,即词的embedding向量,\(Ax_n\)
是将word的embedding向量找到后相加或者取平均,得到hidden向量。B是函数f的参数,f是softmax。
编译好的bin地址:https://daiwk.github.io/assets/fasttext
格式(空格分割):
__label__xx w1 w2 w3 ...
./fasttext supervised -input train_demo_fasttext.txt -output haha.model
高级参数:
-minn 1 -maxn 6: 不用切词,1-6直接n-gram
格式(空格分割):
__label__00 key w1 w2 w3 ...
其中,key可以中间有\1等任何分隔符,但key里面不能有空格
cat test_demo_fasttext.txt | ./fasttext predict-prob haha.model.bin -
key __label__xx probability
cat test_demo_fasttext.txt | ./fasttext print-vectors haha.model.bin
xxxx/pip install cython
xxxx/pip install fasttext
一行代码自动调参,支持模型压缩指定大小,Facebook升级FastText
主要有以下几个:
-autotune-validation validation file to be used for evaluation
-autotune-metric metric objective {f1, f1:labelname} [f1]
-autotune-predictions number of predictions used for evaluation [1]
-autotune-duration maximum duration in seconds [300]
-autotune-modelsize constraint model file size [] (empty = do not quantize)