承接上文自然语言处理-词向量模型
不同模型对比
-
CBOW
一般窗口大小是奇数,比如5,by a red bus in,
要预测的值是red,red的上文是 by a,下文是bus in ,上下文共4个词。
输入上下文,预测中间值。
-
Skipgram
输入red,预测上下文4个词。
输入中间值,预测上下文。
通过Gensim工具包进行训练,无论选择哪种模型,得到的结果都差不多。
Skip-gram模型所需要的训练数据集
对于当前每一个窗口,输入数据和得到的标签(要得到的预测结果)之间的差异
有了输入和输出数据,去词库表中查询这个词对应的词向量,神经网络每次训练都会更新词库表中输入数据对应的词向量。
比如词库表中有5万个词,那么就是一个5万的分类任务,对于最后一层softmax层计算量是非常巨大的。
训练的过程,其实跟神经网络是一样的,通过前向传播得到损失函数,然后计算Error值,然后反向传播更新权重参数。现在不仅仅要更新权重参数,还要更新输入数据。
做一个5万的分类任务,计算量巨大,如何解决该问题?
通过词A预测它后面的词B,词B的可能性太多了,如果词库中有10万个词,那么就有10万种可能性。
A词和B词都作为输入,让神经网络判断下B这个词是A这个词后面的可能性有多大。希望神经网络预测A词后面是B词的概率跟1越接近越好。它们之间相差越多,就意味着需要的更新越多,越去调节当前的输入和网络的权重参数。
原来是10万分类的问题,现在转换成了二分类的问题:A后面的词是不是B。
但现在的问题是预测出来的结果都是1,无法进行比较好的训练。
改进方案就是加入一些负样本(负采样模型)
创建一些词,只要不是语料库当中上下文的词,标签都是0,这些词就是负样本,是上下文的这些词叫正样本。
负采样的个数是多少个比较合适,通常情况大概3个或5个0比较合适。
原来是看下输出是什么
现在是将输入和输出都当作输入,看下输出是否为输入后面的一个词。
词向量训练的过程
- 初始化词向量矩阵
Embedding是要始终维护的词向量大表,Context是output word的结果。
先找输入not词和输出aaron、taco、thou在词库表中对应的词向量。通过神经网络反向传播计算更新参数,此时不光更新权重参数矩阵W,也会更新输入数据。
in和out都要更新,负采样的0也要更新。
词向量一开始是随机的,随着每次训练的更新,越接近真实的情况,越接近计算机能够理解的情况,Embedding词汇表中的向量越来越精准。