一、词向量
词向量的表示方法:
其基本想法是:
通过训练将某种语言中的每一个词映射成一个固定长度的短向量(当然这里的“短”是相对于 one-hot representation 的“长”而言的),将所有这些向量放在一起形成一个词向量空间,而每一向量则为该空间中的一个点,在这个空间上引入“距离”,则可以根据词之间的距离来判断它们之间的(词法、语义上的)相似性了。
为更好地理解上述思想,我们来举一个通俗的例子:假设在二维平面上分布有 N 个不同的点,给定其中的某个点,现在想在平面上找到与这个点最相近的一个点,我们是怎么做的呢?首先,建立一个直角坐标系,基于该坐标系,其上的每个点就唯一地对应一个坐标 (x,y);接着引入欧氏距离;最后分别计算这个词与其他 N-1 个词之间的距离,对应最小距离值的那个词便是我们要找的词了。
二、如何生成词向量
- 基于统计方法
- 共现矩阵
2.神经网络语言模型
1、skip-gram模型
一文详解 Word2vec 之 Skip-Gram 模型(结构篇)
一文详解 Word2vec 之 Skip-Gram 模型(训练篇)
2、cbow模型
CBOW(continue bag of words)连续词袋模型:根据上下文预测中心词
先从简单的上下文只有一个词讲起(one-word context):
网络结构如上图所示,一共有三层:输入层,隐藏层,输出层。
参数:
输入层:一个上下文的词,用one-hot进行编码, X = (V, 1), V表示总词数,隐藏层: h = (N, 1), N表示产出词向量的维度,输入层与隐藏层之间权重矩阵 W = (V, N)
输出层 y = (V, 1),one-hot编码的形式,表示预测出的中心词,隐藏层和输出层的权重矩阵 W' = (N, V), W叫做输入矩阵,用每一行(1,N)表示表示学习到的词向量,W'叫做输出矩阵,每一列(N,1)可以表示一个词向量,一般用输入矩阵作最后的的词向量矩阵。
前馈网络:
h' = WTX + b1, h = sigmoid(h'), u = W'Th + b2, 其中uj = v'jTh, v'jT是W'中的第j列,uj表示预测是第j个词的输出值,
$hat{y_{j}} = frac{exp(u_{j})}{sum_{i}^{V}exp{(u_{i})}} = frac{exp(v_{j}^{'T}h)}{sum_{i}^{V}exp{(v_{i}^{'T}h)}}$
损失函数:cross-entropy $CE(oldsymbol{y},oldsymbol{hat{y}}) = sum_{i}^{V}y_{i}log hat{y_{i}}$
参数更新:
根据损失函数, 利用梯度下降反向更新参数
主要用损失函数(CE)对 u, W', h, h', W 求导, 即$frac{partial CE}{partial oldsymbol{u}}$, $frac{partial CE}{partial oldsymbol{W^{'}}}$, $frac{partial CE}{partial oldsymbol{h}}$, $frac{partial CE}{partial oldsymbol{h^{'}}}$, $frac{partial CE}{partial oldsymbol{W}}$, $frac{partial CE}{partial oldsymbol{X}}$
(1)$frac{partial CE}{partial oldsymbol{u}}$ 损失函数对softmax进行求导,详见softmax求导
$frac{partial CE}{partial oldsymbol{u}} = oldsymbol{hat{y}} - oldsymbol{y}$, 这是对网络输出向量u进行求导结果,结果也是一个V维向量,每一个元素是该位置的预测结果与真实label的差值,如果是对某一个数uj结果为:$frac{partial CE}{partial u_{i}} = hat{y}_{i} - y_{i}$,这是一个数,在$hat{y}_{i}$表示第i个单词的预测值,$y_{i}$表示第i个单词的实际值
(2)$frac{partial CE}{partial oldsymbol{W^{'}}}$ 损失函数对第二个权重矩阵求导
我的计算应该是这样:$frac{partial CE}{partial oldsymbol{W^{'}}} = frac{partial CE}{partial oldsymbol{u}}frac{partial oldsymbol{u}}{partial oldsymbol{W^{'}}} = (oldsymbol{hat{y}} - oldsymbol{y})oldsymbol{h}$ 但是维度不对。 $(oldsymbol{hat{y}} - oldsymbol{y})$ = (V, 1), $oldsymbol{h}$ = (N, 1)
正确结果:
$frac{partial CE}{partial oldsymbol{W^{'}}} = frac{partial CE}{partial oldsymbol{u}}frac{partial oldsymbol{u}}{partial oldsymbol{W^{'}}} =oldsymbol{h}(oldsymbol{hat{y}} - oldsymbol{y})^{T}$, 这是标量对整个矩阵求导,结果维度为矩阵维度(N, V),
也可以写成对每个列向量$oldsymbol{v}_{j}^{'}$进行求导,$oldsymbol{v}_{j}^{'}$是第二个权重矩阵$oldsymbol{W^{'}}$的第j列,因为${u}_{j}=oldsymbol{v}_{j}^{'T}oldsymbol{h}$,$frac{partial CE}{partial oldsymbol{oldsymbol{v}_{j}^{'}}} = frac{partial CE}{partial {u_{j}}}frac{partial {u_{j}}}{partial oldsymbol{{v}_{j}^{'}}} = left ( hat{y_{j}} - y_{j} ight )mathbf{h}$
还可以写成对矩阵每个元素$oldsymbol{W}_{ij}^{'}$进行求导: $frac{partial CE}{partial {oldsymbol{W}_{ij}^{'}}} = frac{partial CE}{partial {u_{j}}} frac{partial u_{j}}{partial {oldsymbol{W}_{ij}^{'}}}=left ( hat{y}_{j} - y_{j} ight )h_{i}$
(3)$frac{partial CE}{partial oldsymbol{h}}$ 损失函数对隐藏层输出h求导
同上,跟我的求导方式不一致,我认为的:$frac{partial CE}{partial oldsymbol{h}} = frac{partial CE}{partial oldsymbol{u}}frac{partial oldsymbol{u}}{partial oldsymbol{h}} =(oldsymbol{hat{y}} - oldsymbol{y})mathbf{W}^{'T}$,维度还是不对
正确结果:直接用标量对向量h求导:$frac{partial CE}{partial oldsymbol{h}} = frac{partial CE}{partial oldsymbol{u}}frac{partial oldsymbol{u}}{partial oldsymbol{h}} =mathbf{W}^{'}(oldsymbol{hat{y}} - oldsymbol{y})$,用标量对h中每一个元素hi求导: $ frac{partial CE}{partial h_{i}} = sum_{j=1}^{V}frac{partial CE}{partial u_{j}}frac{partial u_{j}}{partial h_{i}} = sum_{j=1}^{V}left ( hat{y}_{j} - y_{j} ight )mathbf{W}_{ij}^{'}$
(4)$frac{partial CE}{partial oldsymbol{h^{'}}}$ 损失函数对隐藏层每加sigmoid前的向量求导
$frac{partial CE}{partial oldsymbol{h^{'}}} = frac{partial CE}{partial oldsymbol{h}}frac{partial oldsymbol{h}}{partial oldsymbol{h^{'}}} =mathbf{W}^{'}(oldsymbol{hat{y}} - oldsymbol{y})circ sigma ^{'}left ( oldsymbol{h}^{'} ight )$
$frac{partial CE}{partial h^{'}_{i}} = frac{partial CE}{partial h_{i}}frac{partial h_{i}}{partial h^{'}_{i}} =sigma ^{'}left ( h^{'}_{i} ight ) sum_{j=1}^{V}left ( hat{y}_{j} - y_{j} ight )mathbf{W}_{ij}^{'}$
(5)$frac{partial CE}{partial oldsymbol{W}}$ 损失函数对第一个权重矩阵求导
同上,顺序还是不一致
正确结果:
直接用标量对矩阵W求导 $frac{partial CE}{partial oldsymbol{W}} = frac{partial CE}{partial oldsymbol{h^{'}}}frac{partial oldsymbol{h^{'}}}{partial oldsymbol{W}} = Xfrac{partial CE}{partial oldsymbol{h^{'}}}$
用标量对矩阵W中每一个元素求导:$frac{partial CE}{partial {oldsymbol{W}_{ij}}} = frac{partial CE}{partial {h_{j}^{'}}} frac{partial h_{j}^{'}}{partial {oldsymbol{W}_{ij}}}=frac{partial CE}{partial {h_{j}^{'}}}X_{i}$
多个上下文词
如图选取C个上下文词,CBOW模型采用取平均的方法,变成了和一个上下文词一样的形式
关于负采样
由$hat{y_{j}} = frac{exp(u_{j})}{sum_{i}^{V}exp{(u_{i})}} = frac{exp(v_{j}^{'T}h)}{sum_{i}^{V}exp{(v_{i}^{'T}h)}}$知计算目标词的概率式子中分母要遍历所有的词表,非常耗费时间,所以有一种训练技巧,即随机负采样,随机采样K个不与目标词相同的词,负采样的损失函数 $J_{neg-sampling}left ( j,oldsymbol{h},oldsymbol{U} ight ) = -log sigma left ( v_{j}^{T}mathbf{h} ight )-sum_{k=1}^{K}log sigma left ( -v_{k}^{T}mathbf{h} ight ) $ ,其中$ sigmaleft ( -x ight ) = 1 - sigma left (x ight ) $, 解释不了具体的意思,感觉很对,为什么要用sigmoid, 除以负采样的意义是什么?
负采样求导,主要是 $frac{partial J}{partial v_{j}^{T}}, frac{partial J}{partialoldsymbol{ h}}, frac{partial J}{partial v_{k}^{T}}, $
$frac{partial J}{partial mathbf{h}} = left ( sigma -1 ight )v_{j} + sum_{k=1}^{K}(1-sigma)v_{k}$
$frac{partial J}{partial v_{j}} = left ( sigma -1 ight )oldsymbol{h}$
$ frac{partial J}{partial v_{k}} = -left (sigma left ( -v_{k}^{T}mathbf{h} ight ) - 1 ight )oldsymbol{h}$
关于hierarchical softmax
构造一个V个叶节点的哈夫曼树,每个叶节点都是一个词表的单词,从root到叶节点的路径,就等于这个节点的概率,原来softmax的时间复杂的是O(n),现在是lg(n)
3、skip-gram与cbow的对比
cbow是以周围词作为输入,中心词作为目标的网络,所以假设一篇语料中有V个单词,那么cbow将会以每一个单词作为中心词进行训练,因此会有V次
skip-gram是以中心词作为输入,周围词作为目标的网络,那么对于一篇语料来说,每一个词都会作为中心词,每个中心词周围大小选择K个,那么将会进行KV次
直观上来看,cbow训练次数要比skip-gram少,也即精确率不如skip-gram,但是效率高,速度快。
遇到生僻词,cbow效果会大大降低
3.GLOVE模型