deep_learning 05. word2vec and fasttext

开始的话:
从基础做起,不断学习,坚持不懈,加油。
一位爱生活爱技术来自火星的程序汪

今天开始好好整理下 N e u r a l Neural Neural N e t w o r k Network Network E m b e d d i n g Embedding Embedding的相关知识。初步预计包括: w o r d 2 v e c word2vec word2vec g l o v e glove glove f a s t t e x t fasttext fasttext e l m o elmo elmo b e r t bert bert。希望能尽快整理出来。

话不多说,先开始我们今天的 w o r d 2 v e c word2vec word2vec f a s t t e x t fasttext fasttext

按照惯例先上图

D N N DNN DNN中的 c b o w cbow cbow s k i p skip skip- g r a m gram gram

w o r d 2 v e c word2vec word2vec之前,怎么表示词向量呢?除了 o n e one one- h o t hot hot之外,就已经有用神经网络 D N N DNN DNN来训练词向量来处理词与词之间的关系了。一般采用的是两层神经网络:隐藏层、输出层(输入层一般不算。)

举个栗子:
c b o w cbow cbow C o n t i n u o u s Continuous Continuous B a g Bag Bag- o f of of- W o r d s Words Words)模型为例:
假设输出向量维度为5:
词表大小为10:
输入是某一个中心词(图中的 w t w_t wt)的上下文相关的词(图中除了 w t w_t wt以外的词,用 o n e one one _ h o t hot hot编码这4个词),从输入层到隐藏层的权重为 10 ∗ 5 10*5 105的矩阵,权重是随机初始化的。输入是 4 ∗ 10 4*10 410的矩阵,输入层到隐藏层的权重是 10 ∗ 5 10*5 105的矩阵。这样通过下标对应位置上的随机初始化的向量就是输入的4个词的向量,就得到了一个 4 ∗ 5 4*5 45的矩阵。然后将这个 4 ∗ 5 4*5 45的矩阵和输出层的神经元(权重也是随机初始化的大小为 5 ∗ 10 5*10 510)相乘,然后经过线性变化再加和求平均,这样就得到了词汇表中所有词的 s o f t m a x softmax softmax概率。我们训练的目标是期望中心词 w t w_t wt的概率是最大的,并输出这特定的一个词 w t w_t wt的词向量(也就是输入层到隐藏层那个权重举证对应的概率最大位置的向量。通过反向传播算法,经过反复的迭代,就可以训练得到很不错的词向量了。

结合图看看

这就是我理解的 D N N DNN DNN中的词向量产生的大致过程。

w o r d 2 v e c word2vec word2vec中的 c b o w cbow cbow s k i p skip skip- g r a m gram gram

这和 w o r d 2 v e c word2vec word2vec中的 c b o w cbow cbow s k i p skip skip- g r a m gram gram模型还是有许多地方是不一样的。
区别:
第一:从隐藏层到输出层之间,替换掉了线性变换和激活的操作,而是简单的所有向量加和求平均的操作,还是以上面的例子:也就是对四个词向量加和求平均,得到一个向量来表示。
第二:从隐藏层到输出层之间,替换掉了 s o f t m a x softmax softmax,取而代之的是霍夫曼树。霍夫曼树的叶子节点就是 v o c a b vocab vocab_ s i z e size size大小的词。

根据词表中的各个单词的 c o u n t count count来构建霍夫曼树。
这样就满足了高频词的路径更短,符合贪心优化的思想
另外之前的计算量为 O ( D ) O(D) O(D),现在变为了 O ( l o g 2 D ) O(log_2D) O(log2D)

w o r d 2 v e c word2vec word2vec中,采用的是二元逻辑回归的方法:
沿着左子树走,为负类,编码为 1 1 1
沿着右子树走,为正类,编码为 0 0 0
s i g m o i d sigmoid sigmoid判断正类和负类:
正类:
P ( + ) = σ ( x w T θ ) = 1 1 + e − x w T θ P(+)=σ(x_w^Tθ)=\frac{1}{1+e^{-x_w^Tθ}} P(+)=σ(xwTθ)=1+exwTθ1
负类:
P ( − ) = 1 − P ( + ) P(-)=1 - P(+) P()=1P(+)
x w x_w xw 当前内部节点的词向量
θ θ θ 逻辑回归的模型参数,需要学习的

L o g i s t i c Logistic Logistic R e g r e s s i o n Regression Regression一样:
对数似然函数 L L L为:
L ( w ) = ∑ j = 2 l w ( ( 1 − d j w ) l o g [ σ ( x w T θ j − 1 w ) ] + d j w l o g [ 1 − σ ( x w T θ j − 1 w ) ] ) L(w)=∑_{j=2}^{l_w}((1−d^w_j)log[σ(x^T_wθ^w_{j−1})]+d^w_jlog[1−σ(x^T_wθ^w_{j−1})]) L(w)=j=2lw((1djw)log[σ(xwTθj1w)]+djwlog[1σ(xwTθj1w)])

l w l_w lw 节点总数
d w d^w dw 节点的霍夫曼编码
w o r d 2 v e c word2vec word2vec中每次仅用一个样本更新梯度,可以减少梯度计算量,因为我们要求的是 L ( w ) L(w) L(w)的最大值,所以使用的是:
随机梯度上升法
w = w + α ∇ w f ( w ) w=w+α∇wf(w) w=w+αwf(w)

具体的推导过程就不在这里详细叙述了(也不是我的强项,手动滑稽。)

w o r d 2 v e c word2vec word2vec中的 n e g a t i v e negative negative s a m p l i n g sampling sampling

w o r d 2 v e c word2vec word2vec不仅使用了霍夫曼树来优化最后的输出,还用了另外一种优化方法,那就是 n e g a t i v e negative negative s a m p l i n g sampling sampling(负采样)。最后并不需要构建霍夫曼树。

如何理解呢?
对于上图中的例子,中心词 w t w_t wt,与之相关的 w t − 2 w_{t-2} wt2 w t + 2 w_{t+2} wt+2这四个词(假设称为 c o n t e n t ( w ) content(w) content(w))就是正例。那么负例怎么来呢?我们随机选取 N N N个词作为 c o n t e n t ( w ) content(w) content(w)的中心词,那么这 N N N个就是负例了。

对数的极大似然和霍夫曼树差不多,只不过是N个负例和1个正例的计算量,而不是 l w l_w lw总的节点数量了。

那又如何选取这 N N N个词呢?
假设词表大小为 V V V,我们将一条直线分为 V V V份,每份的长度则为词频与总长度的比。
w o r d 2 v e c word2vec word2vec中设置了 p o w e r = 0.75 power = 0.75 power=0.75,来计算每份的长度

l e n ( w ) = c o u n t ( w ) 0.75 ∑ u ∈ v o c a b c o u n t ( u ) 0.75 len(w)=\frac{count(w)^{0.75}}{∑_{u∈vocab}count(u)^{0.75}} len(w)=uvocabcount(u)0.75count(w)0.75

train_words_pow += wv.vocab[wv.index2word[word_index]].count**power

采样的时候,我们会把这条已经分成 V V V份的线,再次分成 M M M份( M > > V M >> V M>>V ),所以我们只需要在 M M M中采样出 N N N个位置就行,得到的就是我们的负例了。

部分代码片段如下:

 if model.negative:
        # use this word (label = 1) + `negative` other random words not from this sentence (label = 0)
        word_indices = [word.index]
        while len(word_indices) < model.negative + 1:
            w = model.cum_table.searchsorted(model.random.randint(model.cum_table[-1]))
            if w != word.index:
                word_indices.append(w)

着重关注:

model.random.randint(model.cum_table[-1])

而其中的 c u m cum cum_ t a b l e table table

    def make_cum_table(self, wv, power=0.75, domain=2**31 - 1):
        """Create a cumulative-distribution table using stored vocabulary word counts for
        drawing random words in the negative-sampling training routines.

        To draw a word index, choose a random integer up to the maximum value in the
        table (cum_table[-1]), then finding that integer's sorted insertion point
        (as if by bisect_left or ndarray.searchsorted()). That insertion point is the
        drawn index, coming up in proportion equal to the increment at that slot.

        Called internally from 'build_vocab()'.
        """
        vocab_size = len(wv.index2word)
        self.cum_table = zeros(vocab_size, dtype=uint32)
        # compute sum of all power (Z in paper)
        train_words_pow = 0.0
        for word_index in xrange(vocab_size):
            train_words_pow += wv.vocab[wv.index2word[word_index]].count**power
        cumulative = 0.0
        for word_index in xrange(vocab_size):
            cumulative += wv.vocab[wv.index2word[word_index]].count**power
            self.cum_table[word_index] = round(cumulative / train_words_pow * domain)
        if len(self.cum_table) > 0:
            assert self.cum_table[-1] == domain

f a s t T e x t fastText fastText c b o w cbow cbow

最后再来讲一下 f a c e b o o k facebook facebook f a s t T e x t fastText fastText
我理解的 F a s t t e x t Fasttext Fasttext是为了做 t e x t text text c l a s s i f i c a t i o n classification classification的,顺带生成了词向量。
之所以把 f a s t T e x t fastText fastText c b o w cbow cbow放在一起讲呢?就是因为 f a s t t e x t fasttext fasttext c b o w cbow cbow的模型架构很相似:
都是 输入层、隐藏层、输出层( h i e r a r c h i c a l hierarchical hierarchical s o f t m a x softmax softmax

不同的是:

  1. c b o w cbow cbow的输入是中心词的上下文 c o n t e x t ( w ) context(w) context(w),是经过 o n e one one- h o t hot hot的向量,而 f a s t t e x t fasttext fasttext的输入是文本的分词之后的向量表示(也是简单的加和求平均),最重要的是还有字符级 N N N- g r a m gram gram的表示作为输入输入的另一部分。

    这样对于低频词更友好,可以用字符级的特征来表示一部分信息;
    另外对于 O O V OOV OOV也能用字符级的特征来叠加或者表示一部分。

  2. 最后的输出: c b o w cbow cbow是输出中心词的概率, f a s t t e x t fasttext fasttext输出的是文档对应的类别的概率。

个人还是比较喜欢 f a c e b o o k facebook facebook的产品的,简单至上。

  1. f a s t t e x t fasttext fasttext的前半部分就是生成向量来表征 s e n t e n c e sentence sentence:简单的叠加 w o r d s words words- v e c t o r vector vector以及 n n n- g r a m gram gram v e c t o r vector vector,然后取平均。

  2. 得到文档向量之后,就是做 s o f t m a x softmax softmax c l a s s i f i c a t i o n classification classification t a s k task task

  3. 关键在 n n n- g r a m gram gram特征的引入以及 h h h- s o f t m a x softmax softmax.
    谢谢

更多代码请移步我的个人 g i t h u b github github,会不定期更新各种框架。
欢迎关注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值