word2vec理解及pytorch实现

  • word2vec优点
    • 1.低维稠密
    • 2.蕴含语义信息
  • Skip-gram模型
    • 1.训练样本
    • 2.skip-gram
  • 负采样 negative sample
  • 欠采样 subsample
  • pytorch实现

word2vec是Google研究团队的成果之一,它作为一种主流的获取分布式词向量的工具,在自然语言处理、数据挖掘等领域有着广泛的应用。本文首先会介绍一些预备知识,比如softmax、ngram、subsampling、neg-sampling等,之后来讲解word2vec的原理,并着手使用pytorch搭建word2vec模型。

word2vec优点

word2vec词向量与传统的one-hot词向量相比,主要有以下两个优势

1.低维稠密

一般来说分布式词向量的维度设置成100-500就足够使用,而one-hot类型的词向量维度与词表的大小成正比,是一种高维稀疏的表示方法,这种表示方法导致其在计算上效率比较低。

2.蕴含语义信息

one-hot这种表示方式使得每一个词映射到高维空间中都是互相正交的,也就是说one-hot向量空间中词与词之间没有任何关联关系,这显然与实际情况不符合,因为实际中词与词之间有近义、反义等多种关系。Word2vec虽然学习不到反义这种高层次语义信息,但它巧妙的运用了一种思想:“具有相同上下文的词语包含相似的语义”,使得语义相近的词在映射到欧式空间后中具有较高的余弦相似度。
sim(apple,banana)=vecapple⋅vecbanana∣vecapple∣⋅∣vecbanana∣sim(apple, banana) =\frac{vec_{apple}·vec_{banana}}{|vec_{apple}|·|vec_{banana}|} sim(apple,banana)=∣vecapple​∣⋅∣vecbanana​∣vecapple​⋅vecbanana​​

图1

Skip-gram模型

1.训练样本

怎么把“具有相同上下文的词语包含相似的语义”这种思想融入模型是很关键的一步,在模型中,两个词是否出现在一起是通过判断这两个词在上下文中是否出现在一个窗口内。例如,原始样本“The quick brown fox jumps over the lazy dog.”在送入模型前会经过图2所示处理(这里为了绘图简单假设窗口为2,一般窗口是设置成5)。

如图所示,skip-gram模型的输入是当前词,输出是当前词的上下文,虽然我们训练模型的时候喂的是一个个分词好的句子,但内部其实是使用一个个word pair来训练。同样是之前的case“The quick brown fox jumps over the lazy dog.”,假如窗口改为5,则(The,quick)这个word pair会成为一个训练样本。

假如两个词具有相同的输出,则可反推出作为输入的两个词之间具有较高相似性,接下来就是如何使用模型来实现上述目标。

图2

2.skip-gram

skip-gram模型与自编码器(Autoencoder)类似,唯一的区别在于自编码器的输出等于输入,而skip-gram模型的输出是输入的上下文。那么,作为训练样本的word pair应该以什么样的方式输入给模型? 答案是one-hot向量,为了得到one-hot向量,必须首先知道训练语料中包含了多少词。因此,在训练之前会首先对语料进行统计,得到词表。假设词表长度为10000,词向量为300维,则skip-gram模型可表示为图3。

图3

如图3所示,假设输入的word pair为(ants, able),则模型拟合的目标是MaxP(able∣ants)Max \ P(able|ants)Max P(able∣ants),同时也需要满足MinP(otherwords∣ants)Min \ P(other \ words|ants)Min P(other words∣ants),这里利用的是对数似然函数作为目标函数。上述表述中可表示为P(able∣ants)P(able|ants)P(able∣ants):
P(able∣ants)=softmax(Xants1×10000⋅W10000×300)P(able|ants)=softmax(X_{ants \ 1 \times 10000} · W_{10000 \times 300})P(able∣ants)=softmax(Xants 1×10000​⋅W10000×300​)
softmax(X)=exp(X1×300⋅W300×1)∑i=110000exp(X1×300i⋅W300×1)softmax(X) = \frac {exp(X_{1 \times 300}·W_{300 \times 1})}{\sum_{i=1}^{10000}exp(X_{1 \times 300}^i·W_{300 \times 1})} softmax(X)=∑i=110000​exp(X1×300i​⋅W300×1​)exp(X1×300​⋅W300×1​)​
根据P(able∣ants)P(able|ants)P(able∣ants)和P(otherwords∣ants)P(other \ words|ants)P(other words∣ants),可构建似然函数:
L(W)=P(able∣ants)y=able⋅P(otherwords∣ants)y=otherwordsL(W)=P(able|ants)^{y=able}·P(other \ words|ants)^{y=other \ words}L(W)=P(able∣ants)y=able⋅P(other words∣ants)y=other words
则:
logL(W)={y=targetword}{logP(able∣ants)+logP(otherwords∣ants)}=∑i10000{y=targetword}logP(wordi∣ants)log \ L(W) = \{y=target \ word \} \{log \ P(able|ants) + log \ P(other \ words |ants) \} \\ = \sum_{i}^{10000} \{ y=target \ word \}logP(word_i|ants)log L(W)={y=target word}{log P(able∣ants)+log P(other words∣ants)}=i∑10000​{y=target word}logP(wordi​∣ants)
将P(wordi∣ants)P(word_i|ants)P(wordi​∣ants)代入有:
logL(W)=∑i10000{y=targetword}logexp(X1×300⋅W300×1)∑i=110000exp(X1×300i⋅W300×1)logL(W)=\sum_i^{10000}\{ y=target \ word\}log \frac {exp(X_{1 \times 300}·W_{300 \times 1})} {\sum_{i=1}^{10000}exp(X_{1 \times 300}^i·W_{300 \times 1})}logL(W)=i∑10000​{y=target word}log∑i=110000​exp(X1×300i​⋅W300×1​)exp(X1×300​⋅W300×1​)​

式中{*}表示如果表达式*为true,则{*}=1,否则{*}=0。接下来要做的是最大化似然函数,也即:
MaxlogL(W)Max \ logL(W)Max logL(W)
要实现上述目标,可利用梯度上升法,首先对参数求偏导:
∂logL(W)∂wi=xi({y=targetword}−P(targetword∣xi;W))\frac{\partial logL(W)}{\partial w_i}=x_i(\{ y=target \ word \} - P(target \ word|x_i;W))∂wi​∂logL(W)​=xi​({y=target word}−P(target word∣xi​;W))
接下来根据学习率对进行更新:
wi=wi+η⋅∂logL(W)∂wiw_i=w_i + \eta · \frac{\partial logL(W)}{\partial w_i}wi​=wi​+η⋅∂wi​∂logL(W)​
隐藏层的参数矩阵W10000×300W_{10000 \times 300}W10000×300​就包含了所有词的词向量,该矩阵的行为词表长度,列为词向量维度,矩阵中的每一行表示一个词的词向量。由于输入层Xants1×10000X_{ants \ 1 \times 10000}Xants 1×10000​是one-hot向量,与隐藏层W10000×300W_{10000 \times 300}W10000×300​点乘后其实是选中了该矩阵中的一行,如图5所示,这一行表示的是ants的词向量,而输出层其实是以ants的词向量为特征,以ants的上下文词作为类别来训练softmax分类器。

负采样 negative sample

以图3所示的模型为例,对每一个训练样本需要更新的参数个数有三百万(准确的说是三百万零三百,由于输入是one-hot,隐藏层每次只需要更新输入词语的词向量),这还是假设词表只有一万的情况下,实际情况会有五十万甚至更多,这时候参数就达到了亿级。训练过程中要对每个参数计算偏导,然后进行更新,这需要很大的计算资源。

负采样是加快训练速度的一种方法,这里的负可以理解为负样本。针对训练样本(ants, able),able这个词是正样本,词表中除able外的所有词都是负样本。负采样是对负样本进行采样,不进行负采样时,对每一个训练样本模型需要拟合一个正样本和九千九百九十九个负样本。加入负采样后,只需要从这九千九百九十九个负样本中挑出来几个进行拟合,大大节省了计算资源。那么应该挑几个负样本,根据什么进行挑呢?Google给出的建议是挑5-20个,怎么挑是根据词在语料中出现的概率,概率越大越有可能被选中,具体计算公式为:
P(word)=f(word)34∑i=110000(f(wordi)34)P(word)=\frac{f(word)^{\frac{3}{4}}}{\sum_{i=1}^{10000}(f(word_i)^{\frac{3}{4}})}P(word)=∑i=110000​(f(wordi​)43​)f(word)43​​
其中f(word)表示word出现的概率。

那么如何使用负采样数据呢?下面会对使用负采样后的优化目标进行推导。
考虑一对单词和上下文的组合(w,c)(w, c)(w,c)。我们用p(D=1∣w,c)p(D=1|w, c)p(D=1∣w,c)表示(w,c)(w, c)(w,c)是真实上下文对的概率。相应地,p(D=0∣w,c)=1−p(D=1∣w,c)p(D=0|w, c)=1-p(D=1|w, c)p(D=0∣w,c)=1−p(D=1∣w,c)将是(w,c)(w, c)(w,c)不是真实上下文对的概率。假设存在控制分布的参数θ:p(D=1∣w,c;θ)θ:p(D = 1|w, c ;θ)θ:p(D=1∣w,c;θ)。

根据论文,我们假设单词和上下文来自不同的词汇表,因此,单词dog相关联的向量将与上下文dog相关联的向量不同。做出这种假设的一个可能的解释如下:考虑单词dog和上下文dog共享相同向量vvv的情况。单词几乎不会出现在自身的上下文中,因此模型应该为p(dog∣dog)p(dog|dog)p(dog∣dog)分配一个低概率,这需要为v⋅vv · vv⋅v分配一个低值,这是不可取的。
我们现在的目标是找到参数,以最大化所有单词上下文对确实是真实的概率,即:
argmax⁡θ∏(w,c)∈Dp(D=1∣w,c;θ)=argmax⁡θlog∏(w,c)∈Dp(D=1∣w,c;θ)=argmax⁡θ∑(w,c)∈Dlogp(D=1∣w,c;θ)arg\max \limits_{\theta} \prod_{(w, c)\in D} p(D=1|w, c; \theta) \\ =arg\max \limits_{\theta} log \prod_{(w, c)\in D} p(D=1|w, c; \theta) \\ =arg\max \limits_{\theta} \sum_{(w, c)\in D} logp(D=1|w, c; \theta) argθmax​(w,c)∈D∏​p(D=1∣w,c;θ)=argθmax​log(w,c)∈D∏​p(D=1∣w,c;θ)=argθmax​(w,c)∈D∑​logp(D=1∣w,c;θ)
p(D=1∣w,c;θ)p(D=1|w, c;\theta)p(D=1∣w,c;θ)可以用softmax定义:
p(D=1∣w,c;θ)=11+e−vc⋅vwp(D=1|w, c;\theta)=\frac{1}{1+e^{-v_c·v_w}}p(D=1∣w,c;θ)=1+e−vc​⋅vw​1​
优化目标是:
argmax⁡θ∑(w,c)∈D11+e−vc⋅vwarg \max \limits_{\theta } \sum_{(w, c)\in D}\frac{1}{1+e^{-v_c·v_w}}argθmax​(w,c)∈D∑​1+e−vc​⋅vw​1​
我们需要一种机制,通过禁用某些(w,c)(w, c)(w,c)组合来阻止所有向量具有相同的值。负采样就满足这种情况,负样本对不是真实数据,因此其p(D=1∣w,c;θ)p(D=1|w, c;\theta)p(D=1∣w,c;θ)是很低的,设负样本集合为D’,优化目标为:
argmax⁡θ∏(w,c)∈Dp(D=1∣w,c;θ)∏(w,c)∈D′p(D=0∣w,c;θ)=argmax⁡θlog∏(w,c)∈Dp(D=1∣w,c;θ)∏(w,c)∈D′(1−p(D=1∣w,c;θ))=argmax⁡θ∑(w,c)∈Dlogp(D=1∣w,c;θ)+∑(w,c)∈D′log(1−p(D=1∣w,c;θ))=argmax⁡θ∑(w,c)∈Dlog11+e−vc⋅vw+∑(w,c)∈D′log(1−11+e−vc⋅vw)=argmax⁡θ∑(w,c)∈Dlog11+e−vc⋅vw+∑(w,c)∈D′log11+evc⋅vwarg\max \limits_{\theta} \prod_{(w, c)\in D} p(D=1|w, c; \theta) \prod_{(w, c)\in D'} p(D=0|w, c; \theta)\\ =arg\max \limits_{\theta} log \prod_{(w, c)\in D} p(D=1|w, c; \theta) \ \prod_{(w, c)\in D'} (1-p(D=1|w, c; \theta))\\ =arg\max \limits_{\theta} \sum_{(w, c)\in D} logp(D=1|w, c; \theta) + \sum_{(w, c)\in D'} log(1-p(D=1|w, c; \theta)) \\ =arg\max \limits_{\theta} \sum_{(w, c)\in D} log\frac{1}{1+e^{-v_c·v_w}} + \sum_{(w, c)\in D'} log(1-\frac{1}{1+e^{-v_c·v_w}}) \\ =arg\max \limits_{\theta} \sum_{(w, c)\in D} log\frac{1}{1+e^{-v_c·v_w}} + \sum_{(w, c)\in D'} log\frac{1}{1+e^{v_c·v_w}}argθmax​(w,c)∈D∏​p(D=1∣w,c;θ)(w,c)∈D′∏​p(D=0∣w,c;θ)=argθmax​log(w,c)∈D∏​p(D=1∣w,c;θ) (w,c)∈D′∏​(1−p(D=1∣w,c;θ))=argθmax​(w,c)∈D∑​logp(D=1∣w,c;θ)+(w,c)∈D′∑​log(1−p(D=1∣w,c;θ))=argθmax​(w,c)∈D∑​log1+e−vc​⋅vw​1​+(w,c)∈D′∑​log(1−1+e−vc​⋅vw​1​)=argθmax​(w,c)∈D∑​log1+e−vc​⋅vw​1​+(w,c)∈D′∑​log1+evc​⋅vw​1​

令σ=11+e−x\sigma = \frac{1}{1+e^{-x}}σ=1+e−x1​,可得:

argmax⁡θ∑(w,c)∈Dlog11+e−vc⋅vw+∑(w,c)∈D′log11+evc⋅vw=argmax⁡θ∑(w,c)∈Dlogσ(vc⋅vw)+∑(w,c)∈D′logσ(−vc⋅vw)arg\max \limits_{\theta} \sum_{(w, c)\in D} log\frac{1}{1+e^{-v_c·v_w}} + \sum_{(w, c)\in D'} log\frac{1}{1+e^{v_c·v_w}} \\ =arg\max \limits_{\theta} \sum_{(w, c)\in D} log\sigma(v_c·v_w) + \sum_{(w, c)\in D'} log\sigma(-v_c·v_w) argθmax​(w,c)∈D∑​log1+e−vc​⋅vw​1​+(w,c)∈D′∑​log1+evc​⋅vw​1​=argθmax​(w,c)∈D∑​logσ(vc​⋅vw​)+(w,c)∈D′∑​logσ(−vc​⋅vw​)
我们可看到这个就是原文中的优化目标。

欠采样 subsample

图2中的例子中“the”这种词在任何场景中都可能出现,它们并不包含多少语义,而且出现的频率特别高,如果不加处理会影响词向量的效果。欠采样就是为了应对这种现象,它的主要思想是对每个词都计算一个采样概率,根据概率值来判断一个词是否应该保留。概率计算方法为:
P(word)=(f(word)0.001+1)⋅0.001f(word)P(word)= \left( \sqrt{\frac{f(word)}{0.001}}+1 \right) · \frac{0.001}{f(word)}P(word)=(0.001f(word)​​+1)⋅f(word)0.001​
其中f(*)表示*出现的概率,0.001为默认值,具体函数走势如图4所示,可以看出,词语出现的概率越高,其被采样到的概率就越低。这里有一点IDF的味道,不同的是IDF是为了降低词的特征权重,欠采样是为了降低词的采样概率。

图4

pytorch实现

待续

word2vec理解及pytorch实现相关推荐

  1. tensor.view()函数--自己的理解《pytorch学习》

    引言:首先介绍一下,我们会在哪里遇到这个函数呢?最常见的就是在利用pytorch库搭建网络时,时不时的冒出一个,如果不会!你总是看不懂,以后也看不懂,如果有时间,大家一起来看看这个函数吧! 1.ten ...

  2. 图注意网络GAT理解及Pytorch代码实现【PyGAT代码详细注释】

    文章目录 GAT 代码实现[PyGAT] GraphAttentionLayer[一个图注意力层实现] 用上面实现的单层网络测试 加入Multi-head机制的GAT 对数据集Cora的处理 csr_ ...

  3. 损失函数与优化器理解+【PyTorch】在反向传播前为什么要手动将梯度清零?optimizer.zero_grad()

    目录 回答一: 回答二: 回答三: 传统的训练函数,一个batch是这么训练的: 使用梯度累加是这么写的: 回答一: 一句话,用来更新和计算影响模型训练和模型输出的网络参数,使其逼近或达到最优值,从而 ...

  4. 深度学习中的 Batch_Size,以及learning rate参数理解(跑pytorch代码时遇到的问题)

    在训练和测试的时候遇到的问题, _error_if_any_worker_fails() RuntimeError: DataLoader worker (pid 25637) is killed b ...

  5. Keras vs PyTorch:谁是第一深度学习框架?

    「第一个深度学习框架该怎么选」对于初学者而言一直是个头疼的问题.本文中,来自 deepsense.ai 的研究员给出了他们在高级框架上的答案.在 Keras 与 PyTorch 的对比中,作者还给出了 ...

  6. PyTorch之前向传播函数自动调用forward

    参考:1. pytorch学习笔记(九):PyTorch结构介绍 2.pytorch学习笔记(七):pytorch hook 和 关于pytorch backward过程的理解 3.Pytorch入门 ...

  7. PyTorch 图像分类

    PyTorch 图像分类 如何定义神经网络,计算损失值和网络里权重的更新. 应该怎么处理数据? 通常来说,处理图像,文本,语音或者视频数据时,可以使用标准 python 包将数据加载成 numpy 数 ...

  8. python训练手势分类器_使用Pytorch训练分类器详解(附python演练)

    [前言]:你已经了解了如何定义神经网络,计算loss值和网络里权重的更新.现在你也许会想数据怎么样? 目录: 一.数据 二.训练一个图像分类器 使用torchvision加载并且归一化CIFAR10的 ...

  9. Pytorch机器学习/深度学习代码笔记

    代码步骤笔记 导入模块 设置参数 数据预处理 定义数据集 1.Dataset 2.ImageFolder 加载数据集 DataLoader torchvision--数据预处理要使用的库 torchv ...

最新文章

  1. 马化腾:我创办腾讯的这些年
  2. 包python_Python 包:
  3. python实现线性回归预测_机器学习实战笔记(Python实现)-08-线性回归
  4. Java程序员常犯的几类错误
  5. 中缀表达式转后缀表达式两位数_再见,正则表达式!
  6. MongoDB 副本集管理
  7. python办公自动化案例-Python智能办公自动化实战课程
  8. mysql字符集编码解析_MySQL字符集编码的理解
  9. openwrt编译smartdns_【萌新理解交流】浅谈openWRT中的smartDNS中各个选项如何设置及其含义。...
  10. Unity3D--学习太空射击游戏制作(二)
  11. dfs——xy省赛选拔题——问题 E: 整数凑和问题
  12. pmp复习资料链接-2021.06.20考试(中培)
  13. 五子棋联机对战(JAVA实现)含源码
  14. 语义分割中的mIoU计算函数解读
  15. 中国人越来越不愿买新车!二手车电商上半年融资150亿元,谁是大赢家?
  16. 一道传统特色小吃让她萌生创业想法,一天能挣800元
  17. 『VulnHub系列』Hacker Fest: 2019-Walkthrough
  18. 他狂骗五千万美元消失17年...却被一个纪录片导演锲而不舍的追到了镜头前!...
  19. wget命令 scp命令 rcp命令
  20. android 自定义特效,Android自定义View:实现炫酷的点赞特效

热门文章

  1. 搜苹果ipad版_快速实现苹果企业签名,几分钟就可以?
  2. Python学习笔记--Python 爬虫入门 -17-5 js 加密 (和有道词典的瓜葛)
  3. 中集集团全球港航AI高科技独角兽中集飞瞳港口航运新枢纽人工智能技术走向成熟全球前三大船公司及港口码头应用落地港口智能化码头智能化
  4. UnityWebRequest加载音频
  5. java粒子特效_程序员20分钟搞定粒子效果, 仅仅200行代码
  6. 虚拟化存储和非虚拟化存储
  7. android查看app日志的一个技能
  8. 基于OpenCV的卡尔曼滤波的设计
  9. win7系统下阿里旺旺无法登陆怎么解决
  10. 火影忍者的最爱:三勾玉