Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >手把手教你用飞桨做词向量模型 SkipGram

手把手教你用飞桨做词向量模型 SkipGram

作者头像
用户1386409
发布于 2019-09-17 07:26:37
发布于 2019-09-17 07:26:37
71700
代码可运行
举报
文章被收录于专栏:PaddlePaddlePaddlePaddle
运行总次数:0
代码可运行

飞桨开发者说成员:肥猫、忆臻

在做 NLP 的任务时,一个非常 basic 的操作就是如何编码自然语言中的符号,例如词、短语,甚至词缀。目前流行的方法有大约三种:

特征工程:这类方法依赖于手工特征,例如tf-idf 同时考虑词频和词的稀缺度;

统计方法:统计上常常通过矩阵分解(如SVD、EVD)来建模大规模文档集合;

神经网络:目前非常流行通过神经网络端到端的建模语言模型,得到词向量副产品;

今天要讲解的就是SkipGram 模型就属于第三种方法,它的主要思想是利用的词义的分布式表示。除了让您彻底弄懂什么是语言模型以及 SkipGram 的基本原理。我们还会详细的说明如何一步步的用飞桨(PaddlePaddle)实现它。

1.什么是词向量

首先我们需要了解什么是词向量。NLP和图像不太一样,图像的输入本身就是一个有数值特征的矩阵,而 NLP 的输入通常只是一堆自然语言的符号,不方便计算机直接计算。因此,在计算语言学中,我们通常会希望用数值向量来表示这些符号。例如现在我们希望比较词汇“米饭”与“猪肉”和“家具”之间词义的相似性,可以考虑用下面这样的 two-stage 范式。

• 将词汇用向量来表示,例如这里

以及

• 考虑某种数值距离去度量,例如内积

。这里有

。类似的,同理我们也可以得到

;从数值大小可以判断,与“家具”相比,“米饭”和“猪肉”更相似。

从上面这个例子可以看出,使用向量数值表示法最关键的地方在于如何获取词汇的向量的表示,而 SkipGram 就是一个良方。

2.什么是语言模型

词向量一般不是直接获取的,而是某些任务的副产品。它们通常是随机初始化的,然后通过不断的数值优化过程中获得语义信息,例如上述的相似性。因此,训练词向量的办法可以有很多,但是如何高效的获得高质量的词向量很重要,另外任务也应该有一定的可拓展性,例如语料充足,不需要额外标注。

语言模型是一个非常好的选择。因为它语料充足,只要有文章,有帖子,那就有数据;同时由于其任务的特殊性,不需要人工进行额外的数据标注(网上有很多称这是无监督,但我觉得不是特别合适,不需要数据标注和无监督概念有所差异)。那么什么是语言模型呢?

语言模型就是用来衡量一句话出现的概率的。例如

显然,第二句话一般不会出自于一个神智正常的人之口,因此他的概率很低。而一句话

的概率可以用条件概率分解如下:

这里

表示词

的上下文,是对

的近似,否则计算复杂度是指数的。其中一种近似就是 n-gram,即

如上图所示的例子,当n=5时,

表示已知前 4 个词,预测下一个词的概率。由于让模型提高 P(s) 的概率等价于让模型提高每个 P(wi|ci)的概率,因此语言模型又可以被理解为已知上下文时中心词不确定性的度量。

3.什么是 SkipGram

经过前两节的解释,相信您对词向量有了很深的认识了。这一小节中我将会介绍 SkipGram,一种有效训练语言模型的方法。

说到 SkipGram,一定有同学会想到 CBOW。实际上 CBOW 更符合常人的思考逻辑,它建模词语上下文的方法很简单,如下图所示:

它从若干文档的文段中随机抽取出5 个连续的词, 然后类似做完形填空,希望模型能够根据上下文 预测。而 SkipGram 则恰恰相反,如下图所示,它是拿用中心词去预测上下文:

虽然看起来 CBOW 更合理,但很多文献指出,用 SkipGram 训出来的词向量效果更好。笔者分析可能存在下面一些原因:

• SkipGram 用一个中心词去预测上下文,这样相当于对这个中心词的表示要求更高,这就好像一个学生(中心词)同时受到了多个老师(上下文)的教导(这个学习的过程可以被理解为中间的梯度传播),效果肯定比一个老师教导多个学生(因此梯度是均分的,没有区分性,而且由于梯度均分,容易破坏一个窗口中词向量的异构性)效果要好得多;

• 其次,SkipGram 这种强调中心词的结构对某些具有较低频率的生僻词比较友好,因此低频词也可以学到质量较高的向量表示;

但可能是因为 CBOW 的结构相对简单些,经验显示,CBOW 的训练速度要比 SkipGram 快的多,因此两者其实各有优势。

拿上面提到的例子 “Can you please come here ?” 说明 SkipGram 的流程。假设滑动窗口的长度为 5,那么现在窗口 cover 住了片段 “can you please come here”。此时以中心词 please 为输入并度量与上下文 can, you,come, here 的相似度,优化时希望这个值尽量高。

在工程上,实现词向量模型有很多trick,例如概率平滑化,高频词抽样等。但如果做个 demo 不需要考虑太多这些细节。不过无论是 CBOW 还是 SkipGram 都无法规避一个问题,就是过高的词典容量。正常情况下,英语词典的容量在 3000 ~ 4000 上下,因此当训练语料很大时会造成巨大的计算负担。为了权衡质量和效率,目前最常用的方法就是负采样。通俗的来说,就是我不再把整个词典当成负样本了,而是随机抽取若干词作为负样本。实现时,这个随机抽取的数量是一个超参数,大概是 20 ~ 30 之间,这样很明显大大提高了计算效率。另外,也有人指出,用一些重要性采样的技术可以进一步改善效果。

4.用飞桨实现

现在你已经基本了解了什么是SkipGram,下面我们就用强大的飞桨一步一步实现它。

现在你已经基本了解了什么是SkipGram,而实现它需要借助现有的深度学习框架。飞桨是百度自主研发的深度学习框架,功能非常强大,同时支持稠密参数、稀疏参数并行训练;静态网络、动态网络等。而且有非常丰富的中英文文档,非常方便您使用。下面我们就用强大的飞桨一步一步实现它.

首先,我们需要导入一些必要的计算库。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# PaddlePaddle 计算引擎.
importpaddle
frompaddle import fluid

# 一些常用的科学计算库.
importnumpy as np
importmatplotlib.pyplot as plt

然后设置定义一些超参数,用于控制网络结构和训练逻辑。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
EMBEDDING_DIM =64  # 词向量维度.
WINDOW_SIZE =5     #滑动窗口大小.
BATCH_SIZE =200    #迭代 batch 大小.
EPOCH_NUM =10      #训练的轮数.
RANDOM_STATE =0    #设置伪随机数种子.

然后就是文本数据,这里使用飞桨自带(会自动下载)的 PTB 数据集,导入如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from paddle.dataset import imikolov

word_vocab =imikolov.build_dict()
vocab_size =len(word_vocab)

# 打印 PTB 数据字典的容量大小.
print("imikolov 字典大小为 "+str(vocab_size))

# 类似 Pytorch 的 DataLoader, 用于在训练时做 batch, 很方便.
data_loader =paddle.batch(imikolov.test(word_vocab, WINDOW_SIZE), BATCH_SIZE)

imikolov字典大小为 2074

下面我们需要搭建SkipGram 的网络结构,我们用一个函数打包如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def build_neural_network():
    assertWINDOW_SIZE %2==1
   medium_num = WINDOW_SIZE //2

    # 定义输入变量, 是从文本中截取的连续的文本段.
   var_name_list = [str(i) +"-word"for i inrange(0, WINDOW_SIZE)]
   word_list = [fluid.layers.data(name=n, shape=[1], dtype="int64")for n in var_name_list]

    # 取中心词作为输入, 而周围上下文作为输出.
   input_word = word_list[medium_num]
   output_context = word_list[:medium_num] + word_list[medium_num +1:]

    # 将输入输出都做词向量表示, 并且将输出拼起来.
   embed_input = fluid.layers.embedding(
        input=input_word, size=[vocab_size, EMBEDDING_DIM],
       dtype="float32",is_sparse=True,param_attr="input_embedding")
   embed_output_list = [fluid.layers.embedding(
        input=w, size=[vocab_size, EMBEDDING_DIM], dtype="float32",
       is_sparse=True,param_attr="output_embedding")for w in output_context]
   concat_output = fluid.layers.concat(input=embed_output_list,axis=1)

    # 用 -log(sigmoid(score)) 作为度量损失函数.
    var_score =fluid.layers.matmul(embed_input, concat_output, transpose_x=True)
   avg_loss =0-fluid.layers.mean(fluid.layers.log(fluid.layers.sigmoid(var_score)))

    # 使用 Adam 优化算法, 并注意需要返回变量定义名.
   fluid.optimizer.AdamOptimizer().minimize(avg_loss)
    returnavg_loss, var_name_list

类似于 Tensorflow,运行 PaddlePaddle 计算引擎前需要一些热身代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 确定执行的环境, 如果支持 CUDA 可以调用CUDAPlace 函数.
device_place =fluid.CPUPlace()
executor = fluid.Executor(device_place)

main_program =fluid.default_main_program()
star_program =fluid.default_startup_program()

# 固定伪随机数种子, 一般用于保证论文效果可复现.
main_program.random_seed =RANDOM_STATE
star_program.random_seed =RANDOM_STATE

# 定义模型的架构 (之前定义函数输出) 以及模型的输入.
train_loss, tag_list =build_neural_network()
feed_var_list =[main_program.global_block().var(n) for n in tag_list]
data_feeder =fluid.DataFeeder(feed_list=feed_var_list, place=device_place)

下面开始训练模型的流程,将迭代器产生的 batch 不断喂入网络中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
executor.run(star_program)
forepoch_idx inrange(EPOCH_NUM):
   total_loss, loss_list =0.0, []

    forbatch_data in data_loader():
       total_loss +=float(executor.run(
           main_program, feed=data_feeder.feed(batch_data),
           fetch_list=[train_loss])[0])
   loss_list.append(total_loss)
    print("[迭代轮数{:4d}], 在训练集的损失为{:.6f}".format(epoch_idx, total_loss))

[迭代轮数 0], 在训练集的损失为 75.395110 [迭代轮数 1], 在训练集的损失为 2.346059 [迭代轮数 2], 在训练集的损失为 0.797208 [迭代轮数 3], 在训练集的损失为 0.413886 [迭代轮数 4], 在训练集的损失为 0.254423 [迭代轮数 5], 在训练集的损失为 0.171255 [迭代轮数 6], 在训练集的损失为 0.121907 [迭代轮数 7], 在训练集的损失为 0.090095 [迭代轮数 8], 在训练集的损失为 0.068378 [迭代轮数 9], 在训练集的损失为 0.052923

我们可以将刚才训练过程中的损失用 matplotlib 的库函数画出来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
plt.plot(np.array(range(0, len(loss_list))),loss_list)

好啦,以上就是本次所要分享。总的来说,本节我们主要讲述了什么是词向量,什么是语言模型,SkipGram 算法的内容以及其特性,相对 CBOW 来说它对低频词更友好,而且词向量质量更佳,最后我们还细致的教您一步一步用飞桨实现一个简单的 SkipGram 模型。希望您多多支持,咱们下期再会。

想与更多的深度学习开发者交流,请加入飞桨官方QQ群:796771754

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

官网地址:https://www.paddlepaddle.org.cn

Skip-Gram相关内容参考项目地址:

https://github.com/PaddlePaddle/models/tree/v1.5.1/PaddleRec/word2vec

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PaddlePaddle 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
3.词向量word2vec(图学习参考资料1)
项目链接: https://aistudio.baidu.com/aistudio/projectdetail/5009409
汀丶人工智能
2022/11/20
5030
用飞桨做自然语言处理:神经网络语言模型应用实例
语言模型的身影遍布在NLP研究中的各个角落,想要了解NLP领域,就不能不知道语言模型。
量子位
2019/08/15
5420
基于PaddlePaddle的词向量实战 | 深度学习基础任务教程系列(二)
词向量是自然语言处理中常见的一个操作,是搜索引擎、广告系统、推荐系统等互联网服务背后常见的基础技术。
用户1386409
2019/06/10
5030
基于PaddlePaddle的词向量实战 | 深度学习基础任务教程系列(二)
用飞桨做命名实体识别,手把手教你实现经典模型 BiGRU + CRF
命名实体识别(Named Entity Recognition,NER)是 NLP 几个经典任务之一,通俗易懂的来说,就是从一段文本中抽取出需求的关键词,如地名,人名等。
用户1386409
2019/09/25
1.6K0
用飞桨做命名实体识别,手把手教你实现经典模型 BiGRU + CRF
【词向量】Hsigmoid加速词向量训练
导语 PaddlePaddle提供了丰富的运算单元,帮助大家以模块化的方式构建起千变万化的深度学习模型来解决不同的应用问题。这里,我们针对常见的机器学习任务,提供了不同的神经网络模型供大家学习和使用。本周推文目录如下: 周三:【词向量】Hsigmoid加速词向量训练 周四:【词向量】 噪声对比估计加速词向量训练 周五:【RNN语言模型】使用RNN语言模型生成文本 词向量用一个实向量表示词语,向量的每个维都表示文本的某种潜在语法或语义特征,是深度学习应用于自然语言处理领域最成功的概念和成果之一。广义的,词向量
用户1386409
2018/03/15
1.1K0
【词向量】Hsigmoid加速词向量训练
词义类比与全局词共现信息不可兼得?基于飞桨实现的GloVe说可以
通过飞桨核心框架复现的GloVe模型具有良好的性能表现。针对论文给出的训练文本,处理后文本总词量为17M,模型的训练时间在1000s左右,达到了快速训练词向量的要求,可以用来训练大规模的文本数据。模型的详细情况和编程可以参考链接:
用户1386409
2020/08/11
6010
词义类比与全局词共现信息不可兼得?基于飞桨实现的GloVe说可以
超火的个性化推荐你再不会就OUT啦,让飞桨手把手来教你
导读:随着电子商务规模的不断扩大,电商平台的商品数量和种类呈爆发式增长,用户往往需要花费大量的时间才能找到自己想买的商品,这就是信息超载问题。为了解决这个难题,“个性化推荐”技术应运而生,有效地节约用户时间,提升电商成单率。本篇文章中,将为大家介绍个性化推荐系统的实现方法,并送上一份基于飞桨(PaddlePaddle)实现个性化推荐的代码教程。
用户1386409
2019/10/14
4820
超火的个性化推荐你再不会就OUT啦,让飞桨手把手来教你
大语言模型-01-语言模型发展历程-02-从神经网络到ELMo
早期工作MLP(Multilayer Perceptron,MLP,多层感知机): NNLM(Neural Network Language Model,神经网络语言模型),单词映射到词向量,再由神经网络预测当前时刻词汇。是一种通过神经网络进行语言建模的技术,通常用于预测序列中的下一个词。
用户2225445
2025/03/15
1460
大语言模型-01-语言模型发展历程-02-从神经网络到ELMo
大语言模型-1.1-语言模型发展历程
本博客内容是《大语言模型》一书的读书笔记,该书是中国人民大学高瓴人工智能学院赵鑫教授团队出品,覆盖大语言模型训练与使用的全流程,从预训练到微调与对齐,从使用技术到评测应用,帮助学员全面掌握大语言模型的核心技术。并且,课程内容基于大量的代码实战与讲解,通过实际项目与案例,学员能将理论知识应用于真实场景,提升解决实际问题的能力。
用户2225445
2025/03/15
1200
大语言模型-1.1-语言模型发展历程
一文教你实现skip-gram模型,训练并可视化词向量
在本教程中,我将展示如何在Tensorflow中实现一个Word2Vec(Word2Vec是从大量文本语料中以无监督的方式学习语义知识的一种模型,它被大量地用在自然语言处理中)的skip-gram模型,为你正在使用的任何文本生成词向量,然后使用Tensorboard将它们可视化。 我在text8数据集上训练了一个skip-gram模型。然后,我用Tensorboard来设想这些Embedding,Embedding其实就是一个映射,将单词从原先所属的空间映射到新的多维空间中,也就是把原先词所在空间嵌入到一个
AiTechYun
2018/03/06
2K0
一文教你实现skip-gram模型,训练并可视化词向量
【AI 大模型】RAG 检索增强生成 ③ ( 文本向量 | Word2Vec 词汇映射向量空间模型 - 算法原理、训练步骤、应用场景、实现细节 | Python 代码示例 )
Word2Vec 是一个 将 词汇 映射 到 高维向量空间 的模型 , 其 核心思想 是 通过大量的文本数据来学习每个词的向量表示 , 使得 语义相似 的 单词 或 汉字 在向量空间中彼此接近 ;
韩曙亮
2024/08/20
1.3K0
【AI 大模型】RAG 检索增强生成 ③ ( 文本向量 | Word2Vec 词汇映射向量空间模型 - 算法原理、训练步骤、应用场景、实现细节 | Python 代码示例 )
基于飞桨PaddlePaddle的语义角色标注任务全解析
自然语言处理中的自然语言句子级分析技术,可以大致分为词法分析、句法分析、语义分析三个层面。
用户1386409
2019/07/02
9600
5大典型模型测试单机训练速度超对标框架,飞桨如何做到?
为方便用户使用,飞桨提供一些不同粒度的Layer,其中有些Layer的组合可以通过单个Layer完成。比如:
AI科技大本营
2019/08/09
5520
手把手教你如何用飞桨自动生成二次元人物头像
每次生成一组shape为[1,72]的随机数,更改其中某个数值,依次生成20组随机数,作为生成网络的输入,得到横向对比图片,观察GAN带来的神奇效果,如下所示。
用户1386409
2020/06/17
8050
手把手教你如何用飞桨自动生成二次元人物头像
用飞桨检测谣言,新技能get!
https://aistudio.baidu.com/aistudio/projectdetail/263255
用户1386409
2020/03/04
8000
更快更简单|飞桨PaddlePaddle单机训练速度优化最佳实践
导读:飞桨(PaddlePaddle)致力于让深度学习技术的创新与应用更简单。在单机训练速度方面,通过高并行、低开销的异步执行策略和高效率的核心算子,优化静态图训练性能,在Paddle Fluid v1.5.0的基准测试中,在7个典型模型上进行了测试(图像领域5个,NLP领域2个),其中5个模型的速度显著优于对标框架(大于15%),2个模型与对标框架持平(5%之内)。如果想让单机训练速度更快,可以根据这篇文档的建议从网络构建、数据准备、模型训练三个方向了解飞桨单机训练中常用的优化方法。来一组测试数据先睹为快。
用户1386409
2019/07/30
9660
更快更简单|飞桨PaddlePaddle单机训练速度优化最佳实践
DL杂记:word2vec之TF-IDF、共轭矩阵、cbow、skip-gram
版权声明:本文为博主原创文章,未经博主允许不得转载。有问题可以加微信:lp9628(注明CSDN)。 https://blog.csdn.net/u014365862/article/details/87800246
MachineLP
2019/05/26
8050
词向量(1)--从Word2Vec到ELMo
若你是做NLP的,一定对词向量很亲切,若你是做推荐的,对词向量也一定不会陌生,以词向量为代表的序列向量化方法已经成为机器学习中必不可少的实战利器。
流川枫
2020/04/24
9180
Word-Embedding词向量
在自然语言处理任务中,词向量(Word Embedding)是表示自然语言里单词的一种方法,即把每个词都表示为一个N维空间内的点,即一个高维空间内的向量。通过这种方法,实现把自然语言计算转换为向量计算。
灯珑LoGin
2022/10/31
7850
Word-Embedding词向量
TF入门04-TF实现Word2Vec
Word2Vec是一组用来产生词嵌入的模型,包括两种主要的模型:skip-gram和CBOW。
公众号-不为谁写的歌
2020/07/23
1.1K0
推荐阅读
相关推荐
3.词向量word2vec(图学习参考资料1)
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验