掘金 人工智能 22小时前
自然语言处理基础-迈向NLP领域的第1步台阶
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了词向量的概念及其在自然语言处理(NLP)中的应用,重点讲解了如何将词转换为向量,以及如何让这些向量具备语义信息。文章详细阐述了word2vec模型中的CBOW和Skip-gram两种训练算法,并通过飞桨(PaddlePaddle)框架,提供了Skip-gram模型的实际实现方法。通过对文本数据的处理、网络定义、训练和评估,帮助读者理解词向量的构建过程。

🧠词向量是将词汇转化为数值向量的方法,在NLP任务中至关重要,它通过将自然语言转换为向量计算,使计算机能够理解词语之间的语义关系。

🔑为了将词转换为向量,通常使用查询表或字典,将每个词映射到一个高维向量。在神经网络计算中,这种映射通过张量计算实现,包括One-Hot Encoding,将单词转换为固定长度的向量。

💡为了使词向量具备语义信息,word2vec算法通过分析单词的上下文来学习语义。CBOW模型通过上下文预测中心词,而Skip-gram模型则通过中心词预测上下文,两种方式都能捕捉词语之间的关联。

💻Skip-gram模型是word2vec的一种实现方式,它通过构建神经网络,利用负采样等技术,实现对大量词汇的快速训练。通过飞桨框架,可以实现Skip-gram模型的训练、评估,从而掌握词向量的构建方法。

词向量:迈向NLP领域的第1步台阶

1. 词向量概述

在自然语言处理任务中,词向量(Word Embedding)是表示自然语言里单词的一种方法,即把每个词都表示为一个N维空间内的点,即一个高维空间内的向量。通过这种方法,实现把自然语言计算转换为向量计算。

图1 所示的词向量计算任务中,先把每个词(如queen,king等)转换成一个高维空间的向量,这些向量在一定意义上可以代表这个词的语义信息。再通过计算这些向量之间的距离,就可以计算出词语之间的关联关系,从而达到让计算机像计算数值一样去计算自然语言的目的。

图1:词向量计算示意图

因此,大部分词向量模型都需要回答两个问题:

    如何把词转换为向量?

自然语言单词是离散信号,比如“香蕉”,“橘子”,“水果”在我们看来就是3个离散的词。

如何把每个离散的单词转换为一个向量?

    如何让向量具有语义信息?

比如,我们知道在很多情况下,“香蕉”和“橘子”更加相似,而“香蕉”和“句子”就没有那么相似,同时“香蕉”和“食物”、“水果”的相似程度可能介于“橘子”和“句子”之间。

那么,我们该如何让词向量具备这样的语义信息?

1.1 如何把词转换为向量

自然语言单词是离散信号,比如“我”、“ 爱”、“人工智能”。如何把每个离散的单词转换为一个向量?通常情况下,我们可以维护一个如 图2 所示的查询表。表中每一行都存储了一个特定词语的向量值,每一列的第一个元素都代表着这个词本身,以便于我们进行词和向量的映射(如“我”对应的向量值为 [0.3,0.5,0.7,0.9,-0.2,0.03] )。给定任何一个或者一组单词,我们都可以通过查询这个excel,实现把单词转换为向量的目的,这个查询和替换过程称之为Embedding Lookup。


图2:词向量查询表


上述过程也可以使用一个字典数据结构实现。事实上如果不考虑计算效率,使用字典实现上述功能是个不错的选择。然而在进行神经网络计算的过程中,需要大量的算力,常常要借助特定硬件(如GPU)满足训练速度的需求。GPU上所支持的计算都是以张量(Tensor)为单位展开的,因此在实际场景中,我们需要把Embedding Lookup的过程转换为张量计算,如 图3 所示。


图3:张量计算示意图


假设对于句子"我,爱,人工,智能",把Embedding Lookup的过程转换为张量计算的流程如下:

    通过查询字典,先把句子中的单词转换成一个ID(通常是一个大于等于0的整数),这个单词到ID的映射关系可以根据需求自定义(如图3中,我=>1, 人工=>2,爱=>3,...)。

    得到ID后,再把每个ID转换成一个固定长度的向量。假设字典的词表中有5000个词,那么,对于单词“我”,就可以用一个5000维的向量来表示。由于“我”的ID是1,因此这个向量的第一个元素是1,其他元素都是0([1,0,0,…,0]);同样对于单词“人工”,第二个元素是1,其他元素都是0。用这种方式就实现了用一个向量表示一个单词。由于每个单词的向量表示都只有一个元素为1,而其他元素为0,因此我们称上述过程为One-Hot Encoding。

    经过One-Hot Encoding后,句子“我,爱,人工,智能”就被转换成为了一个形状为 4×5000的张量,记为VV。在这个张量里共有4行、5000列,从上到下,每一行分别代表了“我”、“爱”、“人工”、“智能”四个单词的One-Hot Encoding。最后,我们把这个张量VV和另外一个稠密张量WW相乘,其中WW张量的形状为5000 × 128(5000表示词表大小,128表示每个词的向量大小)。经过张量乘法,我们就得到了一个4×128的张量,从而完成了把单词表示成向量的目的。

1.2 如何让向量具有语义信息

得到每个单词的向量表示后,我们需要思考下一个问题:比如在多数情况下,“香蕉”和“橘子”更加相似,而“香蕉”和“句子”就没有那么相似;同时,“香蕉”和“食物”、“水果”的相似程度可能介于“橘子”和“句子”之间。那么如何让存储的词向量具备这样的语义信息呢?

我们先学习自然语言处理领域的一个小技巧。在自然语言处理研究中,科研人员通常有一个共识:使用一个单词的上下文来了解这个单词的语义,比如:

“苹果手机质量不错,就是价格有点贵。”

“这个苹果很好吃,非常脆。”

“菠萝质量也还行,但是不如苹果支持的APP多。”

2. word2vec 词向量训练算法

2013年,Mikolov提出的经典word2vec算法就是通过上下文来学习语义信息。word2vec包含两个经典模型:CBOW(Continuous Bag-of-Words)和Skip-gram,如 图4 所示。


图4:CBOW和Skip-gram语义学习示意图

假设有一个句子“Pineapples are spiked and yellow”,两个模型的推理方式如下:


说明:

一般来说,CBOW比Skip-gram训练速度快,训练过程更加稳定,原因是CBOW使用上下文average的方式进行训练,每个训练step会见到更多样本。而在生僻字(出现频率低的字)处理上,skip-gram比CBOW效果更好,原因是skip-gram不会刻意回避生僻字(CBOW结构中输入中存在生僻字时,生僻字会被其它非生僻字的权重冲淡)。

2.1 CBOW和Skip-gram的网络结构

CBOW的网络结构如 图5 所示,其是一个具有3层结构的神经网络:输入层、隐藏层和输出层。下面我们以这句话:“Pineapples are spiked and yellow”为例展开介绍CBOW的网络结构。


图5:CBOW的算法实现

𝑠𝑜𝑓𝑡𝑚𝑎𝑥(𝑂𝑖)=𝑒𝑥𝑝(𝑂𝑖)∑𝑗𝑒𝑥𝑝(𝑂𝑗)𝑠𝑜𝑓𝑡𝑚𝑎𝑥(Oi)=exp(Oi)∑jexp(Oj)

Skip-gram的网络结构如 图6 所示,其同样是一个具有3层结构的神经网络:输入层、隐藏层和输出层。


图6:Skip-gram算法实现

在实际操作中,使用一个滑动窗口(一般情况下,长度是奇数),从左到右开始扫描当前句子。每个扫描出来的片段被当成一个小句子,每个小句子中间的词被认为是中心词,其余的词被认为是这个中心词的上下文。

下面,我们以Skip-gram模型为例,进一步学习Skip-gram模型的具体实现。

2.2 实现Skip-gram

2.2.1 Skip-gram的理想实现

使用神经网络实现Skip-gram中,模型接收的输入应该有2个不同的tensor:

在理想情况下,我们可以使用一个简单的方式实现skip-gram。即把需要推理的每个目标词都当成一个标签,把skip-gram当成一个大规模分类任务进行网络构建,过程如下:

    声明一个形状为[vocab_size, embedding_size]的张量,作为需要学习的词向量,记为𝑊0W0。对于给定的输入𝑉V,使用向量乘法,将𝑉V乘以𝑊0W0,这样就得到了一个形状为[batch_size, embedding_size]的张量,记为𝐻=𝑉×𝑊0H=V×W0。这个张量𝐻H就可以看成是经过词向量查表后的结果。声明另外一个需要学习的参数𝑊1W1,这个参数的形状为[embedding_size, vocab_size]。将上一步得到的𝐻H去乘以𝑊1W1,得到一个新的tensor 𝑂=𝐻×𝑊1O=H×W1,此时的𝑂O是一个形状为[batch_size, vocab_size]的tensor,表示当前这个mini-batch中的每个中心词预测出的目标词的概率。使用softmax函数对mini-batch中每个中心词的预测结果做归一化,即可完成网络构建。
2.2.2 Skip-gram的实际实现

然而在实际情况中,vocab_size通常很大(几十万甚至几百万),导致𝑊0W0和𝑊1W1也会非常大。对于𝑊0W0而言,所参与的矩阵运算并不是通过一个矩阵乘法实现,而是通过指定ID,对参数𝑊0W0进行访存的方式获取。然而对𝑊1W1而言,仍要处理一个非常大的矩阵运算(计算过程非常缓慢,需要消耗大量的内存/显存)。为了缓解这个问题,通常采取负采样(negative_sampling)的方式来近似模拟多分类任务。此时新定义的𝑊0W0和𝑊1W1均为形状为[vocab_size, embedding_size]的张量。

假设有一个中心词𝑐c和一个上下文词正样本𝑡𝑝tp。在Skip-gram的理想实现里,需要最大化使用𝑐c推理𝑡𝑝tp的概率。在使用softmax学习时,需要最大化𝑡𝑝tp的推理概率,同时最小化其他词表中词的推理概率。之所以计算缓慢,是因为需要对词表中的所有词都计算一遍。然而我们还可以使用另一种方法,就是随机从词表中选择几个代表词,通过最小化这几个代表词的概率,去近似最小化整体的预测概率。比如,先指定一个中心词(如“人工”)和一个目标词正样本(如“智能”),再随机在词表中采样几个目标词负样本(如“日本”,“喝茶”等)。有了这些内容,我们的skip-gram模型就变成了一个二分类任务。对于目标词正样本,我们需要最大化它的预测概率;对于目标词负样本,我们需要最小化它的预测概率。通过这种方式,我们就可以完成计算加速。上述做法,我们称之为负采样。

在实现的过程中,通常会让模型接收3个tensor输入:

模型训练过程如下:

    用𝑉V去查询𝑊0W0,用𝑇T去查询𝑊1W1,分别得到两个形状为[batch_size, embedding_size]的tensor,记为𝐻1H1和𝐻2H2。将这两个tensor进行点积运算,最终得到一个形状为[batch_size]的tensor 𝑂=[𝑂𝑖=∑𝑗𝐻0[𝑖,𝑗]×𝐻1[𝑖,𝑗]]𝑏𝑎𝑡𝑐ℎ_𝑠𝑖𝑧𝑒𝑖=1O=[Oi=∑jH0[i,j]×H1[i,j]]i=1batch_size。使用sigmoid函数作用在𝑂O上,将上述点积的结果归一化为一个0-1的概率值,作为预测概率,根据标签信息𝐿L训练这个模型即可。

在结束模型训练之后,一般使用𝑊0W0作为最终要使用的词向量,用𝑊0W0的向量表示。通过向量点乘的方式,计算不同词之间的相似度。

3. 使用飞桨实现Skip-gram

接下来我们将学习使用飞桨实现Skip-gram模型的方法。在飞桨中,不同深度学习模型的训练过程基本一致,流程如下:

    数据处理:选择需要使用的数据,并做好必要的预处理工作。网络定义:使用飞桨定义好网络结构,包括输入层,中间层,输出层,损失函数和优化算法。网络训练:将准备好的数据送入神经网络进行学习,并观察学习的过程是否正常,如损失函数值是否在降低,也可以打印一些中间步骤的结果出来等。网络评估:使用测试集合测试训练好的神经网络,看看训练效果如何。

在数据处理前,需要先加载飞桨平台(如果用户在本地使用,请确保已经安装飞桨)。

# encoding=utf8import ioimport osimport sysimport requestsfrom collections import OrderedDict import mathimport randomimport numpy as npimport paddlefrom paddle.nn import Embeddingimport paddle.nn.functional as Fimport paddle.nn as nn

3.1 数据处理

3.1.1 数据下载

首先,找到一个合适的语料用于训练word2vec模型。使用text8数据集,这个数据集里包含了大量从维基百科收集到的英文语料,我们可以通过如下代码下载数据集,下载后的文件被保存在当前目录的“text8.txt”文件内。

# 下载语料用来训练word2vecdef download():    # 可以从百度云服务器下载一些开源数据集(dataset.bj.bcebos.com)    corpus_url = "https://dataset.bj.bcebos.com/word2vec/text8.txt"    # 使用python的requests包下载数据集到本地    web_request = requests.get(corpus_url)    corpus = web_request.content    # 把下载后的文件存储在当前目录的text8.txt文件内    with open("./text8.txt", "wb") as f:        f.write(corpus)    f.close()download()

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

词向量 NLP word2vec Skip-gram 飞桨
相关文章