介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现

介绍词向量word2evc概念 , 及CBOW和Skip-gram的算法实现 。 项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5009409
在自然语言处理任务中 , 词向量(WordEmbedding)是表示自然语言里单词的一种方法 , 即把每个词都表示为一个N维空间内的点 , 即一个高维空间内的向量 。 通过这种方法 , 实现把自然语言计算转换为向量计算 。
如图1所示的词向量计算任务中 , 先把每个词(如queen , king等)转换成一个高维空间的向量 , 这些向量在一定意义上可以代表这个词的语义信息 。 再通过计算这些向量之间的距离 , 就可以计算出词语之间的关联关系 , 从而达到让计算机像计算数值一样去计算自然语言的目的 。
介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现
文章图片
因此 , 大部分词向量模型都需要回答两个问题:如何把词转换为向量?
自然语言单词是离散信号 , 比如“香蕉” , “橘子” , “水果”在我们看来就是3个离散的词 。
如何把每个离散的单词转换为一个向量?如何让向量具有语义信息?
比如 , 我们知道在很多情况下 , “香蕉”和“橘子”更加相似 , 而“香蕉”和“句子”就没有那么相似 , 同时“香蕉”和“食物”、“水果”的相似程度可能介于“橘子”和“句子”之间 。
那么 , 我们该如何让词向量具备这样的语义信息?
1.如何把词转换为向量
自然语言单词是离散信号 , 比如“我”、“爱”、“人工智能” 。 如何把每个离散的单词转换为一个向量?通常情况下 , 我们可以维护一个如图2所示的查询表 。 表中每一行都存储了一个特定词语的向量值 , 每一列的第一个元素都代表着这个词本身 , 以便于我们进行词和向量的映射(如“我”对应的向量值为[0.3 , 0.5 , 0.7 , 0.9 , -0.2 , 0.03]) 。 给定任何一个或者一组单词 , 我们都可以通过查询这个excel , 实现把单词转换为向量的目的 , 这个查询和替换过程称之为EmbeddingLookup 。
介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现
文章图片
上述过程也可以使用一个字典数据结构实现 。 事实上如果不考虑计算效率 , 使用字典实现上述功能是个不错的选择 。 然而在进行神经网络计算的过程中 , 需要大量的算力 , 常常要借助特定硬件(如GPU)满足训练速度的需求 。 GPU上所支持的计算都是以张量(Tensor)为单位展开的 , 因此在实际场景中 , 我们需要把EmbeddingLookup的过程转换为张量计算 , 如图3所示 。
介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现
文章图片
假设对于句子"我 , 爱 , 人工 , 智能" , 把EmbeddingLookup的过程转换为张量计算的流程如下:通过查询字典 , 先把句子中的单词转换成一个ID(通常是一个大于等于0的整数) , 这个单词到ID的映射关系可以根据需求自定义(如图3中 , 我=>1,人工=>2 , 爱=>3 , …) 。 得到ID后 , 再把每个ID转换成一个固定长度的向量 。 假设字典的词表中有5000个词 , 那么 , 对于单词“我” , 就可以用一个5000维的向量来表示 。 由于“我”的ID是1 , 因此这个向量的第一个元素是1 , 其他元素都是0([1 , 0 , 0 , … , 0]);同样对于单词“人工” , 第二个元素是1 , 其他元素都是0 。 用这种方式就实现了用一个向量表示一个单词 。 由于每个单词的向量表示都只有一个元素为1 , 而其他元素为0 , 因此我们称上述过程为One-HotEncoding 。 经过One-HotEncoding后 , 句子“我 , 爱 , 人工 , 智能”就被转换成为了一个形状为4×5000的张量 , 记为$V$ 。 在这个张量里共有4行、5000列 , 从上到下 , 每一行分别代表了“我”、“爱”、“人工”、“智能”四个单词的One-HotEncoding 。 最后 , 我们把这个张量$V$和另外一个稠密张量$W$相乘 , 其中$W$张量的形状为5000×128(5000表示词表大小 , 128表示每个词的向量大小) 。 经过张量乘法 , 我们就得到了一个4×128的张量 , 从而完成了把单词表示成向量的目的 。