deeplearning.ai 序列模型 Week 2 NLP & Word Embeddings

 

1. Word representation

  One-hot representation的缺点:把每个单词独立对待,导致对相关词的泛化能力不强。比如训练出“I want a glass of orange juice”后,面对“I want a glass of apple          ”,由于任何两个不同单词的one-hot vector的内积都为0,算法不知道orange和apple是一类词,所以没办法泛化出在apple后面填“juice”。

  Featurized representation: word embedding可以有效解决这个问题。如下图所示,用一大堆特征描述每一个单词,图中列举了300个特征,包括Gender、Royal、Age、Food……Size、Cost、Alive(是不是活的)、Verb(是不是动词)等,每个单词可以用一个300*1的向量描述,例如Man在词典中是第5391个,则它的特征描述向量为e5391(这里e表示word embedding)。这时候看Apple和Orange两个单词,它们的大部分特征很近似,所以算法对它们泛化的比较好。当然,在实际的算法中,特征向量的每一个元素可能不是这么好直观理解,但最终目的都是找到不同词之间的相关性。常用的可视化算法是t-SNE(Van der Maaten and Hinton, 2008, “Visualizing data using t-SNE”),可以把高维度的特征向量映射到二维平面,看到类似聚类的效果。单词的特征描述相当于把一个个单词镶嵌到高维度空间里(例子中是300维),这是embedding这个命名的由来。Word embedding另一个好处是可以用相对低维度的特征向量(例如300维)代替one-hot representation高维度(例如10000维)的描述,虽然one-hot vecotr计算很快(因为是稀疏的),但word embedding更紧凑(dense)。

 

2. Using word embeddings

  如果算法只在数据量比较小的训练集上训练,在测试阶段可能会遇到很多训练集中没有的单词,但是如果这些陌生单词有word embeddings,则算法依旧对它们有非常好的泛化能力。Word embedding在训练集比较小的情况下作用最明显,对于有大量数据的情况(比如机器翻译)用的少一些。

  第一步:从极大的语料库(1~100 Billion个单词,一般是互联网上获得)学习word embeddings(这个语料库没有标签,并不是训练集,只是单纯为了学习每个单词的特征描述);或者直接网上下载pre-trained embeddings。

  第二步:用第一步获得的特征描述在小的训练集(比如100k个单词)上训练算法。这一步是类似transfer learning的操作,把从互联网上免费获得的大量无标签文本中学到的信息迁移到具体的任务上。

  第三步:在新的应用中,可以用新的数据对word embedding进行finetune。这一步是可选的,一般在第二步的训练集足够大(比如100k,第二步认为100k比较少是跟第一步的语料库比)的情况下做,如果第二步的训练集不够大,就没必要finetune。

  另外,word embeddings和人脸识别很类似,因为人脸识别也是把人脸转换成特征编码(比如128*1的向量),这里embedding和encoding是一样的意思。二者的区别在于人脸识别是训练一个可以给任意人脸照片编码的神经网络,即便是没有见过的人脸照片,而NLP这边是针对一个固定大小的词汇表(比如10000个单词)。

 

3. Properties of word embeddings

  Word embeddings的一大用处是可以做词语的类比推理。比如已知man对应woman,问king对应哪个单词?这个问题抽象成数学模型就是求解向量的相似性。

  最常用的评估相似性的方法是cosine similarity:$sim(u, v)=\frac{u^Tv}{||u||_2||v||_2}$,这可以计算u、v两个向量的夹角。另一种用的少一些的描述相似性的方法是欧氏距离:$sim(u, v)=||u-v||^2$。

 

4. Embedding matrix

  如何学习出单词的word embedding描述呢?这里构造了一个矩阵叫embedding matrix,矩阵的每一列对应一个单词的word embedding描述,所以如果用300个特征描述10000个单词,embedding matrix就是300*10000的大小。定义embedding matrix为E,ej为第j个单词的word embedding,oj为第j个单词的one-hot vector,则$Eo_j=e_j$。但在实际操作中,矩阵的乘法时间复杂度太高,所以会一个专门的函数从embedding matrix中直接读取某一列的word embedding,而不是用矩阵乘法。

5. Learning word embeddings

  深度学习领域,研究者们一开始用比较复杂的算法来学习word embeddings,后来慢慢发现可以用更简单的算法达到同样的效果(尤其在数据集很大的情况下)。Andrew NG表示他会先介绍复杂的算法,因为更容易直观理解,之后再介绍简单的算法。

  最早的有效学习word embeddings的方法之一来自Bengio et. al., 2003, A neural probabilistic language model。如下图所示,根据前6个单词推测第7个单词,首先用每个单词的one-hot vector去乘embedding matrix得到word embedding,然后把这6个单词的word embedding堆叠成1800*1的向量(这里假设word embedding是300*1的向量,如果是用4个单词做推测,则堆叠成1200*1的向量)作为输入送给一个神经网络,再跟一个softmax函数预测每一个单词的概率(这里假定词库是10000个单词,所以输出10000*1的向量)。预测出的单词可以和真值作比较,然后用反向传播进行梯度下降,优化的参数包括embedding matrix、神经网络的参数(w[1],b[1])和softmax的参数(w[2],b[2])。研究者发现,如果是为了学习语言模型,一般用前几个单词(比如4个)预测下一个单词;如果是为了学习word embedding,也可以用前四个单词和后四个单词(4 words on left & right)预测中间的单词,或者用前一个单词(last 1 word)预测下一个单词,或者用附近的一个单(nearby 1 word)词预测,也可以得到很好地结果。

6. Word2Vec

  相比于前一节的算法,这一节介绍的学习word embeddings的算法(Mikolov et. al., 2013. Efficient estimation of word representations in vector space)更简单、计算更高效。该算法选取某个单词作为上下文(context),然后在它周围的一定距离内(一般会有个window,比如前后5个或10个单词之内)随机选取另一个单词作为目标单词(target),这种模型被称为Skip-grams。有了context和target的配对就可以构造监督学习问题,即根据context预测target,目的并不是准确预测,而是学习出word embeddings。如下图所示,把context的one-hot vector乘以embedding matrix得到context的word embedding,然后送给softmax函数得到对词库10000个单词的概率的预测$\hat{y_i}$(等价于图片中的条件概率p(t|c)),然后求出损失函数的值。这里参与优化的参数是embedding matrix E和softmax函数的参数 θ。

  这个算法最大的问题是softmax函数分母的计算量太大,影响计算速度。一种解决办法是hierachical softmax classifier,这种方法不是一下子判定到底属于10000类中的哪一类,而是用分类器(比如logistics)先判定在词汇表的前5000个单词还是后5000个单词,如果是前5000个单词再判定在前2500个单词还是后2500个单词,以此类推,最终找到属于某个类别。实际操作中,不会构造一个完美平衡(或者说左右对称)的分类树,而是根据单词出现的频率构造分类树,常用词(比如the、of)在顶部只需要几步搜索,不常用的词(比如durian榴莲)比较深需要很多步的搜索。

  如何对context进行采样?对语料库均匀且随机地采样是不合适的,这会导致常用单词(比如the、of)出现的相当频繁。所以会根据单词出现的概率启发式地设计对context的采样概率P(c)。

 

7. Negative sampling

  这一节的算法(Mikolov et. al., 2013. Distributed representation of words and phrases and their compositionality)省去了上一节softmax函数分母的计算,更加高效。该算法在语料库中选取一个上下文单词,再选取它周围的一个单词作为目标单词,这两个单词构成了一对正样本。然后对同一个上下文单词,从语料库中随机选取其他k个单词(对于of、the这样的常见词,即使出现在上下文单词周围,也被看做是负样本),构成k对负样本。然后对这k+1个样本进行监督学习训练,预测各个样本是正样本还是负样本。如何选择k呢?数据集越小k越大,对于小数据集,k=5~20;对于大数据集,k=2~5。如下图所示,这一节的算法把上一节的10000个类别(10000-way softmax classifier,这里假设语料库有10000个单词)的softmax分类器转化为10000个二分类分类器(logistic函数),而且每一次迭代只是更新其中k+1个分类器。如何选取负样本呢?Mikolov等人提出的经验公式是$P(w_i)=\frac{f(w_i)^{3/4}}{\sum_{j=1}^{10000}f(w_j)^{3/4}}$,其中$f(w_i)$是语料库中$w_i$这个单词出现的频率。

8. GloVe(global vectors for word representation) word vectors

  本节的算法(Pennington et. al., 2014. GloVe: Global vectors for word representation)不如Word2Vec或者skip-gram模型用的多,但确实更简单。该算法定义了变量Xij,表示第i个单词(等价于之前介绍的算法里的target)在第j个单词(等价于之前介绍的算法里的context)的上下文的次数。或者说,Xij是统计这两个单词在一起出现的计数器。如果定义上下文是单词前后对称的若干个单词,则Xij=Xji,否则不相等。该算法的优化目标是:

$$minimize\sum_{i=1}^{10000}\sum_{j=1}^{10000}f(X_{ij})(\theta_i^Te_j+b_i+b_j'-logX_{ij})^2$$

这个公式的含义是训练$\theta_i$和$e_j$使得二者的乘积能够尽可能接近两个单词共同出现的频次Xij(在logistic和softmax函数中都是$e^{\theta_t^Te_c}$,而这里是对Xij取log)。这里$b_i$和$b_j'$是偏差项,$f(X_{ij})$是权重项,当Xij=0时,$f(X_{ij})=0$,并且定义了0log0=0;另一方面,对于this、is、of这样的常见词,$f(X_{ij})$不能太大,而对于durian这样的罕见词,$f(X_{ij})$不能太小。另外,该算法中,$\theta_w$和$e_w$是对称的,两者物理意义相同,所以最终单词w的word embedding可以定义为$e_w^{(final)}=(e_w+\theta_w)/2$。

  值得一提的是,训练出来的特征向量的不一定能用人易于理解的方式来描述。比如我们定义了特征向量的几个维度是Gender、Royal、Age、Food等,但由于$(A\theta_i)^T(A^{-T}e_j)=\theta_i^TA^TA^{-T}e_j=\theta_i^Te_j$,这意味着训练出的特征向量各个维度的轴可能被旋转,或者说各个维度是人能理解的那些维度的组合,导致不再能被人理解。

 

9. Sentiment classification 情感分类

  情感分类问题是根据一段文字判断这个人是否喜欢这个东西。比如大众点评里用户会对商铺写一段评论并且打星,那么这里的情感分类问题就是根据评论判断用户会打几颗星。这个问题的难点在于带标记的训练集没有那么大,但有了word embeddings,即使只有中等大小的带标记的训练集也可以构建一个不错的情感分类器。

  最简单的算法是把评论中每个单词根据embedding matrix转换成word embeddings,然后求所有单词的word embeddings的平均值,然后把这个平均值(如果word embedding是300维的向量,那么这个平均值也是300维的向量)送给一个softmax分类器,然后预测出几颗星。这种算法的问题是忽略了词序,如果评论是“Completely lacking in good taste, good service, and good ambience”,由于出现了很多“good”,所以word embeddings的平均值也是一个偏正面的评价,算法不知道由于存在"lacking in"的否定,所以所有的“good”其实都是负面评价。所以改进版的算法会用一个RNN替换求平均的操作:

 

这是一个many-to-one的RNN架构。这里word embedding的价值在于,如果另一个评论没有用“lacking in”而是用了“absent of”,由于二者的特征向量很接近,所以依旧可以泛化出很好的结果。

 

10. Debiasing word embeddings 词嵌入除偏

  本节算法(Bolukbasi et. al., 2016. Man is to computer programmer as woman is to homemaker? Debiasing word embeddgins.)讨论的是如何消除算法的偏见(比如性别、种族、年龄歧视等)。这里用性别歧视举例子,man:computer programmer等价于woman:什么呢?如果算法给出homemaker,这就产生了性别歧视,我们希望woman也是对应computer programmer,或者说computer programmer这个词组不应该有性别特征。如何消除算法的偏见呢?第一步:确定偏见在word embedding空间(比如300维)的趋势方向。具体做法是计算出he和she、male和female等单词的word embeddings的差值,然后对这些差值求平均值,这就得出了整体的和性别相关的偏见方向(bias direction),这里bias direction是一维的,则剩下的299维构成了non-bias direction。这里Andrew NG是做了简化,原论文中bias direction不是简单取平均值得到的,而是用类似主成分分析的方式得到的,这时候bias direction可能有几个维度,剩下的维度就构成了non-bias direction。第二步:对于doctor、babysitter这种我们希望和性别特征无关的中性词,把它们投影到non-bias direction上去,这样就消除了bias direction上的成分。如何确定哪些单词是中性词呢?这篇论文的作者设计了分类器来判定哪些单词是中性的。第三步:对于grandmother、grandfarther这种我们希望只和性别有关的单词,使得它俩和中性词的距离相同。

  

posted @ 2018-05-01 14:28  ZonghaoChen  阅读(656)  评论(0编辑  收藏  举报