Day 2
神经网络模型
基本框架
- 第一层:输入层。例如输入几个词:我 今天 下午,并初始化化为向量: v(Context(w)1), v(Context(w)2), v(Context(w)3)。训练样本:(Context(w),w)包括前n-1个词分别的向量,假定每个词向量大小为m。
- 第二层:投影层。大小为**(n-1)*m**的首尾拼接在一起的大向量。 将w1,w2,w3的向量拼接在一起形成W。在这里,word2vec的神经网络训练除了要训练各层之间的参数,同时还要对输入层进行迭代优化,以得到适合的词向量。
- 第三层:隐藏层
- 第四层:输出层。yw = (yw1,yw2,…,ywN)^T:我 今天 下午 第N个词,即预测第N个词出现的概率,作为label。
神经网络的优势
- 对于同义的词汇,比如网咖和网吧,如果网吧出现的次数多,那么通过N-gram模型,“我去网卡”的出现概率是大于“我去网吧”的,但是神经网络模型计算出来,两者的向量空间是类似的,因此概率是近似相等的。
- 就比如,猫在院子里跑与狗在院子里跑,神经网络模型会考虑都是动物在院子里跑,会将两者出现的次数合并,计算作为两者共同的概率。
- 因此,神经网络可以得到两者之间近似的含义,且符合真实的逻辑和规律。
实现word2vec模型
Hierarchical Softmax(分层)
-
CBOW (Continuous Bag-of-Words)
1.一种根据上下文的词语预测当前词语的出现概率的模型。使用似然函数求解:给定上下文,求解使概率最大的w是什么,概率值越大越好。
2.哈夫曼树
哈弗曼树是一种带权路径长度最短的二叉树,也称为最有二叉树。
图a:WPL = 5 * 2 + 7 * 2 +2 * 2 +13 * 2 = 54
图b:WPL = 13 * 1 + 7 * 2 +2 * 3 +5 * 3 = 48
可以看出b的带权路径长度最短。所以b是哈弗曼树为什么会用到哈弗曼树呢?
在我们日常生活中,其实最常用的词汇就那么几百个,出现的概率也越高,所以,我们可以用权数来代表词频。如下图,我出现的频率可能最高,是次之,的再次之。这就是分层思想。
如何创建一棵哈弗曼树?
a.初始森林
b.一次合并:将权重最小的两个(词频最小的两个词)放到最下面
c.二次合并
d.哈弗曼树哈弗曼树还有什么作用?
如最右侧的编码树,哈夫曼树可以给每一个词汇编码,即哈夫曼编码,假设左0右1,比如B可以表示为1-0
3.Logistic回归
为什么要用到Logistic回归呢?
因为在哈弗曼树中,从一个节点出发,往左走还是往右走需要进行判断,所以我们可以用二分类算法来进行计算和判断。
通过h(x)得到[0,1]之间的一个概率值。Softmax实际上是一个多分类逻辑回归,是将很多个逻辑回归组合在一起。此处注意g(x)的导数求解,后面的推导会用到这个结果。
4.CBOW模型详解
输入层:是上下文的词向量。在训练CBOW模型时,词向量只是模型的一个参数,是副产品。开始可以是随机值,随着训练进行不断被更新。我们需要更新还有层与层之间的权重参数。
投影层:对输入层求和,即向量加法。
输出层:输出最可能的w。语料库中词汇量是固定的|C|个,上述过程可以堪称是多分类问题。给定特征,从|C|个分类中挑一个。
上图是一些符号的含义。
假设正例往右,负例往左。正例概率>0.5,对应的负例概率就<0.5,由此可以判断从根节点往下的走向。图中红色粗线所示,先左再右再右再左,最终到达足球这个词。第一次负例,第二次正例,第三次正例,第四次负例。最后结果为足球的概率为前四次概率的乘积。
求解参数θ和x:将每一次的正负例概率判断公式代入到目标函数—似然函数中。我们使用对数似然可以将累乘转化为累加,简化计算,但并不影响最后的结论。
我们的目标是是概率最大,因此是一种梯度上升的求解方法。找极值的话,思路便是求导。用当前的似然函数对θ进行求导。此时用到了之前证明的sigmoid函数的倒数结果,log(σ(x))的导数要除以σ(x)本身,所以在对数下,求导后只剩下了(1-σ(x)),后面理解起来就容易多了。
同理,对x求导,结果是一致的,词向量越准确,越适合,上下文预测的效果也就越好,所以x也需要更新。此处的xω是指投影层的词向量,即输入层的向量和。
另外需要注意的是,我们目标是概率值最大,即梯度上升的方法,所以参数更新时:原来参数+η * (上述结果)
迭代就可以开始了!
一个小问题
xω是上下文词向量的和,不是单个词的词向量,如何将这个更新量应用到每个词的词向量上去呢。word2vec采取的是直接将 xω的更新量整个应用到每个单词的词向量上去。
好处是:更新朝着一个整体的趋势进行,词分布的空间趋于类似,符合上下文的逻辑。
Negative Sampling(负采样)(对分层的优化)
对于哈夫曼树,如果语料库非常大,计算复杂度还是非常高的,基于这个问题,有另一种解决方案,即负采样。
关于向左走还是向右走的问题=是或不是的问题。比如我今天下午打(),我们希望最终预测是篮球,那就是,否则就不是。但是负样本那么多,我们如何选取的。
对于给定的正样本,我们希望(Context(w),w) 最大化正确的可能性。
解决思路
任何采样算法都应该保证频次越高的样本越容易被采样处理。基本思路就是对于长度为1的线段,根据词频将其公平地分配给每个词语。
接下来我们生成一个0-1之间的随机数,看落到哪个区间,就能采样到该区间对应的单词,是公平的的方式。
g(w) = 正确的概率 * (1-错误的概率)
之后推导与上文类似。
参数更新也与上文类似。