Skip-Gram神经网络体系结构

这篇文章是关于NLP的一边文章,但是用到的方法与walk2friends攻击算法几乎一致。方便理解算法


模型介绍

skip-gram神经网络模型最基本的形式实际上是惊人的简单;Word2Vec使用了一个你可能在机器学习中看到过的技巧,我们将训练一个带有单个隐藏层的简单神经网络来完成某个任务,但是实际上我们并没有将这个神经网络用于我们训练的任务。相反,目标实际上只是为了学习隐藏层的权重

另一个技巧是无监督的特征学习,在这里你训练一个自动编码器来压缩隐藏层中的输入向量,并在输出层将其解压缩回原始数据。训练完成后,你将剥离输出图层(解压缩)步骤,然后使用隐藏层,这是学习良好图像特征而不标记训练数据的一种技巧。

假任务

我们要训练神经网络做以下事情。给定一个句子中的特定单词(输入单词),查看附近的单词并随机选择一个单词。网络将告诉我们,我们词汇表中每个单词是我们选择的“邻近单词的概率”。

当说“附近”时,算法实际上有一个“window size”参数。一个典型的窗口大小可能是5,即5个字在前,5个字在后。

输出概率将和我们查找到的字典单词在我们输入词附近的可能性有关。例如,如果你给训练有素的网络输入单词“苏联”,输出是比如“联盟”和“俄罗斯”的概率将比“西瓜”和“袋鼠”这样无关的单词高得多。

我们将通过在训练文档中找到单词对来训练神经网络。下面的例子显示了一些训练样本(单词对),这些单词对将从“The quick brown fox jumps over the lazy dog.”中获取。这里采用了一个小的窗口大小为2.标为高亮蓝色的是我们的输入单词。

在这里插入图片描述

该神经网络会学习每一对单词出现频率的统计信息。例如,该神经网络获得的(““Soviet”, “Union”)训练样本数,远多于(“Soviet”, “Sasquatch”)。训练结束后,如果输入“苏联”一词作为输入,则输出““Union””或“Russia””的概率比“Sasquatch”的概率高得多。


模型细节

首先,要知道我们不可能直接将字符串输出给神经网络,所以需要对单词进行编码,以满足神经网络的输入要求。为了做这件事,我们可以使用训练集文档去构建一个单词自带你。比如,我们有10000个单词的字典。

我们将一个输入的单词表示成一个one-hot向量。这个向量有10000个元素(字典中的每个单词都是占一位,而形成一个向量),我们将单词出现的位置设置为1,其他位置设置为0。

神经网络的输出是一个单独的向量,依然有10000个元素,包含了对于字典中的每个单词,随机选中的单词是那个单词的概率。

下图是神经网络的架构
在这里插入图片描述
隐藏层没有激活函数,但输出层使用的是softmax。一会再说这个问题。

当在单词对上训练这个网络时,输入的是表示输入词的one-hot向量,训练输出也是表示输出词的one-hot向量,但当你使用输入词去评估训练完的网络的时候,输出向量实际上就是变成了一个概率分布(即一堆浮点值,而不是一个one-hot向量)。


隐藏层

下面讲到的例子,学习的是具有300个特征的单词向量。所以隐藏层将由一个10000行(每一行都针对的是词汇表中的每个单词)和300列(每隔隐藏的神经元的一列)的权重矩阵来表示。

300个特征是Google在Google新闻数据集上训练的发布模型中使用的特征。特征的数量是一个超参数,对于你自己的应用你需要有自己的调整。

如果你看这个权重矩阵的行,这些实际上是我们的词向量。

在这里插入图片描述
因此,所有在、这些的最终目标实际上是为了学习这个隐藏的层权重矩阵 - 当我们完成时,我们会被抛弃输出层

但是,让我们回头过来看看我们要训练的这个模型的定义。

这时候你可能会问自己 “one-hot”向量基本都是0,将会有什么影响?如果你使用110000的onehot向量和一个10000300的向量相乘。比方说:

在这里插入图片描述

这意味着这个模型的隐藏层实际上只是作为一个查找表来操作,隐藏层的输出只是输入单词的“word vector”。


输出层

然后1*300,“ants”这个单词向量被送到输出层。输出层是一个softmax分类器。要点是:每个输出的神经元(一个在字典中的单词向量)将会产生一个输出值,这个值在0~1之间,并且所有的输出值求和后是1.

具体而言,每隔输出神经元都有一个权向量,他与隐藏层的但词向量相乘,然后将该函数exp(x)应用于结果。最后,为了得到输出总和为1,我们将这个结果除以所有10000个输出节点的结果之和。

下面是计算单词“car”的输出神经元输出的图示。

在这里插入图片描述
请注意,**神经网络不知道输出此相对于输入词的偏移量。对于输入词之前,之后的单词,他不会学习不同的概率集合。**为了理解这个含义,假设在我们的训练语料库中,每个单词“York”的前面都有“New”这个词。也就意味着,至少在测试集中,New和York附近的概率将会是100%。然而,如果你取出York附近的10个单词,然后随机从他们中间取出一个,是New的可能性并不是100%;你可能会在其附近获得了一个其他单词。


直觉

如果两个不同的单词具有非常相似的“上下文”(也就是说,他们的周围可能出现哪些单词),那么我们的模型需要为这两个单词输出非常相似的结果。若果两个单词向量相似,那么网络将会为这两个单词输出相似的上下文。假设两个单词有相同的上下文,那么我们的网络将会学习相似的单词向量。

那么两个单词有相似的上下文是什么意思呢?可以认为是同义词,比方说如“intelligent” 和“smart”,将会有相似的上下文。或者,像“engine”和“transmission”这样相关的词语也可能具有相似的上下文。


引入的问题

注意到skip-gram神经网络包含一个巨大的权重矩阵。例如,300个特征,10000个单词字典,那么输出层和隐藏层都将有3M个权重。在一个大的数据集上进行训练是十分困难的,所以word2vec作者引入了一些调整使得训练变得可行。


优化

在上述的例子中,我们有300个组件的单词向量和10000个单词的词汇表。回想一下,神经网络有两个权重矩阵-隐藏层和输出层。这两个层都有一个权重矩阵,每个权重矩阵为300*10000=300万!

在大型的神经网络上运行梯度下降会很慢,更糟糕的是,你需要大量的训练数据调整许多权重,避免过度拟合。对数以百万计的驯良样本训练数百亿词,意味着几乎不可能实现。

Word2Vec的作者在他们的第二篇文章中解决了这些问题。主要有一下三个创新:

  1. 在他们的模型中将常见单词对或者短语视为一个“单词”
  2. 对频繁的词进行抽样以减少训练样例的数量
  3. 使用他们所谓的“负抽样”技术来修改优化目标,使得每个训练样本只更新模型权重的一小部分

值得注意的是,对频繁词进行二次抽样和应用负抽样不仅减少了训练过程的计算负担,而且也提高了他们产生的词向量的质量


词对和短语

这一部分内容和walk2friends论文没有太大关系。

作者指出,像“波士顿环球报”(一家报纸)这样的单词对,与“波士顿”和“环球”这两个单词的含义有很大不同。因此,无论在文本中出现在什么地方都将“波士顿环球报”都视为具有自己的单词向量表示的单个单词,是有道理的。

可以在他们发布的模型中看到结果,该模型已从Google新闻数据集中获得1000亿字的训练。模型中短语使词汇量增加到300万!

作者给出的工具每次只进行两个单词的组合,但是可以通过多次运行来获得更长的短语。比如:第一遍会选择“New_York”这个短语,然后再次运行会将“New_York_City”视为“New_York”和“City”的组合。

该工具会统计两个单词组合在文本中出现的次数,然后将这些计数用于方程中以确定将哪些单词组合成短语。这个方程设计的目的是将单词组合成短语,原因是单词组合出现相对于单个出现的的频率更高。他也关心由少见的单词组成的短语,避免一些常见的词组成短语,比如”and the”,”this is ”。


抽样频繁词语

在一个比较大的样本集合中,最频繁的词将会以数百万计的频率出现,比如:in,the,a。相对于罕见的词来讲这些单词携带的信息量很少。例如,skip-gram从观察”france”和”paris”组合出现收益程度,远高于从观察”france”和“the”组合出现收益的程度。可以理解,频繁词的向量表征在训练了数百万个例子后并不会发生十分显著的变化。


频繁词与抽样率的确定

word2vec C代码实现了一个计算词汇中给定单词的概率的公式。wi代表单词,z(wi)代表wi单词在语料库中所有单词出现次数的占比。如果”peanut”出现了1000次,语料库中有10亿,那么z(“peanut”)= 1E-6。

代码中还有一个参数叫做sample,它控制着抽样的比例,默认值是0.001.采样率如果过小,很多低频率的词可能无法保留下来。

P(wi)是保留该词的概率

在这里插入图片描述
在这里插入图片描述
没有一个单词应该是语料库的一个很大的比例,所以我们想要在X轴上看看非常小的值。

在这个函数里有一些有趣的点,使用默认的样本值0.001。

P(wi)=1.0 (将100%可能被保留)当z(wi)<= 0.0026。超过总单词0.26%的单词会被采样到。

P(wi)=0.5 有1/2的概率被采样到,z(wi) = 0.00746

P(wi)=0.033 3.3%机会被采样到,z(wi) = 1.0

也就是说,如果这个语料库完全是由wi这个词组成的,那当然是荒谬的。


负采样

训练一个神经网络意味着取一个训练样本并稍微调整所有神经元的权重,以便更准确地预测训练样本。换句话说,每个训练样本将调整神经网络的所有的权重。

正如上面所说,单词词汇的大小意味着skip-gram伸进网络拥有大量的权重,所有这些都将被我们数十亿训练样本中的每一个进行微更新!

负采样通过让每个训练样本只修改一小部分权重而不是全部权重来解决这个问题。

当在单词对(“fox”,“quick”)上训练网络时,记住网络的“标签”或“正缺输出”是one-hot向量。也就是说,对于对应于“quick”的输出神经元输出1,并且对于所有其他数千个输出神经元输出0。

在负抽样的情况下,我们将随机选择少量的“negative”(比如5)来更新权重。(在这种情况下,一个“negative”字是我们希望网络输出0的字)。我们还将更新我们的“正面”的词(在我们当前的例子中是“quick”)的权重。

该论文指出,选择5-20个单词适用于较小的数据集,并且对于大型数据集只能使用2-5个单词

回想一下,我们模型的输出层有300*10000的权重矩阵。所以我们只是更新我们的positive词(“quick”)的权重,加上我们要输出0的其他5词的权重。这总共有6个输出神经元,总共有18000个权重值,这只是3M的0.06%!

在隐藏层中,只有输入词的权重才会更新(不管是否使用负采样)

选择负样本

“负样本”(也就是我们要输出为0的五个字)使用“unigram distribution”来选择的。

本质上,选择一个词作为负样本的概率与其频率有关,越频繁的词越有可能被选作负样本

在word2vec的c代码中,可以找到该概率的方程。每隔单词被赋予一个等于它的频率(单词书)提升到3/4次方的权重。厕一个单词的概率只是它的权重除以所有单词的权重之和。

在这里插入图片描述
把频率提高到3/4的决定似乎是以来经验的。你可以看看函数的形状-只需要在google输入” plot y = x^(3/4) and y = x” 然后放大范围x = [0,1]。

实现方式:建立一个100M的元素(它们称为单字表)大阵列。他们用词汇表中的每个单词的索引多次填充这个表格,单词索引出现在表格中的次数由P(wi) * table_size给出。

然后,为了选出一个负样本,你仅仅只需要产生一个随机整数,整数范围是0-100M,然后使用当前索引在表中指定的word。由于高概率的单词在表中出现的次数多,你有更高的概率选择到这些。


Softmax

这里总结一下softmax函数的一些知识点

softmax函数

softmax函数公式如下:
在这里插入图片描述
其中,等式左边代表第L层第j个神经元的输出,右边分子代表第j个神经元的输入,分子代表第L层所有神经元的输入之和。

可以看出softmax实际上是logistic回归的一般形式,当类别数为2时,softmax退化为logistic回归

softmax、logistic和神经网络的关系:
在这里插入图片描述在这里插入图片描述
一般的神经网络有输入层,隐含层以及输出层构成,而上图中只有输入层和输出层,而没有隐含层。神经网络处理二分类时,输出层为一个节点,但处理K(K>2)分类问题时,数据节点为K个,这个logistic回归和softmax回归保持一致。值得注意的,在神经网络中的最后一层隐含层和输出层就可以看成是logistic回归或softmax回归模型,之前的层只是从原始输入数据从学习特征,然后把学习得到的特征交给logistic回归或softmax回归处理。

因此,可以把处理分类问题的神经网络分成两部分,特征学习和logistic回归或softmax回归。

softmax函数最明显的特点在于他把每个神经元的输入站当前层所有神经元输入之和的比值当作该神经元的输出神经元的输出值越大,该神经元对应的类别是真实类别的可能性越高。

softmax函数配合log似然函数训练人工神经网络

二次代价函数在训练ANN时可能会导致训练速度变慢的问题。那就是,初始的输出值离真实值越远,训练速度就越慢。这个问题可以通过采用交叉熵代价函数来解决。其实,这个问题也可以采用另外一种方法解决,那就是采用softmax激活函数,并采用log似然代价函数(log-likelihood cost function)来解决。

参考https://blog.csdn.net/u014313009/article/details/51045303

层级softmax

针对softmax的大幅度提高计算效率的版本就是层级softmax。优点是不需要评估神经网络中的W输出节点来获得概率分布,只需要估计log2(W)节点。

层级softmax使用二叉树代表输出层,使用W(单词矩阵)单词代表叶子。针对每隔节点,明确地指出了其子节点的概率。这些定义了将概率赋予单词的随机游走。

更确切地说,每个单词W可以通过树根开始的适当路径到达。使用n(w,j) = root 同时 n(w,L(W)) = w。另外,对于任何内部节点n,使用ch(n)作为任意的固定子节点。如果x是true
[[x]]为1,如果x为false,[[x]]为-1.然后,层级softmax定义输入单词w1和输出单词w2关系为:

在这里插入图片描述
其中在这里插入图片描述

在这里插入图片描述

上面等式可以证明是正确的。这意味着计算成本正比于L(),它平均不大于logW。不同于标准的softmax公式(标准的softmax公式会为每个单词分配两个表征和),层级softmax公式针对每个单词有一个表征,针对每隔二叉树内部的节点n有一个表征。

层级softmax使用的树的结构对性能有相当大的影响,Mnih和Hinton探索了构建树结构的一些方法,以及对训练时间和模型精度的影响。在我们的工作中,**我们使用二元霍夫曼树,因为它将短代码分配给频繁词汇可使得训练速度加快。**之前已经观察到,通过它们的频率将词组合在一起作为基于神经网络的语言模型的非常简单的加速技术是很好的。


参考:
[1]http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/
[2]https://blog.csdn.net/u014313009/article/details/51045303
[3]https://blog.csdn.net/hahaha_2017/article/details/81066673

猜你喜欢

转载自blog.csdn.net/qq_14809159/article/details/96851351
今日推荐