前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[L3]实战语言模型~构建embedding层

[L3]实战语言模型~构建embedding层

作者头像
触摸壹缕阳光
发布2020-06-04 14:58:47
1.3K0
发布2020-06-04 14:58:47
举报

相信我,我们可以更快乐,因为童真只是一种态度!

——宫崎骏

全文字数:2507字

阅读时间:10分钟

前言

由于在公众号上文本字数太长可能会影响阅读体验,因此过于长的文章,我会使用"[L1]"来进行分段。这个系列将主要借鉴《Tensorflow实战Google学习框架》这本书,主要介绍实现语言模型的一些前期准备,后期会出更详细的文章。

实战语言模型系列:

[L1]实战语言模型~语料词典的生成

[L2]实战语言模型~数据batching

a

Embedding 层

在介绍完了如何处理数据以及如何构造样本之后,就可以构建我们的神经网络语言模型了,下面是使用LSTM构建的语言模型的大体结构:

▲使用循环神经网络实现自然语言模型的示意图

那可以看出上面着重写出来的两层:

  1. embedding层;
  2. softmax层;

那接下来介绍embedding层。embedding层也称为词向量层或者是词嵌入层。那大家肯定知道在自然语言中词的表示方法类型有两种:

  1. 独热one-hot表示方式;
  2. 分布式表示方式;

下面来简单说一说这两种表示方式,理解了这两种词的表示方式能够更好的了解为什么需要词向量层。

独热one-hot表示方式

这种方式是目前最常用的词的表示方法,这种方法把每个词表示为一个很长的词向量,这个很长向量的维度就是词项(不重复的词)字典中的个数,也就是我们在前面构造ptb数据集时候构造的字典。回忆我们在构造字典的时候把每个词按照词频进行排序,然后每一行代表一个词。one-hot表示方式说的就是词汇表中的单词都用一个词汇表那么长的向量表示,只有在词汇表中对应单词的位置为1,其余的所有位置都是0,通过这样稀疏的向量来表示这个单词。这种方式的缺点和优点点都很明显:

  • 缺点:任意两个词之间都是孤立的,任意两个词之间都是孤立的,根本无法表示出在语义层面上词之间的相关信息;

其实one-hot仅仅是将词符号化,后来就出现了词的分布表示。

词的分布表示

Harris在1954年提出的分布假说为词的分布表示提供了理论基础,假说的基本内容说的是"上下文相似的词,其语义也相似"。后来Firth在1957年对分布假说进行了进一步的阐述和明确:"词的语义由上下文决定"。

到目前为止,基于分布假说的词表示方法,根据建模的不同,主要分成:

  1. 基于矩阵的分布表示;
  2. 基于聚类的分布表示;
  3. 基于神经网络的分布表示;

虽然这些分布表示的方法不同,但是这些分布表示都是基于分布假说的,他们的核心思想也都有两部分组成:

  1. 选择一种方式来描述上下文;
  2. 选择一种模型刻画某个词与其上下文之间的关系;

我们使用神经网络能够很高效方便的描述出分布假说的核心思想的两个部分。而恰巧我们的语言模型具有能够捕捉上下文信息的能力,那么构建上下文与目标词之间的关系,最自然的一种思路就是使用语言模型。所以早期的词向量仅仅是神经网络训练语言模型的副产品。将one-hot转换成词向量主要有两大作用:

  • 降低了输入的维度。如果不使用词向量,而直接将单词以one-hot vector的形式输入循环神经网络,那么输入的维度大小将与词汇表的大小相同,通常在10000以上。而词向量的维度通常在200~1000之间,这将大大的减少循环神经网络的参数数量与计算量,将维度也相当与将原来稀疏的巨大的维度压缩嵌入到一个小的维度空间上,所以词向量才有了词嵌入的别名;
  • 增加语义信息。简单的单词编号是不包含任何的语义信息的。两个单词之间编号越相近,并不意味着他们的含义有任何的关联(我们创建词汇表的时候按照的是词频的大小来排序的)。而词向量将稀疏编号转换为稠密的向量表示,这使得向量有可能包含更为丰富的信息。在自然语言应用中学习到的词向量通常会将含义相似的词赋予取值相近的词向量值,使得上层的网络可以更为容易的抓住相似单词之间的共性。

说了这么多词向量,而且上面也说了词向量是由语言模型训练的,所以对于大家熟悉的word2vec中的CBOW以及skip-gram仅仅是训练语言模型的一种方式。有人会说那和我们的embedding层有什么关系呢?其实对于我们现在的任务来说,embedding层和word2vec(实质上也就是一个两层的神经网络)的作用和效果一样,因为他们都是使用语言模型训练出来的。那你可能有疑问,因为很多时候,我们看到没有训练语言模型的时候仍然使用embedding层,那这就和使用语言模型训练词向量有点矛盾,其实这也是embedding层和word2vec的区别所在,embedding层是根据我们的任务所定,训练与我们任务有关系的词向量,和我们训练的任务有很大的关系,但是使用word2vec的话,仅仅是使用语言模型训练出来的词向量,表示的是一个词的向量空间,使用Word2vec的话,往往和我们的任务有很大的距离。

假设词向量的维度是EMB_SIZE,词汇表的大小为VOCAB_SIZE,那么所有单词的词向量可以放入一个大小为VOCAB_SIZE * EMB_SIZE。在读取词向量的时候,tensorflow给我们提供了一个tf.nn.embedding_lookup方法,那下面看看如何在使用tensorflow实现embedding层:

代码语言:javascript
复制
import tensorflow as tf

#这里仅仅使用get_variable声明了一个名字叫做"embedding"的词向量矩阵
embedding = tf.get_variable("embedding",[VOCAB_SIZE,EMB_SIZE])
input_embedding = tf.nn.embedding_lookup(embedding,input_data)

这样一看觉得还是很难理解,下面我通过一个简单的例子来演示一下:

代码语言:javascript
复制
import tensorflow as tf

#词汇表为4
VOCAB_SIZE = 4
#将维度到2
EMB_SIZE = 2

#随机生成一个词向量矩阵
embedding = tf.get_variable(
    name = "embedding",
    shape =(VOCAB_SIZE,EMB_SIZE),
    initializer=tf.truncated_normal_initializer(stddev = 0.1) )

input_data = [0,1]
input_embedding = tf.nn.embedding_lookup(embedding,input_data)
with tf.Session() as sess:
    #初始化变量
    sess.run(tf.global_variables_initializer())
    # 打印出随机初始化的词向量矩阵
    print("embedding layer:"+ str(sess.run(embedding)) )
    print("embedding layer output:" + str(sess.run(input_embedding)))

▲embedding层的过程

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

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
NLP 服务
NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档