李裕礞 从神经网络入门到Attention
新闻来源:IR实验室       发布时间:2016/10/25 20:03:40

今年Attention机制变得非常流行,在ACL2016的论文中有10篇与Attention相关的,在EMNLP2016的论文中又有10篇,其火热程度由此可见。与Attention相关的总结性文章也有很多(http://www.cnblogs.com/robert-dlut/p/5952032.html),本文主要将以探索的视角逐步了解神经网络并初窥Attention机制,力求让研一的同学也能尽快入门了解深度学习中的一隅。http://acl2016.org/index.php?article_id=68)(http://www.emnlp2016.net/accepted-papers.html

本文将首先介绍一些神经网络的基础知识,然后简单介绍Word Embeeding,再由词向量到句子向量及篇章向量,最终介绍Pooling层中的Attention方式,尝试理解其想法的涌现过程。

1. 入门神经网络

假设我们当前要处理一项任务:判断一个句子的情感极性,以评论为例即该评论是好评还是差评。这是一个典型的分类的问题,输入是文本,输出是情感类别。首先应该做的便是将句子向量化,比较简单的一种方式是计算每句话的TFIDF特征值,TFIDF是使用词频除以文档频率来表示一个词的重要性权重,这种处理使得文字转变为向量,从而可以输入到模型中,而且向量中的值还携带着句子的信息(各词的重要性)。TFIDF向量的维度是整个词表的大小,一个100M左右的语料估计也会有20万个不重复的词,因此该特征处理起来是较慢的,但它已经达到了对文本进行向量化的目的,并且效果还不错。

image_1avtd6mu81k2efgiu4ucmn1c759.png-27kB       image_1avth2rkv1kmjtav1li163o1u5h9.png-55.8kB

将得到的TFIDF向量输入到上面这样的单层网络中,网络将输出一个其为好评的概率值。其中x_nTFIDF向量的各维上的值,w是随机初始化的权重,激活函数选用常用的sigmoid激活,输出0表示差评,1表示好评。这个和逻辑回归是一样的,这里就不再赘诉。 

记得我在刚刚学习逻辑回归的时候,曾想过一个问题,如果训练10个逻辑回归模型,然后将得到的10组结果拼接在一起作为下一个模型的输入,再训练一个逻辑回归模型,这样是否可行呢?当时还动手尝试了一下,结果过拟合了,于是对10个逻辑模型使用了不同的训练集,然后再把它们的结果输入到一个新的逻辑回归中,这样最终在测试集上的结果也有了提高。当时并不知道,这其实是一种常用的模型融合方法。 
 这里介绍的多层的神经网络模型也可以看做是多个逻辑回归结合在一起,但与上面我说的手动连接两层逻辑回归模型的区别在于,神经网络模型中权重w的更新是两层同步进行的。 

手动拼接两层逻辑回归:

训练好第一层的10个逻辑回归模型,每个模型可能迭代了100次以上,并已经收敛了。 
合并第一层的输出,作为第二层逻辑回归的输入,再迭代100次,直到收敛。 
也就是训练好了第一层,再去训练第二层。

两层的神经网络模型:

第一层的10个逻辑回归模型迭代1次,将结果传递给第二层逻辑回归,第二层迭代1次。 反复执行上面的步骤,直到收敛。这便是经典的前馈神经网络,实际上在每轮迭代过程中,都根据输出误差的梯度值对各个边上的权重w进行了更新,每更新一代,都包括了网络中所有层的边的权重。这要比训练好第一层,再去训练第二层效果好很多。

2. 关于激活函数

网络的每一层在输出时,都需要进行一次非线性变换,被称为激活。如果不进行激活,则网络中各层均进行线性变换,这样无论网络包含多少层,最终的输出都可以用输入的线性变换表示出来,也就和1层的线性网络没有差别了。非线性的变换能够让网络存储的信息大大增加,而非线性变换的方式并不固定。下表列出了常用的非线性变换的函数形状(其中第三项是线性变换,是用作对比的)。

image_1avthbacta3tmap1q8m15b6cffm.png-131.5kB

除上面这些之外,还有几种高级的激活函数。

clip_image008.png   clip_image010.png  

            Relu激活函数                         PRelu激活函数

clip_image012.png   clip_image014.png

                ELU激活函数                    MPELU激活函数

到底应该在自己构建的神经网络中使用哪种激活函数,并没有固定的答案。根据前人总结的经验,通常使用tanh激活函数要比sigmoid收敛速度更快;在较深层的神经网络中,选用relu激活函数能使梯度更好地传播回去,但当使用softmax作为最后一层的激活函数时,其前一层最好不要使用relu进行激活,而是使用tanh作为替代,否则最终的loss很可能变成Nan;当选用高级激活函数时,建议的尝试顺序为ReLU->ELU->PReLU->MPELU,因为前两者没有超参数,而后两者需要自己调节参数使其更适应构建的网络结构。

总之,神经网络其实并没有想象中那么高端,在理解了逻辑回归之后,了解神经网络还是很容易的,其中的损失函数,梯度下降的计算都是类似的。在理解了前馈神经网络之后,再去推导卷积神经网络和循环神经网络,也会感觉他们的变化其实并没有那么大。


3. Word Embedding

  谈到使用神经网络模型或者深度学习模型,就不得不提起Word Embedding技术。在2012Googleword2vec工具开源之后,这项技术便热门起来。其根本原理是十分简单的,但word2vec的工具运行速度被优化地太快了,可以在1天内训练几十G的语料,而且是无监督学习,效果又这么好。就像下图展示的这样,输入一个词之后,可以使用该模型得到与其语义距离最相近的一些词。

blob.png

因为word2vec也火了4年了,介绍该理论的文章也十分全面了,我在这里也不去介绍其加速的过程了,只展示其根本原理,让我们来一起看看其实它也不过如此。 
Word2vec
只是定义了一个特别的损失函数,如下所示: 

image_1avtii5be1sk81fol17751o6qtjc3h.png-7.4kB

说得直白一点也就是:当给出周围的词时,让中间的那个词出现的概率最大。举个例子:I am in Dalian ____ of Technology. 如果这句话让我们进行完型填空的话,99%的人都会填上University。这是基于我们的先验知识的,我们认为周围词是上述这些词的时候,中间出现University的概率最大。word2vec想要达到的就是这种效果,它先为每个词随机赋予n维的向量,然后定义了如下的概率计算方法: 

image_1avtjjfr21gi5p6nnk11ni81efj3u.png-5.8kB

image_1avtjjreb16mggcl1hus1ua21o2a4b.png-4.6kB

其中wUniversity这个词的向量,Context(w)为周围这几个词的词向量的平均值。通过softmax函数转变为和为1的概率值。通过不断地调整各个词的词向量,使得当填入University时,求得的概率P最大(至少比填入Home, Father这些词时求得的P值要大)。当对于训练语料的所有句子,均进行了n轮这样的词向量调整之后,也就达到了用词向量的空间距离来表示各词的语义关系的目的。

word2vec的词向量的神奇之处还在于,两个词的词向量的差,即向量方向,可以表示一种关系。如下图所示,国王-皇后得到的方向与男人-女人得到的方向非常接近。 
blob.png     blob.png 

这种效果都得益于其构造的损失函数。下面这张图中的TransE模型,在词向量的基础上进行了改变,来用向量表示实体关系,可以使得 中国+首都 = 北京。这种效果也是在损失函数上进行改动,只需要使 中国+首都-北京 得到的值尽可能小便可以了。

blob.png

  总之,词向量作为另一种将文本转换为向量的方式,比TFIDF特征包含了更多语义的信息,而这种无监督的学习方式,使我们获取训练语料更加的方便,在实际应用中也具有很好的效果,现在的大多应用到文本上的深度学习模型也都会选取各种词向量生成模型来作为第一级的文本向量化的部分。

4. 句子及篇章向量

我们可以很容易地使用word2vec或者GloVe这样的工具基于一份大语料获得词向量,但如果是进行句子级的分类,我们是需要将句子向量输入到传统机器学习模型或者上面介绍过的前馈神经网络中。这里就需要进行词向量到句子向量的变换。 
  一个最直观的想法是对该句子中所有词的词向量取平均,来得到句子向量。实际上,也有很多论文采用了这种方法。另一种选择是取句子中每维度上词向量的最大值。从句子向量到篇章向量也可以采用这样的策略,以下面这条微博为例: 

image_1avtol83fb1t163m7oota1md21g.png-66.5kB

我们可以很直观地看到其中红框内的文字突显出了这条微博的情感极性,而作死两个字又能直接概括这句话的情感。而这种最大池化的方法有效的另一个原因是,在神经网络模型运行的过程中,原始的词向量也是会被改变的,它会根据网络的结构,制定的策略而调整到最适合该结构的词向量。 
现在我们已经有了两种策略:平均池化、最大池化,而实际上,我们当然也可以为每个词设置一个权重,通过对句子中各词的词向量进行加权取平均来得到句子的向量。

5. 加权池化

平均池化及最大池化都可以看做加权池化的一个特例,平均池化为各词权重相同,最大池化为值最大的权重为1其余均为0。那么如何制定各词的权重规则更合理呢?我们可以使用上文提到的TFIDF特征,因该特征表示的就是词的重要程度,因此用该特征进行词向量的加权也是有根据的。 

我们以SMP CUP 2016 微博用户画像竞赛的任务为例:该任务为给定用户发表的多条微博,推断用户的年龄、性别及地域。 

如下图所示,首先使用微博的TFIDF特征对微博中各词的词向量进行加权平均,然后进行了一层隐藏层变换,再使用最大池化的方法由微博向量得到用户向量。以这种方式完成了 词向量->微博向量->用户向量 的转化。

image_1avtousf8pk6jc2amn1sbs1tfv1t.png-134.3kB

当然我们有更简单的一种方式,直接将一个用户的所有微博拼接在一起当做一个句子,计算TFIDF特征,然后对词向量进行加权,则直接得到了用户向量。我们同时采用这两种方式得到的用户向量,则形成了一种层级式的BP神经网络模型,如下图所示: 

image_1avtpf7f66s49be1f7911srosh2n.png-179kB

这种层级式的网络模型优势在于可以充分利用不同粒度的文本权重信息,其用户粒度的用户向量还可以拼接上使用PCA降维之后的TFIDF特征向量,在输出层之前还可以拼接上人工构建的非文本特征,使得网络可利用的信息更加全面。

6. Attention机制

我们使用TFIDF对词向量进行加权平均,是因为我们知道TFIDF特征能够在一定程度上表现词的重要性,这是基于我们先验知识的。那么能不能使网络自动计算出各词的权重呢?这就是Attention机制在Pooling层的应用。实际上Attention机制只是一种称呼罢了,本质上是在想各种办法改变网络的连接结构,从而在网络的各个部位对输入或者输出进行加权。这种加权有时候利用的是词向量本身,有时候还会利用外部的其他向量(例如用户向量、商品向量),在具有多个输入实体的任务上(例如关系分类),又会使用两个实体的向量互相加权。最为神奇的是,这种加权并不需要人工干预,不用人工设置初始值,只需随机初始化或者起始时设为相同值,甚至加入的外部向量(用户向量、商品向量)也可以随机初始化,随着网络根据损失函数的设定,不断调节各向量的值及边上的权重,便可有效地表示出各词的权重。说到底,我们只需要给网络赋予一种能力,基于词向量的加权池化层让网络具有自己非线性调整输出权重的机会,用户向量的加入是让网络可以知道哪些评论是同一个用户发出来的,商品向量让网络知道哪些评论是针对同一个商品的,虽然都是随机初始化的,但这种关系已经被保留到了网络中,在处理某条评论时,改变了用户向量,则在处理该用户的下一条评论时,使用的也会是最新的用户向量。

blob.png

目前较为常用的Attention公式如上所示,其中hit为经过隐藏层变换的词向量,也可以直接替换为词向量。Wwbw都是随机初始化的权重,uw是原词的词向量,blob.png即为得到的该词的权重。

本文只简单介绍神经网络的概念及其中Attention的想法,帮助新生更好地入门。目前Attention发展得很快,想在这方面做文章,还需要跟随上目前发展的脚步,了解当前的发展综述可参考这篇文章http://www.cnblogs.com/robert-dlut/p/5952032.html并阅读其中推荐的论文。

 

7. 参考文献

[1] 神经网络中激活函数的作用 http://www.jiqizhixin.com/article/1479

[2] Chen, Huimin, et al. "Neural Sentiment Classification with User and Product Attention."

[3] Yang, Zichao, et al. "Hierarchical attention networks for document classification." Proceedings of the 2016 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies. 2016.

[4] 复旦 神经网络与深度学习讲义 http://nlp.fudan.edu.cn/dl-book/