cbow word2vec 损失_词向量word2vec之CBOW算法

词向量模型之CBOW模型的原理与实现

关于词向量模型word2rec,平台里只有skip-gram一个模型的代码实现,本项目将对word2rec算法的第二个模型——CBOW模型进行补充

此项目用于交流与学习,如有问题,请大家积极指出,作者将第一时间在后续的版本中进行改正与优化,感谢大家支持!

欢迎大家来逛我的主页

来AI Studio互粉吧~等你哦~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/218138

CBOW的原理

2013年,Mikolov提出了经典的word2vec算法,该算法通过上下文来学习语义信息。word2vec包含两个经典模型,CBOW(Continuous Bag-of-Words)和Skip-gram.

我们重点介绍一下CBOW模型的原理:

举个例子:Two boys are playing basketball.

在这个句子中我们定'are'为中心词,则Two,boys,playing,basketball为上下文。CBOW模型的原理就是利用上下文来预测中心词,即利用Two,boys,playing,basketball预测中心词:are。这样一来,are的语义就会分别传入上下文的信息中。不难想到,经过大量样本训练,一些量词,比如one,two就会自动找到它们的同义词,因为它们都具有are等中心词的语义。

CBOW的算法实现

对比Skip-gram,CBOW和Skip-gram的算法实现如图1所示。本项目将补充CBOW的算法实现过程

图1:CBOW和Skip-gram的算法实现

如图1所示,CBOW是一个具有3层结构的神经网络,分别是:

Input Layer(输入层):接收one-hot张量V∈R1×vocab_sizeV \in R^{1 \times \text{vocab\_size}}V∈R1×vocab_size作为网络的输入,里面存储着当前句子中上下文单词的one-hot表示。

Hidden Layer(隐藏层):将张量VVV乘以一个word embedding张量W1∈Rvocab_size×embed_sizeW^1 \in R^{\text{vocab\_size} \times \text{embed\_size}}W1∈Rvocab_size×embed_size,并把结果作为隐藏层的输出,得到一个形状为R1×embed_sizeR^{1 \times \text{embed\_size}}R1×embed_size的张量,里面存储着当前句子上下文的词向量。

Output Layer(输出层):将隐藏层的结果乘以另一个word embedding张量W2∈Rembed_size×vocab_sizeW^2 \in R^{\text{embed\_size} \times \text{vocab\_size}}W2∈Rembed_size×vocab_size,得到一个形状为R1×vocab_sizeR^{1 \times \text{vocab\_size}}R1×vocab_size的张量。这个张量经过softmax变换后,就得到了使用当前上下文对中心的预测结果。根据这个softmax的结果,我们就可以去训练词向量模型。

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

CBOW算法和skip-gram算法最本质的区别就是:CBOW算法是以上下文预测中心词,而skip-gram算法是以中心城预测上下文。

CBOW的理想实现

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

代表当前上下文的tensor:假设我们称之为context_wordsVVV,一般来说,这个tensor是一个形状为[batch_size, vocab_size]的one-hot tensor,表示在一个mini-batch中,每组上下文中每一个单词的ID。

代表目标词的tensor:假设我们称之为target_wordsTTT,一般来说,这个tensor是一个形状为[batch_size, 1]的整型tensor,这个tensor中的每个元素是一个[0, vocab_size-1]的值,代表目标词的ID。

在理想情况下,我们可以这样实现CBOW:把上下文中的每一个单词,依次作为输入,把当前句子中的中心词作为标签,构建神经网络进行学习,实现上下文预测中心词。具体过程如下:

声明一个形状为[vocab_size, embedding_size]的张量,作为需要学习的词向量,记为W0W_0W0​。对于给定的输入VVV,即某一个上下文的单词,使用向量乘法,将VVV乘以W0W_0W0​,这样就得到了一个形状为[batch_size, embedding_size]的张量,记为H=V∗W0H=V*W_0H=V∗W0​。这个张量HHH就可以看成是经过词向量查表后的结果。

声明另外一个需要学习的参数W1W_1W1​,这个参数的形状为[embedding_size, vocab_size]。将上一步得到的HHH去乘以W1W_1W1​,得到一个新的tensorO=H∗W1O=H*W_1O=H∗W1​,此时的OOO是一个形状为[batch_size, vocab_size]的tensor,表示当前这个mini-batch中的每一组上下文中的每一个单词预测出的目标词的概率。

使用softmax函数对mini-batch中每个中心词的预测结果做归一化,即可完成网络构建。

CBOW的实际实现

和课程中讲解的skip-gram一样,在实际中,为避免过于庞大的计算量,我们通常采用负采样的方法,来避免查询整个此表,从而将多分类问题转换为二分类问题。具体实现过程如图6:

图6:CBOW算法的实际实现

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

代表上下文单词的tensor:假设我们称之为context_wordsVVV,一般来说,这个tensor是一个形状为[batch_size, vocab_size]的one-hot tensor,表示在一个mini-batch中每个中心词具体的ID。

代表目标词的tensor:假设我们称之为target_wordsTTT,一般来说,这个tensor同样是一个形状为[batch_size, vocab_size]的one-hot tensor,表示在一个mini-batch中每个目标词具体的ID。

代表目标词标签的tensor:假设我们称之为labelsLLL,一般来说,这个tensor是一个形状为[batch_size, 1]的tensor,每个元素不是0就是1(0:负样本,1:正样本)。

模型训练过程如下:

首先遍历上下文,得到上下文中的一个单词,用VVV(上下文)去查询W0W_0W0​,用TTT(目标词)去查询W1W_1W1​,分别得到两个形状为[batch_size, embedding_size]的tensor,记为H1H_1H1​和H2H_2H2​。

点乘这两个tensor,最终得到一个形状为[batch_size]的tensorO=[Oi=∑jH0[i,j]∗H1[i,j]]i=1batch_sizeO = [O_i = \sum_j H_0[i,j] * H_1[i,j]]_{i=1}^{batch\_size}O=[Oi​=∑j​H0​[i,j]∗H1​[i,j]]i=1batch_size​。

使用随即负采样得到一些负样本(0),同时以目标词作为正样本(1),输入值标签信息label。

使用sigmoid函数作用在OOO上,将上述点乘的结果归一化为一个0-1的概率值,作为预测概率,根据标签信息label训练这个模型即可。

使用飞桨实现CBOW

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

数据处理:选择需要使用的数据,并做好必要的预处理工作。

网络定义:使用飞桨定义好网络结构,包括输入层,中间层,输出层,损失函数和优化算法。

网络训练:将准备好的数据送入神经网络进行学习,并观察学习的过程是否正常,如损失函数值是否在降低,也可以打印一些中间步骤的结果出来等。

训练结果与总结:使用测试集合测试训练好的神经网络,看看训练效果如何。

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

In[

]

import io

import os

import sys

import requests

from collections import OrderedDict

import math

import random

import numpy as np

import paddle

import paddle.fluid as fluid

from paddle.fluid.dygraph.nn import Embedding

数据处理

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

In[

]

#下载语料用来训练word2vec

def 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值