目录

  • word2vec出现的背景
  • 跳字模型(skip-gram)
  • 连续词袋模型(CBOW)
  • 小结
  • 负采样
  • 具体训练过程

word2vec出现的背景

  • 我们都知道,自然语言处理需要对文本进行编码,将语言中的词转化为向量的形式,计算机的世界里只有数字,所以这是一项必须要做的工作。
  • 有人可能会想,最常见的编码如one-hot编码,能不能用于自然语言处理对于文本的编码呢?答案是肯定的,当然能,但是效果不好,也许没人会这么做。
  • 为什么呢,因为文本几乎都具有相关性,构成文本的单词更是有相关性,它们之间应该能通过各自的词向量来表征它们之间的关系。我们知道余弦相似度可以用来表征两个向量的相似性,我们也可以用余弦相似度来表征词向量的相似性,而如果采用one-hot编码,则不管取哪两个词,结果都是0,也就是说,单身男子这个词和人类的相似度,等同于单身男子的相似度。
  • 所以独热编码是不适用于该领域的。所以人们需要构造出从单词到向量的转换。word2vec应运而生。

跳字模型(skip-gram)

  • 关于这些基础知识我不手写了,这里引用Dive-into-DL-PyTorch中的介绍:

连续词袋模型(CBOW)

  • 下面

小结

  • 可以看出,这些训练词向量的方法都是使用了内积相似度(即向量w*向量u) 来衡量两个词向量之间的相似程度,这是为什么呢?
  • 因为衡量两个向量的相似程度不能仅靠其夹角,还要考虑其长度,而内积运算正是如此:

    所以,word2vec使用内积相似度是合理的。

负采样

  • 我们可以看到其实跳字模型和连续词袋模型是差不多的,它们有一个共同点,每次计算条件概率都要在分母统计所有词与中心词(或背景词)的向量内积,我们都知道词典是很大的, 而每次迭代计算条件概率都要进行这么庞大的内积计算,成本很大。当然计算之后根据loss来修改词向量的时候是对全部词向量进行修改。
  • 负采样就是来解决这个问题的。由于跳字模型和连续词袋模型类似,此处仅以跳字模型为例介绍这两种方法。负采样采用了一个背景窗口,原先不是更新所有词与中心词的向量内积嘛,现在不这样了,我们选取一个窗口大小的背景词填满窗口,然后每次就用这些背景词和中心词进行向量内积,然后呢根据loss更改参数也是只修改这些词和中心词的词向量,并不是全部修改。
  • 负采样修改了原来的目标函数。给定中心词WcW_{c}Wc​的一个背景窗口,我们把背景词WoW_{o}Wo​出现在该背景窗口看作一个事件,并将该事件的概率计算为

    其中的σσ函数与sigmoid激活函数的定义相同:

    我们先考虑最大化文本序列中所有该事件的联合概率来训练词向量。具体来说,给定一个长度为T的文本序列,设时间步t的词为WtW^{t}Wt,且背景窗口大小为m,考虑最大化联合概率
  • 使用sigmoid函数来根据内积结果生成对应的概率值是合理的,因为内积结果越大,概率值越高,即内积相似度越高,概率越高,这是合理的。
  • 然而上面的背景窗口只包含了真实的背景词,这导致当所有词向量相等且值为无穷大时,以上的联合概率才被最大化为1。很明显,这样的词向量毫无意义。负采样通过采样并添加负类样本使目标函数更有意义。
  • 其实我始终不太明白这里为什么一定要加入负样本,虽然确实联合概率很难达到1,但是这也是正常的,损失肯定是有的,如果有哪位小伙伴明白,可以评论告诉我。
  • 那现在看来不能只考虑背景词了,还要加入一些噪声词,很明显,背景词是正儿八经出现在中心词附近的,而噪声词是我们人为添加的,所以背景词是正类,噪声词是负类。每次更新词向量,就更新正类和负类以及中心词的词向量。这儿有点像跳词模型中的分母考虑所有词,而这里只考虑背景词和少量噪声词,我们设置噪声词的个数为超参数K。所谓的负采样,其实就是采样K个负类,即噪声词。
  • 那么条件概率就变为了:

具体训练过程

  • 下面我具体来说,我们训练词向量的时候,一个中心词对应多个背景词,我们设置背景窗口的大小s,然后中心词在一句话中的前s个词和后s个词作为背景词,然后随机选取K个噪声词。
  • 然后我们需要统一尺寸,而由于中心词可能位于句子的前端或者后端,导致背景词数量并不一致,我们以所有中心词对应的最多的背景词+噪声词作为尺寸max_len,然后不满的补0,最终得到了[batch_size,max_len]的训练样本。
  • 然后我们要设置label,背景词的标签是1,噪声词是负类,标签是0。对于长度补充的也设置为0,意思是只让背景词和噪声词向量参与运算。
  • 还得设置是否是填充的,用mask来表示,对于填充的元素设置为0,背景词和噪声词都是1,之所以设置mask是因为在调用nn.functional.binary_cross_entropy_with_logits时需要设置填充的不参与运算。
  • 举个栗子:
class SigmoidBinaryCrossEntropyLoss(nn.Module):def __init__(self): # none mean sumsuper(SigmoidBinaryCrossEntropyLoss, self).__init__()def forward(self, inputs, targets, mask=None):"""input – Tensor shape: (batch_size, len)target – Tensor of the same shape as input"""inputs, targets, mask = inputs.float(), targets.float(), mask.float()res = nn.functional.binary_cross_entropy_with_logits(inputs, targets, reduction="none", weight=mask)return res.mean(dim=1)loss = SigmoidBinaryCrossEntropyLoss()pred = torch.tensor([[1.5, 0.3, -1, 2], [1.1, -0.6, 2.2, 0.4]])
# 标签变量label中的1和0分别代表背景词和噪声词
label = torch.tensor([[1, 0, 0, 0], [1, 1, 0, 0]])
mask = torch.tensor([[1, 1, 1, 1], [1, 1, 1, 0]])  # 掩码变量
loss(pred, label, mask) * mask.shape[1] / mask.float().sum(dim=1)
输出tensor([0.8740, 1.2100])

上面的运算过程就相当于:

def sigmd(x):return - math.log(1 / (1 + math.exp(-x)))print('%.4f' % ((sigmd(1.5) + sigmd(-0.3) + sigmd(1) + sigmd(-2)) / 4)) # 注意1-sigmoid(x) = sigmoid(-x)
print('%.4f' % ((sigmd(1.1) + sigmd(-0.6) + sigmd(-2.2)) / 3))
输出
0.8740
1.2100

自然语言处理中的负采样相关推荐

  1. 【技术综述】深度学习在自然语言处理中的应用发展史

    本篇介绍深度学习在自然语言处理(NLP)中的应用,从词向量开始,到最新最强大的BERT等预训练模型,梗概性的介绍了深度学习近20年在NLP中的一些重大的进展. 作者&编辑 | 小Dream哥 ...

  2. 深度学习-自然语言处理中的近似训练

    自然语言处理中的近似训练 跳字模型的核心在于使用softmax运算得到给定中心词wcw_cwc​来生成背景词wow_owo​的条件概率 P(wo∣wc)=exp(uo⊤vc)∑i∈Vexp(ui⊤vc ...

  3. 自然语言处理中的语言模型与预训练技术的总结

    目录 0. 背景 1. 统计语言模型(Statistical Language Model) 马尔科夫假设(Markov Assumption) N-Gram模型 拉普拉斯平滑(Laplace Smo ...

  4. 自然语言处理中的迁移学习(上)

    作者:哈工大SCIR 徐啸 来源:Transfer Learning in Natural Language Processing Tutorial (NAACL 2019) 作者:Sebastian ...

  5. vs需要迁移_赛尔笔记 | 自然语言处理中的迁移学习(上)

    点击上方"MLNLP",选择"星标"公众号 重磅干货,第一时间送达 作者:哈工大SCIR 徐啸 转载自公众号:哈工大SCIR 来源:Transfer Learn ...

  6. 论文阅读:Natural Language Processing Advancements By Deep Learning: A Survey 深度学习在自然语言处理中的进展

    Natural Language Processing Advancements By Deep Learning: A Survey 深度学习在自然语言处理中的进展 目录 Natural Langu ...

  7. 自然语言处理中的N-Gram模型

    N-Gram(有时也称为N元模型)是自然语言处理中一个非常重要的概念,通常在NLP中,人们基于一定的语料库,可以利用N-Gram来预计或者评估一个句子是否合理.另外一方面,N-Gram的另外一个作用是 ...

  8. 自然语言处理中的语言模型预训练方法

    最近,在自然语言处理(NLP)领域中,使用语言模型预训练方法在多项 NLP 任务上都获得了不错的提升,广泛受到了各界的关注.就此,我将最近看的一些相关论文进行总结,选取了几个代表性模型(包括 ELMo ...

  9. 自然语言处理中CNN模型几种常见的Max Pooling操作

    /* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 (想更系统地学习深度学习知识?请参考:深度学习枕边书) CNN是目前自然语言处理中和RNN并驾齐驱的两 ...

最新文章

  1. MySQL面试题 | 附答案解析(六)
  2. android ffmegp for_FFmpeg 编译for Android
  3. linux怎么进入bios查看mac地址,详细教您查看本机mac地址
  4. lds天线技术流程图_音箱耳机入门,蓝牙真无线耳机中的LDS天线 「Soomal」
  5. javascript 本地对象和内置对象_详解 JavaScript 面向对象
  6. python什么时候用进程什么时候用线程_Python多线程/多进程释疑:为啥、何时、怎么用?...
  7. 虚拟资源拳王公社:闲鱼虚拟资源玩法案例拆解,教你玩转虚拟资源,货源+方法
  8. 调试信息清除小工具的编写
  9. bokeh python_Python Bokeh数据可视化教程
  10. python判断成语是abac型_ABAC型成语大全
  11. android平板生产力工具,重塑应用生态,让安卓平板成为生产力工具:华为MatePad Pro体验...
  12. java求职面试指南
  13. 人活着就是为了改变世界,不要把时间浪费在重复其他人的生活上。————乔布斯
  14. 蓝魔手机回归产品本身 老战友魅族OPPO怎么看?
  15. 一个微信可以有多个头像昵称了
  16. 燕十八mysql笔记_学习笔记2..燕十八老师公益课堂
  17. 世上无难事只怕有心人,GO!vmware15 安装win10详解
  18. matlab矩阵转化成一行向量
  19. 通达信主力加仓指标 疯牛有理加仓爆发选股指标
  20. ESP8266开发入门

热门文章

  1. 不同进制间的相互转化。
  2. 1072 开学寄语 (20分)
  3. 电脑右下角没有声音图标,电脑喇叭有声音解决
  4. 机房收费系统—日结账单
  5. android studio配置阿里仓库gardle
  6. 滋灌中小企业,分销伙伴和华为来做“送水人”
  7. python读取grib数据
  8. 相位谱的matlab程序,基于相位谱视觉注意机制matlab代码
  9. Java查询每个部门总人数(包含每个部门层级的总数)
  10. EXIT外部中断实验——EXTI