文章目录

  • 1. CBOW模型
    • 1.2 连续词袋模型训练过程
  • 2. Skip-Gram模型
  • 3. 霍夫曼树
  • 4. Hierarchical Softmax(层次softmax)的模型概述
  • 5. 负采样近似训练
  • 6. 一些推导公式
  • 7. 负采样程序
  • 8. skip_gram程序

1. CBOW模型

CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。比如下面这段话,我们的上下文大小取值为4,特定的这个词是"Learning",也就是我们需要的输出词向量,上下文对应的词有8个,前后各4个,这8个词是我们模型的输入。由于CBOW使用的是词袋模型,因此这8个词都是平等的,也就是不考虑他们和我们关注的词之间的距离大小,只要在我们上下文之内即可。

在这个CBOW的例子里,我们的输入是8个词向量,输出是所有词的softmax概率(训练的目标是期望训练样本特定词对应的softmax概率最大),对应的CBOW神经网络模型输入层有8个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某8个词对应的最可能的输出中心词时,我们可以通过一次DNN前向传播算法并通过softmax激活函数找到概率最大的词对应的神经元即可。
总结:连续词袋模型是根据上下文预测中心词

1.2 连续词袋模型训练过程

(1)输入层:上下文单词的onehot. (假设词表大小为VVV,上下文单词个数为CCC
(2)所有onehot分别乘以共享的输入权重矩阵WWW. (权重矩阵WWWV∗NV*NVN矩阵,NNN为自己设定的数,随机初始化)
(3)所得的向量 (因为是onehot所以为向量) 相加求平均作为隐层向量, size为 1∗N1*N1N
(4)乘以输出权重矩阵W′W^{'}W (shape=N∗VN*VNV)
(5)得到向量shape=1∗V1*V1V 激活函数处理得到V-dim概率分布(PS: 因为是onehot,其中的每一维都代表着一个单词)
(6)概率最大的index所指示的单词为预测出的中间词(target word)与true label的onehot做比较,误差越小越好(根据误差更新权重矩阵)
需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W’。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding)

注意事项
在一些程序中(包括gensim 和 google的 word2vec)并没有用到onehot encoder,而是初始化的时候直接为每个词随机生成一个N维的向量,并且把这个N维向量作为模型参数学习;所以word2vec结构中不存在上图中显示的将V维映射到N维的隐藏层。
本质是一样的,加上 one-hot encoder 层,是为了方便理解,因为这里的 N 维随机向量,就可以理解为是 V 维 one-hot encoder 输入层到 N 维隐层的权重。每个 one-hot encoder 里值是 1 的那个位置,对应的 V 个权重被激活,其实就是『从一个V*N的随机词向量矩阵里,抽取某一行』。学习 N 维向量的过程,也就是优化 one-hot encoder 层到隐含层权重的过程

2. Skip-Gram模型

输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。还是上面的例子,我们的上下文大小取值为4, 特定的这个词"Learning"是我们的输入,而这8个上下文词是我们的输出。
在这个Skip-Gram的例子里,我们的输入是特定词, 输出是softmax概率排前8的8个词,对应的Skip-Gram神经网络模型输入层有1个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某1个词对应的最可能的8个上下文词时,我们可以通过一次DNN前向传播算法得到概率大小排前8的softmax概率对应的神经元所对应的词即可。

word2vec为什么不用现成的DNN模型,要继续优化出新方法呢?最主要的问题是DNN模型的这个处理过程非常耗时。我们的词汇表一般在百万级别以上,这意味着我们DNN的输出层需要进行softmax计算各个词的输出概率的的计算量很大。

3. 霍夫曼树

word2vec使用了CBOW与Skip-Gram来训练模型与得到词向量,相比传统的DNN模型有以下优化。

优化数据结构,用霍夫曼树来代替隐藏层和输出层的神经元,霍夫曼树的叶子节点起到输出层神经元的作用,叶子节点的个数即为词汇表的小大。 而内部节点则起到隐藏层神经元的作用

霍夫曼树的建立过程如下:
输入:权值为(w1,w2,...wn)的n个节点;输出:对应的霍夫曼树
1)将(w1,w2,...wn)看做是有n棵树的森林,每个树仅有一个节点。
2)在森林中选择根节点权值最小的两棵树进行合并,得到一个新的树,这两颗树作为新树的左右子树。新树的根节点权重为左右子树的根节点权重之和。
3)将之前的根节点权值最小的两棵树从森林删除,并把新树加入森林。
4)重复步骤(2)和(3)直到森林里只有一棵树为止。

例:有(a,b,c,d,e,f)共6个节点,节点的权值分布是(20,4,8,6,16,3)
首先是最小的b和f合并,得到的新树根节点权重是7.此时森林里5棵树,根节点权重分别是20,8,6,16,7。此时根节点权重最小的6,7合并,得到新子树,依次类推,最终得到下面的霍夫曼树。

一般得到霍夫曼树后我们会对叶子节点进行霍夫曼编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词拥有更短的编码。一般对于一个霍夫曼树的节点(根节点除外),可以约定左子树编码为0,右子树编码为1.如上图,则可以得到c的编码是00
在word2vec中,约定编码方式和上面的例子相反,即约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。

4. Hierarchical Softmax(层次softmax)的模型概述

word2vec对DNN模型做了如下改进
(1) 对于从输入层到隐藏层的映射,没有采取神经网络的线性变换加激活函数的方法,而是采用简单的对所有输入词向量求和并取平均的方法
例:输入的是三个4维词向量(1,2,3,4),(9,6,11,8),(5,10,7,12),那么我们word2vec映射后的词向量就是(5,6,7,8)
(2) 从隐藏层到输出的softmax层这里的计算量改进。为了避免要计算所有词的softmax概率,word2vec用霍夫曼树来代替从隐藏层到输出softmax层的映射

用霍夫曼树代替隐藏层到输出softmax层的映射过程如下:

霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元。其中,根节点的词向量对应我们的投影后的词向量,而所有叶子节点就类似于之前神经网络softmax输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"

word2vec中采用了二元逻辑回归的方法,即规定沿着左子树走,那么就是负类,沿着右子树走,那么就是正类。判别正类和负类的方法是使用sigmoid函数,即: P(+)=σ(xwTθ)=11+e−xwTθP(+)=\sigma\left(x_{w}^{T} \theta\right)=\frac{1}{1+e^{-x_{w}^{T} \theta}}P(+)=σ(xwTθ)=1+exwTθ1

其中xwx_wxw是当前内部节点的词向量,而θθθ则是我们需要从训练样本求出的逻辑回归的模型参数。

使用霍夫曼树的好处:之前计算量为V,现在变成了log2Vlog_2Vlog2V。其次由于使用霍夫曼树,高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想

被划分为左子树而成为负类的概率为P(−)=1−P(+)。在某一个内部节点,要判断是沿左子树还是右子树走的标准就是看P(−),P(+)谁的概率值大。而控制P(−),P(+)谁的概率值大的因素一个是当前节点的词向量,另一个是当前节点的模型参数θ。

上图中w2w_2w2如果它是一个训练样本的输出,那么我们期望对于里面的隐藏节点n(w2,1)的P(−)概率大,n(w2,2)的P(−)概率大,n(w2,3)的P(+)概率大

补充解释
取一个适当大小的窗口当做语境,输入层读入窗口内的词,将它们的向量(K维,初始随机)加在一起,形成隐藏层K个节点。输出层是一个巨大的二叉 树,叶节点代表语料里所有的词(语料含有V个独立的词,则二叉树有|V|个叶节点)。而这整颗二叉树构建的算法就是Huffman树。这样,对于叶节点的每一个词,就会有一个全局唯一的编码,形如"010011",记左子树为1,右子树为0。接下来,隐层的每一个节点都会跟二叉树的内节点有连边,于是对于二叉树的每一个内节点都会有K条连边,每条边上也会有权值。
对于语料库中的某个词wtw_twt,对应着二叉树的某个叶子节点,因此它必然有一个二进制编码,如"010011"。在训练阶段,给定上下文,要预测后面的词wtw_twt的时候,就从二叉树的根节点开始遍历,这里的目标就是预测这个词的二进制编号的每一位。即给定的上下文,我们的目标是使得预测词的二进制编码概率最大。形象地说,我们希望在根节点,词向量和与根节点相连经过 logistic 计算得到 bit=1 的概率尽量接近 0,在第二层,希望其 bit=1 的概率尽量接近1,这么一直下去,我们把一路上计算得到的概率相乘,即得到目标词wtw_twt在当前网络下的概率P(wt)P(w_t)P(wt),那么对于当前这个 sample的残差就是1−P(wt)1-P(w_t)1P(wt),于是就可以使用梯度下降法训练这个网络得到所有的参数值了。显而易见,按照目标词的二进制编码计算到最后的概率值就是归一化的。

Hierarchical Softmax用Huffman编码构造二叉树,其实借助了分类问题中,使用一连串二分类近似多分类的思想。例如我们是把所有的词都作为输出,那么“桔 子”、“汽车”都是混在一起。给定wtw_twt的上下文,先让模型判断wtw_twt是不是名词,再判断是不是食物名,再判断是不是水果,再判断是不是“桔子”。
在训练过程中,模型会赋予这些抽象的中间结点一个合适的向量,这个向量代表了它对应的所有子结点。因为真正的单词公用了这些抽象结点的向量,所以Hierarchical Softmax方法和原始问题并不是等价的,但是这种近似并不会显著带来性能上的损失同时又使得模型的求解规模显著上升

传统的Softmax直接从隐层直接计算每一个输出的概率,就需要对|V|中的每一个词都算一遍,这个过程时间复杂 度是O(|V|)的。而使用了二叉树(如Word2vec中的Huffman树),其时间复杂度就降到了O(log2(|V|)),速度大大地加快了。

5. 负采样近似训练

有一个训练样本,中心词是www ,它周围上下文共有2c2c2c个词,记为context(w)context(w)context(w)。由于这个中心词 的确和context(w)context(w)context(w)相关存在,因此它是一个真实的正例。通过Negative Sampling采样,我们得到neg个和www 不同的中心词wiw_iwii=1,2,..neg,这样context(w)context(w)context(w)wiw_iwi 就组成了neg个并不真实存在的负例。利用这一个正例和neg个负例,我们进行二元逻辑回归,得到负采样对应每个词wiw_iwi 对应的模型参数θiθ_iθi和每个词的词向量。

Negative Sampling负采样方法
word2vec采样的方法并不复杂,如果词汇表的大小为V,那么我们就将一段长度为1的线段分成V份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短。每个词 的线段长度由下式决定:
len⁡(w)=count⁡(w)∑u∈vocab count⁡(u)\operatorname{len}(w)=\frac{\operatorname{count}(w)}{\sum_{u \in \text { vocab }} \operatorname{count}(u)} len(w)=uvocabcount(u)count(w)
在word2vec中,分子和分母都取了3/4次幂如下
len⁡(w)=count⁡(w)3/4∑u∈vocab count⁡(u)3/4\operatorname{len}(w)=\frac{\operatorname{count}(w)^{3 / 4}}{\sum_{u \in \text { vocab }} \operatorname{count}(u)^{3 / 4}} len(w)=uvocabcount(u)3/4count(w)3/4
在采样前,我们将这段长度为1的线段划分成M等份,这里M>>V,这样可以保证每个词对应的线段都会划分成对应的小块。而M份中的每一份都会落在某一个词对应的线段上。在采样的时候,我们只需要从M个位置中采样出neg个位置就行,此时采样到的每一个位置对应到的线段所属的词就是我们的负例词。在word2vec中,M取值默认为 10810^8108

6. 一些推导公式

跳字模型
用一个词来预测它在文本序列周围的词






连续词袋模型
用在文本序列周围的词来预测中心词

损失函数


Uc表示中心词向量 V表示背景词

7. 负采样程序

负采样的整体过程如下:
对于skip-gram模型,我们要采样的负样本作为背景词,首先根据每个词的被选为负样概率p(w)p(w)p(w)选出若干个词(一般量比较大,如1e5个),然后再在这若干个词中选出K组负样本。

def get_negative(all_contexts, sampling_weights, K):'''args:all_contexts: 所有的背景词,shape=[[],[],[]]sampling_weights: 采样到每个词的概率=词出现的频率的0.75次方K:负采样个数'''all_negatives, neg_candidates, i = [], [], 0population = list(range(len(sampling_weights)))for contexts in all_contexts:negatives = []# 本程序基于skipgram 模型,因此负样本为背景词,要选择k组背景词负样本while len(negatives)<len(contexts)*K:if i == len(neg_candidates):# 先选出大量负样本再从这些负样本中选择所需个数的负样本i, neg_candidates = 0, random.choices(population, sampling_weights, k=int(1e5))neg, i = neg_candidates[i], i+1if neg not in set(contexts):negatives.append(neg)all_negatives.append(negatives)return all_negatives

8. skip_gram程序

def skip_gram(center, contexts_and_negatives, embed_v, embed_u):v = embed_v(center)u = embed_u(contexts_and_negatives)pred = torch.bmm(v, u.permute(0, 2, 1))return pred
net = nn.Sequential(nn.Embedding(num_embeddings=len(idx_to_token), embedding_dim=embed_size),nn.Embedding(num_embeddings=len(idx_to_token), embedding_dim=embed_size))
pred = skip_gram(center, context_negative, net[0], net[1])

len(idx_to_token) = 512
embed_size = 100
那么v.shape = [512, 1, 100], u.shape = [512, 60, 100]

问题: 为啥skip_gram的前向传播直接是 vuTvu^TvuT
为了便于说明,我们从vvvuuu中直接拿一个"矩阵"来说明:
vvv中拿一个batch, 假设为v1v_1v1,且shape=[1, 100]; 从uuu中拿一个batch, 假设为u1u_1u1,且shape=[60,100]; 为了方便举例,我们将两者的形状再次缩小,设v1v_1v1.shape=[1, 3], u1u_1u1.shape=[2, 3], 即设 v1=[0.5, 1,−0.1]v_1=\left[ \text{0.5, 1,}-0.1 \right] v1=[0.5, 1,0.1]u1=[0.1, 0.5, 0.2−0.5, 0.3, 0.8]u_1=\left[ \begin{array}{c} \text{0.1, 0.5, }0.2\\ -\text{0.5, 0.3, }0.8\\ \end{array} \right] u1=[0.1, 0.5,0.20.5, 0.3,0.8]
其中v1v_1v1的一行代表一个中心词的向量;u1u_1u1的每一行代表中心词上下文及噪声词的向量,所以v1u1Tv_1u_1^Tv1u1T就表示中心词与每个上下文的词或噪声词的内积,假设u1u_1u1的第一行是上下文词, 第二行是噪声词的向量,那么v1v_1v1u1u_1u1第一行做内积结果应该趋向(上下文之间的词相似性更高), v1v_1v1u1u_1u1第二行做内积结果应该趋向0(噪声词和中心词没啥关联),正好我们设置的label = [1, 0]这种格式, 通过交叉熵损失函数,迭代优化后会调整u1u_1u1v1v_1v1的值(实际上是调整embed_v和embed_u),使得内积结果趋向label; 最终的词向量是embed_v,它每一行代表一个词的向量, 每个词的索引和行数对应

未完,待更新…
完整程序见:word2vec.py
原理参考:
[1].word2vec原理(三) 基于Negative Sampling的模型
[2].本地word2vec总结
[3].动手学深度学习

word2vec总结相关推荐

  1. 通俗易懂word2vec详解词嵌入-深度学习

    https://blog.csdn.net/just_so_so_fnc/article/details/103304995 skip-gram 原理没看完 https://blog.csdn.net ...

  2. python实现glove,gensim.word2vec模型训练实例

    20210331 https://blog.csdn.net/sinat_26917383/article/details/83029140 glove实例 https://dumps.wikimed ...

  3. gensim的word2vec如何得出词向量(python)

    首先需要具备gensim包,然后需要一个语料库用来训练,这里用到的是skip-gram或CBOW方法,具体细节可以去查查相关资料,这两种方法大致上就是把意思相近的词映射到词空间中相近的位置. 语料库t ...

  4. 用gensim学习word2vec

    20211224 输入为分词列表 import gensim # Train Word2Vec model model = gensim.models.Word2Vec(all_data_test[' ...

  5. word2vec 中的数学原理详解(二)预备知识

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/peghoty/article/details/37969635 https://blog.csdn. ...

  6. 理解 Word2Vec 之 Skip-Gram 模型

    20211003 NLP系列:Word2Vec原始论文:Efficient Estimation of Word Representations in Vector Space - 简书 原始论文翻译 ...

  7. 漫谈Word2vec之skip-gram模型

    https://zhuanlan.zhihu.com/p/30302498 陈运文 ​ 复旦大学 计算机应用技术博士 40 人赞同了该文章 [作者] 刘书龙,现任达观数据技术部工程师,兴趣方向主要为自 ...

  8. word2vec应用场景_Embedding在腾讯应用宝的推荐实践

    作者:carloslin,腾讯 PCG 应用研究员 Embedding 技术目前在工业界以及学术界中应用非常广泛,关于 Embedding 的探索和应用从未停歇.Embedding 的训练方法主要分成 ...

  9. 收藏 | 图解Word2vec,读这一篇就够了!

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:大数据文摘 ...

  10. 将LSTM与word2vec结合实现中文自动写作

    将LSTM与word2vec结合实现中文自动写作 # 载入所需的工具包 import jieba from gensim.models.word2vec import Word2Vecimport p ...

最新文章

  1. 斯坦福连续发了四年的 AI 报告,今年讲了什么?
  2. 福利 | 2022全球敏捷运维峰会:跟技术老将畅聊时下数据库、运维、金融科技应“云”而生的技术创新...
  3. 在线和本地两种方法构建 RAxML 进化树方法和解读
  4. java hdfs 新建目录_如何用java在hdfs中创建一个新目录?
  5. windows 安装 php memcached,Windows安装配置php+memcached的方法
  6. AngularJS:SQL
  7. go get报错:unrecognized import path “golang.org/x/net/context”…
  8. Cordova(PhoneGap) 环境搭建与基础
  9. java 极客_Java极客思维
  10. mysql的socket文件下载,mysql下的socket文件作用
  11. android crash没有日志_App测试之monkey(四)-调试参数及日志
  12. matlab练习程序(图像放大/缩小,双立方插值)
  13. 拍拍二手重装上阵,京东剑指闲鱼胜算几何?
  14. 计算机系统修复命令提示符,win10怎么用命令提示符修复电脑 用命令提示符修复win10电脑的方法...
  15. Python数据分析学习系列 九 绘图和可视化
  16. 设计——免费PSD素材+设计网站+图标生成工具+自动标注
  17. 在CentOS上安装和配置OpenNebula入门实例
  18. 【Android】TypedArray——三个方法获取dimen返回值的类型
  19. 苹果笔记本回收平台怎么选看这些
  20. 子桓说:陈冠希的39岁才是多数人羡慕的中年

热门文章

  1. 常用的十种数据分析方法
  2. 如何批量给视频加文字水印?
  3. 【Vegas原创】HP惠普笔记本重装系统无法引导无法进操作系统的终极解决方法
  4. Latex使用总结(待完善)
  5. js encodeuricomponent php解码,JS中encodeURIComponent函数用php 解码
  6. 换服务器影响网站排名,网站更换服务器空间会影响排名吗
  7. mysql修改时间为东八区,mysql时区设置为东八区
  8. lol手游之任务进度条精准计算
  9. 乔布斯逝去十年 苹果坠入凡间?
  10. leetcode:954. 二倍数对数组