本系列为吴恩达老师《深度学习专项课程(Deep Learning Specialization)》学习与总结整理所得,对应的课程视频可以在这里查看。
在ShowMeAI前一篇文章 序列模型与RNN网络 中我们对以下内容进行了介绍:
本篇介绍自然语言处理,文本表示与词嵌入的相关知识。
ShowMeAI在上一篇内容 序列模型与RNN网络 里介绍了基于词表(例如10000大小的vocabulary)映射,使用one-hot的方式对每个单词进行编码。例如单词Rome、Paris、Italy、France分别出现在词汇表的第1、2、3、4的位置,则表示如下:
这中one-hot稀疏单词表征的最大缺点就是每个单词都是独立的、正交的,无法知道不同单词之间的语义相似与关联度。例如「橙子」和「橘子」都是水果,词性相近,但是单从one-hot编码上来看,内积为零,无法知道二者的相似性。在自然语言处理的很多任务里,我们更希望能更准确地对词进行向量化表征,覆盖到其语义相似度和分布特性。
换用特征化表示方法能够解决这一问题。我们可以通过用语义特征作为维度来表示一个词,因此语义相近的词,其词向量也相近。语义特征表征的例子如下图所示:
词语义特征表征的长度可以基于场景做不同设定,通常越长能包含的信息越多。假定上图的词特征向量长度设定为300。则词汇表中的每个单词都可以使用对应的 300 × 1 300 \times 1 300×1的向量来表示,该向量的每个元素表示该单词对应的某个特征值。
这种特征表征的优点是根据特征向量能清晰知道不同单词之间的相似程度,例如「橙子」和「橘子」之间的相似度较高,很可能属于同一类别。这种单词「类别」化的方式,大大提高了有限词汇量的泛化能力。这种特征化单词的操作被称为Word Embeddings,即单词嵌入。
在我们当前的这个例子中,特征向量的每个特征元素含义是具体的,对应到实际特征,例如性别、年龄等。而在实际自然语言处理应用中,特征向量很多特征元素并不一定对应到有物理意义的特征,是比较抽象的。但这并不影响对每个单词进行向量化的有效表征,而且不同单词之间的相似性和分布特性也可以由向量表征计算获得。
如果我们使用降维算法(详细可以阅读ShowMeAI文章 图解机器学习 | 降维算法详解)对得到的词嵌入向量处理,并在2维平面里进行可视化,可以直观看到词之间的分布和相似度,如下图所示
相关论文:van der Maaten and Hinton., 2008. Visualizing Data using t-SNE
一个更官方一点的定义是:词嵌入(Word Embedding)是NLP中语言模型与表征学习技术的统称,它是指把一个维数为所有词的数量的高维空间(one-hot形式表示的词)「嵌入」到一个维数低得多的连续向量空间中,每个单词或词组被映射为实数域上的向量。
在ShowMeAI上一篇文章 序列模型与RNN网络 介绍的命名实体识别例子中,每个单词采用的是one-hot编码。如下图所示,因为「菜农」是份职业,可以判断知道「王刚」是一个人名。
如果替换one-hot为特征化表示方法对每个字进行编码,再构建RNN模型。对于一个新的句子:
因为两句话中,「菜」与「果」的特征向量很接近,很容易类比得出「张三」也是一个人名。这就是特征化表示方法的优点之一。
通过上例,我们知道特征化表示方法有减少训练样本数目的优点,前提是对海量单词建立特征向量表述(word embedding)。这样,即使是训练样本中没有的单词,也可以根据word embedding的结果得到与其词性相近的单词,从而得到与该单词相近的结果,有效减少了训练样本的数量。
特征化表示方法的特性使得很多NLP任务能方便地进行迁移学习,方法步骤是:
吴恩达老师建议仅当训练样本足够大的时候,再进行上述第三步。
大家可能会注意到,这里的词嵌入,和ShowMeAI前面文章 CNN应用:人脸识别和神经风格转换 里提到的人脸特征编码有很多相似性。人脸图片经过Siamese网络,得到其特征向量,这点跟词嵌入是类似的。
不同的地方是Siamese网络输入的人脸图片可以是数据库之外的;而词嵌入一般都是已建立的词汇库中的单词,非词汇库单词统一用< UNK >表示。
词嵌入的一个应用场景是类比推理。
举个例子,我们用 e w o r d e_{word} eword表示单词word的词嵌入向量,则给定对应关系「男性(Man)」对「女性(Woman)」,想要类比出「国王(King)」对应的词汇。
则可以有 e m a n − e w o m a n ≈ e k i n g − e ? e_{man} - e_{woman} \approx e_{king} - e_? eman−ewoman≈eking−e?,之后的目标就是找到词向量 w w w,来找到使相似度 s i m ( e w , e k i n g − e m a n + e w o m a n ) sim(e_w, e_{king} - e_{man} + e_{woman}) sim(ew,eking−eman+ewoman)最大。
我们最常用到的相似度计算函数是余弦相似度(cosine similarity)(详细参考ShowMeAI文章 图解AI数学基础 | 线性代数与矩阵论 中距离与相似度度量部分内容)。余弦相似度计算公式为:
s i m ( u , v ) = u T v ∣ ∣ u ∣ ∣ 2 ∣ ∣ v ∣ ∣ 2 sim(u, v) = \frac{u^T v}{|| u ||_2 || v ||_2} sim(u,v)=∣∣u∣∣2∣∣v∣∣2uTv
相关论文:Mikolov et. al., 2013, Linguistic regularities in continuous space word representations
假设构建好的词汇库vocabulary包含了10000个单词,每个词包含的特征维度为300,那么表征所有词的嵌入矩阵(embedding matrix)维度为 300 × 10000 300 \times 10000 300×10000,用E来表示。词 w w w的one-hot向量表示为 O w O_w Ow(我们知道其维度为 10000 × 1 10000 \times 1 10000×1),则该词对应的嵌入向量(embedding vector)可以如下计算得到:
e w = E ⋅ O w e_w=E\cdot O_w ew=E⋅Ow
所以,一旦有了嵌入矩阵embedding matrix (具体的计算方法在后面会提到),就能计算得到所有单词的embedding vector 。不过真的做矩阵乘积运算的效率并不高,矩阵维度很大,且大部分元素为零,实际上述矩阵运算等价于直接从中选取第w列作为词嵌入向量。
神经概率语言模型(Neural Probabilistic Language Model)构建了一个能够通过上下文来预测未知词的神经网络。嵌入矩阵 E E E 可以通过构建神经概率语言模型(Neural Probabilistic Language Model),运用梯度下降优化得到。举个简单的例子,输入样本是下面这句话:
I want a glass of orange (juice).
通过这句话的前6个词,预测最后的词「juice」。嵌入矩阵 E E E未知待求,每个单词可用嵌入向量 e w e_w ew表示。构建的神经概率模型结构如下图所示:
神经网络输入层包含6个词嵌入向量,每个向量的维度是300,则输入层总共是1800维输入。Softmax层有10000个维输出(对应词表里的10000个词)。正确的输出label是「juice」。
网络中 E E E, W [ 1 ] W^{[1]} W[1], b [ 1 ] b^{[1]} b[1], W [ 2 ] W^{[2]} W[2], b [ 2 ] b^{[2]} b[2]为可学习的参数。在足量的语料样本下,使用梯度下降,迭代优化,最终可以得到嵌入矩阵 E E E。
这个任务下构建的神经网络,能有效保证具有相似属性单词的嵌入向量embedding vector相近。
为了简化和固定神经网络的输入,我们可以选择只用前4个单词作为输入预测下一个词,对应到本例中,是使用「a glass of orange」4个单词作为输入。(当然,4是超参数,根据数据量和计算资源不同,可以调整。)
一般地,我们把输入叫做上下文context,输出叫做target。对应上例:
context: a glass of orange
target: juice
关于context的选择有多种方法:
上述不管哪一个方法,在数据量充分的情况下都能得到出较准确的嵌入矩阵embedding matrix E E E。
相关论文:Bengio et. al., 2003, A neural probabilistic language model
在很长一段时间里,大家使用多的是Word2Vec这个模型,它是一种简单高效的词嵌入学习方法,包括 2 种模型:
这两种方法训练得到的隐层参数即是对应的词嵌入。
这部分也推荐大家学习ShowMeAI整理的斯坦福cs224n课程课件注解与笔记:
在模型的训练阶段,又包含**负采样(Negative Sampling)和分级的Softmax(Hierarchical Softmax)**两种训练技巧方法。
相关论文:Mikolov et. al., 2013. Efficient estimation of word representations in vector space.
下面我们来展开讲解一下Skip-gram和CBOW模型:
Skip-gram是一个使用中心词去预测context里周边词的模型,结构如图所示,从左到右是:
① 输入的中心词One-hot向量
② 输入乘以center word的矩阵 W W W,得到词向量
③ 词向量乘以另一个context word的矩阵 W ′ W\prime W′得到对每个词语的「相似度」
④ 对相似度得分取Softmax得到概率,与答案对比计算损失。
设中心词为 c c c,该词的一定词距内选取目标上下文 t t t,则根据Softmax单元得到输出条件概率:
p ( t ∣ c ) = e x p ( θ t T e c ) ∑ j = 1 m e x p ( θ j T e c ) p(t|c) = \frac{exp(\theta_t^T e_c)}{\sum^m_{j=1}exp(\theta_j^T e_c)} p(t∣c)=∑j=1mexp(θjTec)exp(θtTec)
公式中 θ t \theta_t θt是一个与输出 t t t有关的参数。损失函数仍选用交叉熵:
L ( y ^ , y ) = − ∑ i = 1 m y i l o g y ^ i L(\hat{y}, y) = -\sum^m_{i=1}y_ilog\hat{y}_i L(y^,y)=−i=1∑myilogy^i
这个Softmax分类中,每次计算条件概率时,需要对词典中所有词做求和操作,因为词库很大,所以总的计算量很大。优化方案之一是使用一个层次化 Softmax 分类器(Hierarchical Softmax Classifier),形如二叉树。在实践中,一般对词表根据频次构建霍夫曼树(Huffman Tree),常用词在顶部。
CBOW模型的工作方式与Skip-gram相反,通过上下文词来预测中间的词。
基本步骤原理如下:
吴恩达老师没有深入去讲CBOW。想要更深入了解的话,也推荐大家学习ShowMeAI整理的斯坦福cs224n课程课件注解与笔记:
为了解决词表大的情况下平铺开的Softmax计算量大的问题,Word2Vec的作者提出了负例采样(Negative Sampling)方法。
负例采样的做法是采样选取context词,和target词构建样本,一般包含一个正样本和k个负样本。
例「orange」为context word,「juice」为target word,「orange juice」是正确的组合,相应的target label为1。
保持「orange」为context word不变,target word随机选择「king」、「book」、「the」或者「of」等。这些都不是合适的组合,相应的target label为0。
一般地,固定某个context word对应的负样本个数k一般遵循:
在负例采样中,调整为多个Sigmoid输出上下文-目标词 ( c , t ) (c,t) (c,t)为正样本的概率:
P ( y = 1 ∣ c , t ) = σ ( θ t T e c ) P(y=1 \mid c, t) = \sigma(\theta_t^Te_c) P(y=1∣c,t)=σ(θtTec)
公式其中, θ t \theta_t θt、 e c e_c ec分别代表目标词和上下文的词向量。
对比原始形态,每次要更新 n n n维的多分类Softmax单元( n n n为词典中词的数量)。使用负例采样之后,每次只需要更新 k + 1 k+1 k+1维的二分类Sigmoid单元,计算量大大降低。
关于计算选择某个词作为负样本的概率,可以使用随机选择。但作者给出了如下效果更好的公式:
p ( w i ) = f ( w i ) 3 4 ∑ j = 0 m f ( w j ) 3 4 p(w_i) = \frac{f(w_i)^{\frac{3}{4}}}{\sum^m_{j=0}f(w_j)^{\frac{3}{4}}} p(wi)=∑j=0mf(wj)43f(wi)43
公式中, f ( w i ) f(w_i) f(wi)代表语料库中单词 w i w_i wi出现的频率。上述公式更加平滑,能够增加低频词的选取可能。
相关论文:Mikolov et. al., 2013. Distributed representation of words and phrases and their compositionality
GloVe(Global Vectors)是另一种流行的词嵌入算法。Glove模型基于语料库统计了词的共现矩阵 X X X, X X X中的元素 X i j X_{ij} Xij表示单词 i i i和单词 j j j「为上下文-目标词」的次数。之后,用梯度下降法最小化损失函数。
共现矩阵的一个例子如下(此时左右窗长都为1):
语料库的3句话如下:
like deep learning.
I like NLP.
I enjoy flying.
损失函数公式定义为:
J = ∑ i = 1 N ∑ j = 1 N f ( X i j ) ( θ i t e j + b i + b j − l o g ( X i j ) ) 2 J = \sum^N_{i=1}\sum^N_{j=1}f(X_{ij})(\theta^t_ie_j + b_i + b_j - log(X_{ij}))^2 J=i=1∑Nj=1∑Nf(Xij)(θitej+bi+bj−log(Xij))2
公式中, θ i \theta_i θi、 e j e_j ej是单词 i i i和单词 j j j的词向量; b i b_i bi、 b j b_j bj; f ( ) f() f()是一个用来避免 X i j = 0 X_{ij}=0 Xij=0时 l o g ( X i j ) log(X_{ij}) log(Xij)为负无穷大、并在其他情况下调整权重的函数。 X i j = 0 X_{ij}=0 Xij=0时, f ( X i j ) = 0 f(X_{ij}) = 0 f(Xij)=0。
「为上下文-目标词」可以代表两个词出现在同一个窗口。在这种情况下, θ i \theta_i θi和 e j e_j ej是完全对称的。因此,在训练时可以一致地初始化二者,使用梯度下降法处理完以后取平均值作为二者共同的值。
相关论文:Pennington st. al., 2014. Glove: Global Vectors for Word Representation
最后,注意一点,使用word2vec或者GloVe等词嵌入算法学到的词向量,并不能对其中每个维度作明确的物理含义解析,但可以表征词语的分布和相近度,对下游任务也是有帮助的。
情感分类是指分析一段文本对某个对象的情感是正面的还是负面的,实际应用包括舆情分析、民意调查、产品意见调查等等。
情感分类的问题之一是标记好的训练数据不足。但是有了词嵌入得到的词向量,中等规模的标记训练数据也能构建出一个效果不错的情感分类器。
如上图所示,用词嵌入方法获得嵌入矩阵 E E E后,计算出句中每个单词的词向量并取平均值,输入一个Softmax单元,输出预测结果。
这种方法的优点是适用于任何长度的文本;缺点是没有考虑词的顺序,对于包含了多个正面评价词的负面评价,很容易预测到错误结果。
使用RNN能够实现一个效果更好的情感分类器:
上图中的RNN模型是典型的「多对一」模型,因为RNN考虑单词出现的次序,能更有效地进行真实情感的判断。
再配合上使用词嵌入,能够有效提高模型的泛化能力,即使训练样本不多,也能保证模型有不错的性能。
语料库中可能存在性别歧视、种族歧视、性取向歧视等非预期形式偏见(Bias),这种偏见会直接反映到通过词嵌入获得的词向量。如下面的例子(本身不恰当,但是可能词向量表现出这层关系):
上例中,明显第2和第3句话存在性别偏见,因为Woman和Mother也可以是Computer programmer和Doctor。
下面以性别偏见为例,介绍下消除词嵌入word embeddings偏见的方法。
方法是对所有性别对立的单词求差值,再平均。公式如下:
b i a s d i r e c t i o n = 1 N ( ( e h e − e s h e ) + ( e m a l e − e f e m a l e ) + ⋯ ) bias\ direction=\frac1N ((e_{he}-e_{she})+(e_{male}-e_{female})+\cdots) bias direction=N1((ehe−eshe)+(emale−efemale)+⋯)
下图展示了bias direction和non-bias direction。
将需要消除性别偏见的单词投影到non-bias direction上去,消除bias维度。例如babysitter,doctor等。
让性别对立单词与上面的中立词距离相等,具有同样的相似度。例如让grandmother和grandfather与babysitter的距离同一化。
吴恩达老师指出,掌握哪些单词需要中立化非常重要。一般来说,大部分英文单词,例如职业、身份等都需要中立化,消除词嵌入中「性别」这一维度的影响。
相关论文:Bolukbasi et. al., 2016. Man is to computer programmer as woman is to homemaker? Debiasing word embeddings