模型结构

CBOW模型,中文译为“连续词袋模型”,完成的任务是给定中心词 

cordava 文档_词向量

 的一定邻域半径(比如半径为2,通常成为windows,窗口,这里窗口的大小为5)内的单词

cordava 文档_数据_02

,预测输出单词为该中心词

cordava 文档_词向量

 的概率,由于没有考虑词之间的顺序,所以称为词袋模型。论文中给出的CBOW模型的结构如下图:


cordava 文档_cordava 文档_04

在上面的结构示意图中,符号w(t-1),w(t-2),w(t+1),w(t+2) 表示输入的单词,实际是一个one-hot的vector,通过构建词典,建立单词索引可以很容易实现,向量的维度和词典中单词数目相同,只有一个维度的值为1,该维度对应该单词在词典索引中的位置,其余维度的值为0。其中的PROJECTION层是通过查表得到的,首先初始化一个words vector矩阵W,W是一个二维的矩阵,行数等于构建的词典中的单词的数目,依赖具体语料库大小等因素,列数是一个超参数,人为设定,一般为100;论文中给出的结构图太简单,我自己画了一个,如下:

cordava 文档_cordava 文档_05

输入是中心词 

cordava 文档_词向量

 的上下文单词,都是one-hot编码的,我假设了widows size 是5,所以有4个one-hot编码向量的输入

cordava 文档_数据_07

。设输入层矩阵为

cordava 文档_中心词_08

,大小为 

cordava 文档_cordava 文档_09

,其中 

cordava 文档_cordava 文档_10

 是词典的大小 ,

cordava 文档_cordava 文档_11

 是词向量的维度, 

cordava 文档_cordava 文档_12

 向量则是

cordava 文档_中心词_08

的一行,lookup的过程即是如下的操作:

cordava 文档_词向量_14

将one-hot编码的向量 

cordava 文档_词向量

 和 

cordava 文档_中心词_08

 相乘,就是取出了输入矩阵 

cordava 文档_中心词_08

 中 

cordava 文档_词向量

 对应的一行,该行的行号是单词 

cordava 文档_词向量

 在词典中的索引号。经过输入层操作得到的向量是一个稠密的向量(dense),假设为

cordava 文档_数据_20

 。输出层的矩阵设为 

cordava 文档_数据_21

,输出矩阵的大小

cordava 文档_cordava 文档_22

,则输出向量为

cordava 文档_词向量_23

cordava 文档_词向量_24

 的大小为 

cordava 文档_cordava 文档_25

,每一个维度的值可以理解为在当前上下文

cordava 文档_数据_02

环境下,输出的中心单词是字典每一个单词的logit概率,做softmax后,就是每一个单词的概率了。以上描述的也是CBOW模型一次前向传播的过程。

公式详解每一步操作

1、查表(lookup)  从单词到向量


cordava 文档_中心词_27

进行查表即是完成下列操作:

cordava 文档_数据_28

这是一个(n x 1) 的矩阵和一个(n x d)的矩阵之间的矩阵乘法,得到的是一个(1 x d)的向量

cordava 文档_cordava 文档_29

,就是一个向量。这个

cordava 文档_cordava 文档_29

 向量就是单词

cordava 文档_中心词_27

 对应的词向量。同理有:

cordava 文档_cordava 文档_32

cordava 文档_词向量_33

cordava 文档_词向量_34

cordava 文档_cordava 文档_35

2、求和平均(sum and average)

上一步通过lookup,得出了中心词

cordava 文档_中心词_27

 上下文单词

cordava 文档_数据_07

 对应的词向量

cordava 文档_中心词_38

,因为我们要根据这些词向量算出单词

cordava 文档_中心词_27

 出现的概率,所以需要对这4个词向量做求和,然后取平均值,作为PROJECTION层的输出,即

cordava 文档_数据_40

这里做一下说明,论文中给出的求和后取平均值,可以看成是四个上下文 

cordava 文档_数据_07

词向量对生成中心词

cordava 文档_中心词_27

 的贡献是相同的,没有考虑单词的顺序问题(CBOW名称的来源)。

3、输出(output)

这一步需要计算的是由

cordava 文档_数据_07

 生成 

cordava 文档_中心词_27

 的概率。即计算:

cordava 文档_中心词_45

由于经过lookup层后,上下文单词 

cordava 文档_数据_07

 被综合表示成 

cordava 文档_数据_47

 ,所以我们需要计算由

cordava 文档_数据_47

生成中心单词 

cordava 文档_中心词_27

的概率是多大。所以

cordava 文档_数据_50

由于给定上下文时,不止是只能生成中心词,还能生成整个词典中的任何一个单词,只是生成的概率没有中心词概率大,我们用一个通用的公式表示如下:

cordava 文档_词向量_51


表示给定上下文单词 

cordava 文档_数据_07

  时,生成中心单词

cordava 文档_中心词_27

 的概率。这个值是通过对整个字典中的单词做softmax后得到的,具体的计算公式如下:

cordava 文档_中心词_54

其中,

cordava 文档_中心词_55

表示词典的大小, 

cordava 文档_中心词_38

 表示上下文单词的向量。这里不好理解的是

cordava 文档_词向量_57

。在上一步的查表中,可以得知向量 

cordava 文档_数据_58

 就是上下文单词的词向量,因为 

cordava 文档_中心词_38

 就是通过一个one-hot编码的向量和词向量矩阵进行矩阵乘法得到的。

cordava 文档_词向量_57

 就是输出层矩阵

cordava 文档_中心词_61

 中的一行。在李沐的“动手学深度学习”教程中,将 

cordava 文档_cordava 文档_62

 和 

cordava 文档_数据_58

 看成是一个单词的两套词向量,即

cordava 文档_数据_64

  是同一个单词 

cordava 文档_中心词_27

 的两个词向量,对应到CBOW的结果图中,就是一个是输出矩阵中的行,一个输入矩阵中的行。我个人认为这个解释不是太有力,我更倾向于 

cordava 文档_词向量_57

 是一个打分权重,这个打分权重可以理解为在当前上下文输入下,输出单词为

cordava 文档_中心词_27

 的得分是多少,类似于logistic regression中的权重系数。

模型的损失函数及优化

在讲解CBOW模型的损失函数和参数优化前,可以先看看训练数据是什么样子的。假设训练数据是一段文本,长度为T,则在CBOW模型下,训练样本的格式如下:

cordava 文档_cordava 文档_68

训练数据是从长度为T的文本中抽取的,可以抽取很多个上式表达的训练数据。有训练数据,同时我们又建立了概率模型,那么我们就可以定义一个似然函数,使得训练集中样本的似然概率最大。

生成这一段文本的似然概率如下:

cordava 文档_数据_69

其中,

cordava 文档_cordava 文档_70

 不存在,会用特殊的占位符替换。上式就是CBOW的目标函数,为了学习到合适的词向量,需要最大化上述似然函数的值,这等价于最小化如下损失函数的值: 

cordava 文档_中心词_71

将具体的概率公式替换。可得

cordava 文档_数据_72

这个cost fucntion是关于

cordava 文档_cordava 文档_73

的函数,对上式求关于

cordava 文档_cordava 文档_73

的倒数,使用随即梯度下降方法,多次迭代,既可以找到最优值。