word2vec原理总结

一篇很好的入门博客,http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/

他的翻译,https://www.jianshu.com/p/1405932293ea

可以作为参考的,https://blog.csdn.net/mr_tyting/article/details/80091842

有论文和代码,https://blog.csdn.net/mr_tyting/article/details/80091842

word2vector,顾名思义,就是将语料库中的词转化成向量,以便后续在词向量的基础上进行各种计算。

最常见的表示方法是counting 编码。假设我们的语料库中是如下三句话:

I like deep learning
I like NLP
I enjoy flying
利用counting编码,我们可以绘出如下矩阵:

word2vec原理总结

假设语料库中的单词数量是N,则上图矩阵的大小就是N*N,其中的每一行就代表一个词的向量表示。如第一行
0 2 1 0 0 0 0
是单词I的向量表示。其中的2代表I这个单词与like这个词在语料库中共同出现了2次。

但这种方法至少有三个缺点:

[En]

But this approach has at least three drawbacks:

  • 1是词语数量较大时,向量维度高且稀疏,向量矩阵巨大而难以存储
  • 2是向量并不包含单词的语义内容,只是基于数量统计。
  • 3是当有新的词加入语料库后,整个向量矩阵需要更新

尽管我们可以通过SVD来降低向量的维度,但是SVD本身却是一个需要巨大计算量的操作。
很明显,这种办法在实际中并不好用。我们今天学习的skip gram算法可以成功克服以上三个缺陷。它的基本思想是首先将所有词语进行one-hot编码,输入只有一个隐藏层的神经网络,定义好loss后进行训练,后面我们会讲解如何定义loss,这里暂时按下不表。训练完成后,我们就可以用隐藏层的权重来作为词的向量表示!!
这个思想乍听起来很神奇是不是?其实我们早就熟悉它了。auto-encoder时,我们也是用有一个隐藏层的神经网络进行训练,训练完成后,丢去后面的output层,只用隐藏层的输出作为最终需要的向量对象,藉此成功完成向量的压缩。

Word2Vec工作流程

Word2Vec有两种训练方法,一种叫CBOW,核心思想是从一个句子里面把一个词抠掉,用这个词的上文和下文去预测被抠掉的这个词;第二种叫做Skip-gram,和CBOW正好反过来,输入某个单词,要求网络预测它的上下文单词。下面以Skip-gram为例介绍,

1、word2Vec只是一个三层 的神经网络。
2、喂给模型一个word,然后用来预测它周边的词。
3、然后去掉最后一层,只保存input_layer 和 hidden_layer。
4、从词表中选取一个词,喂给模型,在hidden_layer 将会给出该词的embedding repesentation。

使用神经网络进行训练,一般有以下步骤:

[En]

To train with neural network, there are generally the following steps:

准备好data,即X和Y
定义网络结构

[En]

Define the network structure

定义好loss
选择合适的优化器

[En]

Choose the right optimizer

进行迭代训练
存储训练有素的网络

[En]

Store a trained network

首先,构建训练数据

[En]

First, construct training data

假设我们的语料库中只有一句话:The quick brown fox jumps over the lazy dog.

这句话中共有8个词(这里The与the算同一个词)。skip gram算法是怎么为这8个词生成词向量的呢?

其实非常简单,(x,y)就是一个个的单词对。比如(the,quick)就是一个单词对,the就是样本数据,quick就是该条样本的标签。
那么,如何从上面那句话中生成单词对数据呢?答案就是n-gram方法。多说不如看图:

word2vec原理总结

我们从词的角度扫描这个句子,每次扫描一个词,我们从左右两个词中取出总共四个词,并以扫描的词作为我们的训练数据形成词对。

[En]

We scan this sentence in terms of words, and every time we scan a word, we take out a total of four words from each of the left and right words, and form word pairs with the scanned words as our training data.

以下是两个细节。一种是从要扫描的单词的左侧和右侧提取两个单词。这里的2称为窗口大小,可以调整。最好使用由哪个窗口生成的单词对进行训练,这需要对特定问题进行具体分析。一般来说,取5是一个很好的经验值。也就是说,从左到右取5个词,总共10个词。第二个细节是,扫描句子开头和结尾的词时,可以取的词的对数较少,这不影响全局,忽略它。

[En]

Here are two details. One is to take two words from the left and right of the words to be scanned. The 2 here is called * window size * , which can be adjusted. It is best to use the word pairs generated by which window to train, which requires specific analysis of specific problems. Generally speaking, taking 5 is a good empirical value. That is, take 5 words from left and right, a total of 10 words. The second detail is that when the words at the beginning and end of a sentence are scanned, there are fewer logarithms of words that can be taken, which does not affect the overall situation, ignore it.

这里我们需要停下来细细琢磨下,我们这样取单词对作为训练数据的目的何在?以(fox,jumps)为例,jumps可以理解为fox的上下文,我们将fox输入神经网络时,希望网络能够告诉我们,在语料库的8个单词中,jumps是更可能出现在fox周围的。
你可能会想,(fox,brown)也是一个单词对,它输入神经网络后,岂不是希望神经网络告诉我们,在8个单词中,brown是更可能出现在fox周围?如果是这样,那么训练完成后的神经网络,输入fox,它的输出会是brown和jumps的哪一个呢?
答案是取决于(fox,brown)和(fox,jumps)两个单词对谁在训练集中出现的次数比较多,神经网络就会针对哪个单词对按照梯度下降进行更多的调整,从而就会倾向于预测谁将出现在fox周围。

第二,以数字方式表示词对

[En]

Second, digitally represent word pairs

上面我们获得了许多单词对作为训练数据,但是神经网络不能直接接收和输出字符串形式的单词对,所以需要将单词对转化为数字的形式。方法也很简单,就是用one-hot编码,如下图所示:

word2vec原理总结

(the,quick)单词对就表示成【(1,0,0,0,0,0,0,0),(0,1,0,0,0,0,0,0)】。这样就可以输入神经网络进行训练了,当我们将the输入神经网络时,希望网络也能输出一个8维的向量,并且第二维尽可能接近1(即接近quick),其他维尽可能接近0。也就是让神经网络告诉我们,quick更可能出现在the的周围。当然,我们还希望这8维向量所有位置的值相加为1,因为相加为1就可以认为这个8维向量描述的是一个概率分布,正好我们的y值也是一个概率分布(一个位置为1,其他位置为0),我们就可以用交叉熵来衡量神经网络的输出与我们的label y的差异大小,也就可以定义出loss了。

3、_网络结构 _网络结构如下,它的隐藏层并没有激活函数,但是输出层却用了softmax,这是为了保证输出的向量是一个概率分布。

_4、隐藏层
_

输出层的神经元数目应为8个,这样才能输出8维矢量。那么,隐藏层中应该有多少神经元呢?

[En]

The number of neurons in the output layer should be 8, so that an 8-dimensional vector can be output. So how many neurons should there be in the hidden layer?

这取决于我们希望得到的词向量是多少维,有多少个隐藏神经元词向量就是多少维。每一个隐藏的神经元接收的输入都是一个8维向量,假设我们的隐藏神经元有3个(仅仅是为了举例说明使用,实际中,google推荐的是300个,但具体多少合适,需要你自己进行试验,怎么效果好怎么来),如此以来,隐藏层的权重就可以用一个8行3列的矩阵来表示,这个8行3列的矩阵的第一行,就是三个隐藏神经元对应于输入向量第一维的权重,如下图所示:

word2vec原理总结

网络训练完成后,8行3列矩阵的每一行都是一个单词向量!如下图所示:

[En]

After the network training is completed, each row of the 8-row-3-column matrix is a word vector! As shown in the following figure:

word2vec原理总结

网络的输入是one-hot编码的单词,它与隐藏层权重矩阵相乘实际上是取权重矩阵特定的行,如下图所示:

word2vec原理总结

这意味着,隐藏层实际上相当于一个查找表,其输出是输入单词的单词向量。

[En]

This means that the hidden layer is actually equivalent to a lookup table, and its output is the word vector of the input word.

5、输出层

当我们从隐含层得到单词的词向量时,我们必须通过输出层。

[En]

When we get the word vector of a word from the hidden layer, we have to go through the output layer.

输出层的神经元数量和语料库中的单词数量一样。每一个神经元可以认为对应一个单词的 输出权重,词向量乘以该 输出权重就得到一个数,该数字代表了输出神经元对应的单词出现在输入单词周围的可能性大小,通过对所有的输出层神经元的输出进行softmax操作,我们就把输出层的输出规整为一个概率分布了。如下图所示:

word2vec原理总结

这里要注意的一件事是,我们所说的是单词出现在输入单词周围的概率,输入单词包含单词的前面和后面。

[En]

One thing to note here is that what we say is the probability that the word appears around the input word, which contains both the front and the back of the word.

前面,我们表示,skip gram算法生成的词向量可以包含语义信息,也就是说,语义相近的词其词向量也相近。这里,我们给一个直觉的解释。
首先,语义相似的词往往有相似的上下文。这是什么意思?举个例子,如果两个词的意思相似,那么它们的使用场景也是相似的,它们周围的词也大体相似或相同。

[En]

First of all, words with similar semantics often have similar contexts. What does this mean? For example, if the meanings of the words “smart” and “smart” are similar, their usage scenarios are also similar, and the words around them are largely similar or the same.

语义相似的词具有相似的上下文,因此我们的神经网络在训练过程中为相似的词产生相似的输出向量。互联网是如何做到这一点的?答案是,经过训练,网络可以为语义相似的词生成相似的词向量。因为此时输出层已经训练好了,不会改变。

[En]

Words with similar semantics have similar contexts, so our neural network produces similar output vectors for similar words in the process of training. How does the Internet do this? The answer is that after the training, the network can generate similar word vectors for words with similar semantics. Because at this time the output layer has been trained and will not change.

6、负采样

我们知道对于训练语言模型来说,softmax层非常难算,毕竟你要预测的是当前位置是哪个词,那么这个类别数就等同于词典规模,因此动辄几万几十万的类别数,算softmax函数当然很费力啦。但是,如果我们的目标不在于训练一个精准的语言模型,而只是为了训练得到语言模型的副产物-词向量,那么其实只需要用这里隐含的一个计算代价更小的”子任务”就好啦。

想一想,给你10000张写有数字的卡片,让你找出其中的较大值,是不是特别费力?但是如果把里面的较大值事先抽出来,跟五张随机抽取的卡片混到一起,让你选出其中的较大值,是不是就容易多啦?

负抽样就是这个想法,即不是直接让模型从整个词汇表中找到最有可能的单词,而是直接给出单词(即正例)和几个随机抽样的噪声词(即反例)。只要模型能从中找到合适的词语,就会被认为达到了目标。因此,与这个想法相对应的目标函数是:

[En]

Negative sampling is this idea, that is, instead of directly letting the model find the most possible words from the whole vocabulary, it is directly given the word (that is, positive examples) and several randomly sampled noise words (that is, negative examples). As long as the model can find the right words from this, it will be considered to achieve the goal. So the objective function corresponding to this idea is:

word2vec原理总结

在tensorflow里面实现的word2Vec,vocab_szie并不是所有的word的数量,而且先统计了所有word的出现频次,然后选取出现频次最高的前50000的词作为词袋。具体操作请看代码 tensorflow/examples/tutorials/word2vec/word2vec_basic.py,其余的词用unkunk代替。
该算法采用了一种所谓的“负采样”操作,允许样本一次只更新一小部分权值矩阵,减少了训练过程中的计算压力。

[En]

A so-called “negative sampling” operation is adopted, which allows a sample to update only a small part of the weight matrix at a time, reducing the computational pressure in the training process.

举例来说:一个input output pair如:(“fox”,”quick”),由上面的分析可知,其true label为一个one−hot向量,并且该向量只是在quick的位置为1,其余的位置均为0,并且该向量的长度为vocab size,由此每个样本都缓慢能更新权重矩阵,而”负采样”操作只是随机选择其余的部分word,使得其在true label的位置为0,那么我们只更新对应位置的权重。例如我们如果选择负采样数量为5,则选取5个其余的word,使其对应的output为0,这个时候output只是6个神经元,本来我们一次需要更新300∗10,000参数,进行负采样操作以后只需要更新300∗6=1800个参数。

Original: https://www.cnblogs.com/bnuvincent/p/11296343.html
Author: Alexander
Title: word2vec原理总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/7605/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

发表回复

登录后才能评论
免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部