概述
Lecture 3. More Word Vectors
Lecture 3 这节课首先复习了上节课学到的word2vec模型,以及使用梯度下降和SGD优化参数,然后介绍了词向量的内部评测和外部评测,参数对于类比评测任务的影响,处理词义的模糊性和窗口分类等。
文章目录
- Lecture 3. More Word Vectors
- 梯度的更新
- 词向量的评测
- 内部评测 vs 外部评测
- 内部评测示例:词向量的类比
- 内部评测调整示例
- 内部评测示例:相关性评测
- 扩展阅读:处理词的模糊性
- 外部任务的训练
- 用公式表示问题
- 词向量的重训练
- Softmax分类和正则化
- 窗口分类
- 非线性分类
梯度的更新
回顾一下上节课提到的word2vec的损失函数:
J ( θ ) = 1 T ∑ t = 1 T ∑ − c ≤ j ≤ c , j ≠ 0 l o g p ( w t + j ∣ w t ) J(theta) = frac{1}{T} sum_{t=1}^Tsum_{-cleq{j}leq{c},jneq0}logp(w_{t+j}|w_t) J(θ)=T1t=1∑T−c≤j≤c,j̸=0∑logp(wt+j∣wt)
概率P定义为:
p ( w O ∣ w I ) = e x p ( u w O T v w I ) ∑ w = 1 W e x p ( u w T v w I ) p(w_O|w_I) = frac{exp(u_{w_O}^Tv_{w_I})}{sum_{w=1}^{W}exp(u_w^Tv_{w_I})} p(wO∣wI)=∑w=1Wexp(uwTvwI)exp(uwOTvwI)
其中 u u u 和 v v v 表示词的输入和输出向量,我们在上节课也推导了 v w I v_{w_I} vwI 的梯度,同样也需要对 u u u 推导。
通常来说,对于每个上下文窗口我们要计算所有用到的参数的更新,例如“I like learning”这句话,当窗口大小为1的时候,第一个窗口我们需要计算参数输入向量 v l i k e v_{like} vlike ,输出向量 u I u_{I} uI 和 u l e a r n i n g u_{learning} ulearning 参数的梯度。
对于句首和句尾词的处理,通常在句子首尾加上<s>字符串,例如"<s> I like learning <s>"。所以我们用google的word2vec工具训练出来的词向量,第一个总是<s>。
我们通常用 θ theta θ 代表模型中的所有参数的集合,在维度为 d d d 的词向量中,词典为 V V V ,那么 θ theta θ 应该为:
θ = [ v a a r d v a r k v a ⋮ v z e b r a u a a r d v a r k ⋮ u z e b r a ] ∈ R 2 d V theta = begin{bmatrix}v_{aardvark}\v_a\vdots\v_{zebra}\u_{aardvark}\vdots\u_{zebra}end{bmatrix} in R^{2dV} θ=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡vaardvarkva⋮vzebrauaardvark⋮uzebra⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤∈R2dV
在整个训练数据上计算化损失函数 J ( θ ) J(theta) J(θ) 的最小化,需要对所有的窗口计算以下梯度:
θ j n e w = θ j o l d − α α α θ j o l d J ( θ ) theta_j^{new} = theta_j^{old} - alphafrac{alpha}{alphatheta_j^{old}}J(theta) θjnew=θjold−ααθjoldαJ(θ)
θ j n e w = θ j o l d − α ∇ θ J ( θ ) theta_j^{new} = theta_j^{old} - alphanabla_{theta}J(theta) θjnew=θjold−α∇θJ(θ)
实现的代码为:
while True:
theta_grad = evaluate_gradient(J, corpus, theta)
theta = theta - alpha * theta_grad
这就是梯度下降优化方法。然而通常训练集会很大,也许有4亿个单词,更新一次就需要耗费很长的时间训练,所有一般使用**Stochastic Gradient Descent(SGD)**随机梯度下降来计算参数,核心就是每个窗口 t t t 后更新参数,公式就变为:
θ n e w = θ o l d = α ∇ θ J t ( θ ) theta^{new} = theta^{old} = alphanabla_{theta}J_t(theta) θnew=θold=α∇θJt(θ)
代码更改为:
while True:
window = sample_window(corpus)
theta_grad = evaluate_gradient(J, window, theta)
theta = theta - alpha * theta_grad
在计算每个窗口时,最多有 2 c − 1 2c-1 2c−1 个词,所以梯度矩阵是很稀疏的,我们只需要更新出现的词的向量。有两种方法:
- 对每个词向量做hash
- 只更新输入词向量矩阵和输出词向量矩阵的指定的列(即词在的那列)
重要的一点,如果我们有百万级别的词向量要计算,最好使用分布式方式。
词向量的评测
目前为止,我们已经讨论了使用word2vec、GloVe方法来训练得到词在语义空间的潜在语义向量表达,下面我们就来讨论下如何评价词向量的质量。
评价词向量的方法一般分为两种,内部任务评测和外部任务评测。
内部评测 vs 外部评测
Intrinsic Evaluation内部任务评测通常是指定内部子任务,例如词向量的类比任务。
内部评测的特点有:
- 在指定的内部的任务上做评测
- 评测计算速度快
- 能够辅助我们了解子系统(辅助我们了解word2vec的原理)
- 在评测效果上需要与现实系统正相关(即如果内部任务评测效果好,应该推进现实系统的表现)
我们以要构建问答系统为例,训练该系统有这么几个步骤:
- 输入表达问题的词。
- 将它们转化为向量。
- 将词向量作为输入到复杂的问答系统中。
- 系统的输出词向量映射到真实的词。
- 结果组合为答案。
在构建这样一个完美的问答系统过程中,我们首先需要最优的词向量表达,然后将它们应用在下游系统中。在实践过程中,需要调非常多的参数,理想的做法是每次调整word2vec的参数后都要重新训练下游问答系统来查看调参的结果,但是复杂的下游系统可能有很多层和百万级别的参数,这就导致这种理想的做法不现实。这种情况下,我们就需要有一个内部任务来代替。
外部评测就是我们上面说的用下游子系统来评测,特点有:
- 在真实任务上做评测
- 评测计算速度慢
- 不清楚问题在于哪个子系统,或者子系统之间的交互上
- 如果替换子系统能够提高效果,那么这种替换通常是好的
内部评测示例:词向量的类比
这小节有很多示例图片,我就不截图了,可以打开Lecture Notes 2.pdf 查看
词向量的类比形式就是 a : b : : c : ?
内部任务评测时,就是找到最大化余弦距离的词,数学公式表达为:
d = a r g m a x i ( x b − x a + x c ) T x i ∣ ∣ x b − x a + x c ∣ ∣ d = argmax_i{frac{(x_b - x_a + x_c )^Tx_i}{||x_b - x_a + x_c||}} d=argmaxi∣∣xb−xa+xc∣∣(xb−xa+xc)Txi
使用类比评测时,还需要注意训练集的不同方面。例如,在计算美国各州包含的城市时,不同城市具有相同的名字。在city-captial类比中,同一个国家在不同时期首都可能会变化。
上述两个例子都是语义方面的类比。在语法的类比上,可以有“形容词-最高级”、“动词-动词过去式”等形式。
内部评测调整示例
同样有很多评测结果的图片,不截图
词向量类比评测任务中,可以调节的参数:
-
词向量维度
-
训练集大小
-
训练集数据源/类型
-
上下文窗口大小
-
上下文窗口对称性
还能想到其他参数吗?
几个观察的结论:
-
评测效果依赖选择训练词向量的模型/算法
-
训练集越大,效果越好
-
词向量维度特别高或者特别低的极端情况下,效果都不好。一般控制在300以内。
维度过低,导致高偏差;维度过高,导致高方差。
-
GloVe训练时,窗口大小为4时效果较好
-
对称窗口比非对称窗口效果好
内部评测示例:相关性评测
相关性评测也是评价词向量质量的一个简单方法,通常是人为的对两个词的相似度打分(0-10),然后与对应的词向量的余弦相似性比较。
扩展阅读:处理词的模糊性
也许有人疑惑,我们对于词的多义性怎么处理,例如,“run”即是动词,也是名词,根据不同的上下文表现出的词性不同。有一篇论文描述了解决这种情况的一个解决方法:
论文:Improving Word Representation Via Global Context And Multiple Word Prototypes (Huang et al. 2012)
-
对所有词固定上下文(例如前5后5)
-
词向量加权平均作为窗口的向量(例如以idf为权重)
-
对窗口用kmeans聚类
-
最后,出现在不同类簇的词用下标区别开,例如“run1”“run2”
LDA可以解决词的多义性,也许有方法将两者结合起来用
外部任务的训练
到目前,我们讨论了几种内部评测任务,现实中,大部分场景是用词向量来完成其他外部任务,接下来我们讨论下几种外部任务:
用公式表示问题
大多数的任务都可以归结为分类问题。例如,给定一个句子,可以将其分类为正、负、中间情绪;NER任务中,给定上下文和中心词,将中心词分类为不同的类别。针对这类问题,我们的输入都是这样的形式:
{ x ( i ) , y ( i ) } 1 N {x^{(i)}, y^{(i)}}_1^N {x(i),y(i)}1N
其中, x ( i ) x^{(i)} x(i)表示d维的词向量, y ( i ) y^{(i)} y(i)是C维的ohe-hot向量表示类别。
在典型的机器学习任务中,我们通常固定输入数据和目标类别,使用优化方法(梯度下降、L-BFGS、牛顿法)训练权重参数。然而,在NLP任务中,我们介绍一种思想,当我们训练外部任务的时候同样对词向量也重新训练。
下面讨论什么时候和为什么要重训练词向量。
词向量的重训练
我们已经知道,外部任务输入的词向量都是经过内部任务评测后效果较好的词向量,但是在子系统任务中,仍然可以对词向量进行重训练来达到更好的效果。然而,重训练也是有风险的。
**Tips:**词向量重训练时,需要考虑用较大的数据集,最好可以覆盖现有的词向量。否则,效果可能变差。
例如,初始训练“Telly”“TV”“Television”可能在相似的位置。重训练后,新的训练集可能不包含“Television”,而“Telly”“TV”训练到了新的位置,在计算相似性时,就会出现偏差。
Softmax分类和正则化
我们来讨论下softmax分类函数的形式:
p ( y i = 1 ∣ x ) = e x p ( W j ⋅ x ) ∑ c = 1 C e x p ( W c ⋅ x ) p(y_i = 1 | x) = frac{exp(W_{jcdot} x)}{sum_{c=1}^Cexp(W_{ccdot} x)} p(yi=1∣x)=∑c=1Cexp(Wc⋅x)exp(Wj⋅x)
这里, W ∈ R C ∗ d W in R^{C*d} W∈RC∗d ,公式中W的下标 W j ⋅ W_{jcdot} Wj⋅表示取第j行, W ⋅ i W_{cdot{i}} W⋅i 表示取i列。我们需要计算的是词向量 x 属于类别 j 的概率,使用交叉熵作为你损失函数,则损失函数公式为:
− ∑ j = 1 C y i l o g ( p ( y j = 1 ∣ x ) ) = − ∑ j = 1 C y i l o g ( e x p ( W j ⋅ x ) ∑ c = 1 C e x p ( W c ⋅ x ) ) - sum_{j=1}^Cy_ilog(p(y_j=1|x)) = - sum_{j=1}^C y_i log(frac{exp(W_{jcdot}x)}{sum_{c=1}^Cexp(W_{ccdot}x)}) −j=1∑Cyilog(p(yj=1∣x))=−j=1∑Cyilog(∑c=1Cexp(Wc⋅x)exp(Wj⋅x))
因为只有一个 y j y_j yj 为1,我们假设第k位为1,这个损失函数公式可以简化为:
− l o g ( e x p ( W k ⋅ x ) ∑ c = 1 C e x p ( W c ⋅ x ) ) -log(frac{exp(W_{kcdot}x)}{sum_{c=1}^Cexp(W_{ccdot}x)}) −log(∑c=1Cexp(Wc⋅x)exp(Wk⋅x))
然后,我们就可以将上述公式扩展到整个训练集上:
− ∑ i = 1 N l o g ( e x p ( W k ( i ) ⋅ x ( i ) ) ∑ c = 1 C e x p ( W c ⋅ x ( i ) ) ) -sum_{i=1}^N{log(frac{exp(W_{k(i)cdot}x^{(i)})}{sum_{c=1}^Cexp(W_{ccdot}x^{(i)})})} −i=1∑Nlog(∑c=1Cexp(Wc⋅x(i))exp(Wk(i)⋅x(i)))
这里, k ( i ) k(i) k(i) 是一个函数,返回样本 x ( i ) x^{(i)} x(i) 对应的正确的类别的下标。
我们来估计下训练模型权重和词向量会有多少个参数需要更新。我们知道,一个简单的线性决策边界需要一个输入 d d d 维向量和输出 C C C 中类别的分布的模型,那么,我们就需要更新 C ∗ d C*d C∗d 个参数。如果我们对词汇集 V V V 中每个词向量都更新,那么就需要更新 ∣ V ∣ |V| ∣V∣ 个词向量,每个 d d d 维。所以,一个简单的线性分类器总共需要更新的参数个数为 C ∗ d + ∣ V ∣ ∗ d C*d+|V|*d C∗d+∣V∣∗d :
∇ θ J ( θ ) = [ ∇ W ⋅ 1 ⋮ ∇ W ⋅ d ∇ x a a r d v a r k ⋮ ∇ x z e b r a ] nabla_theta{J(theta)} = begin{bmatrix}nabla_{W_{cdot{1}}}\vdots\nabla_{W_{cdot{d}}}\nabla_{x_{aardvark}}\vdots\nabla_{x_{zebra}}end{bmatrix} ∇θJ(θ)=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡∇W⋅1⋮∇W⋅d∇xaardvark⋮∇xzebra⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
这是一个非常巨大的参数,很容易造成过拟合。为了降低过拟合的风险,提出了增加正则项的方法:
− ∑ i = 1 N l o g ( e x p ( W k ( i ) ⋅ x ( i ) ) ∑ c = 1 C e x p ( W c ⋅ x ( i ) ) ) + λ ∑ k = 1 C ⋅ d + ∣ V ∣ ⋅ d θ k 2 -sum_{i=1}^N{log(frac{exp(W_{k(i)cdot}x^{(i)})}{sum_{c=1}^Cexp(W_{ccdot}x^{(i)})})} + lambdasum_{k=1}^{Ccdot{d}+|V|cdot{d}}theta_k^2 −i=1∑Nlog(∑c=1Cexp(Wc⋅x(i))exp(Wk(i)⋅x(i)))+λk=1∑C⋅d+∣V∣⋅dθk2
如果相对权重 λ lambda λ 调参到合适的值,最小化上述的损失函数,就会避免出现权重特别大的情况,同事模型的泛化能力也表现不错。需要注意的是,正则化对于拥有很多参数的神经网络这种复杂的模型很重要。
窗口分类
目前为止,我们讨论都是基于一个单词的词向量作为输入的外部任务。现实中,自然语言在不同上下文往往有不同的含义,所以我们需要消歧。大多数情况下,我们需要一系列的词作为模型的输入,也就是一个上下文窗口。
通常,小窗口适于解决语法任务,大窗口适于解决语义任务。
在之前定义的softmax模型中,如果使用窗口代替单词,则输入 x ( i ) x^{(i)} x(i) 要变为 x w i n d o w ( i ) x_{window}^{(i)} xwindow(i)
x w i n d o w ( i ) = [ x ( i − 2 ) x ( i − 1 ) x ( i ) x ( i + 1 ) x ( i + 2 ) ] x_{window}^{(i)} = begin{bmatrix}x^{(i-2)}\x^{(i-1)}\x^{(i)}\x^{(i+1)}\x^{(i+2)}\end{bmatrix} xwindow(i)=⎣⎢⎢⎢⎢⎡x(i−2)x(i−1)x(i)x(i+1)x(i+2)⎦⎥⎥⎥⎥⎤
相应的,在计算损失函数的梯度的时候,我们会得到 ∇ nabla ∇ 形式的向量。
实际上,这一步是可以分布式计算的。
非线性分类
现在,需要介绍一下非线性分类器,例如神经网络。在实际应用中经常会需要非线性分类器。我们将在下节课开始介绍在深度学习中表现出色的非线性决策边界—神经网络。
最后
以上就是粗暴小天鹅为你收集整理的CS224D 课程学习笔记 L03的全部内容,希望文章能够帮你解决CS224D 课程学习笔记 L03所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复