序列模型介绍
在机器学习的任务中,很多任务其实都可以看作序列的模型。所谓序列,就是指这个模型中的元素不再独立,而是具有一定的相关性。一般,我们根据输入输出,把常用模型划分为如下几类:
-
一对一的模型。比如全连接神经网络,就是一对一的结构。我们给它一个输入,它能得到一个输出,而且不同输入间被视作了独立的关系,分别进行学习或者识别等任务。而现在我们要关注的,是后四幅图,也就是时序的模型。
一对多模型:根据模型的一个输出,可以用来预测一个序列。比如对于一个图像,输出一串字幕来描述它。
多对一模型:根据一个序列输入,从而预测一个值。比如根据用户在一家饭店的留言,判断用户对这家饭店的评价。那么,输入是一段话是一个序列输入,输出是
0-5
之间的一个数作为打分。多对多有延迟:根据模型的序列输入,我们根据已有的输入,有延迟地输出一个序列。常见的任务比如翻译的学习任务,英文翻译成中文。模型需要等英文输入到一定程度后,才能翻译成中文,这样输入输出都为一个序列。
多对多无延迟:根据模型的序列输入,根据输入同步输出一个序列。常见的比如做天气预报,需要实时根据测得的温度、湿度等做出下雨概率的预测。但是,每一次预测其实也要考虑之前的一些序列输入,而不仅由这一时刻的输入所决定。
可以看出,序列模型的典型特点是输入输出不独立,往往输出跟前一步、甚至前几步的输入相关。此时可以使用循环神经网络等拟合并分析这样的过程。
简单的循环神经网络
在传统的神经网络中,输入层到输出层的每层直接是全连接的,但是层内部的神经元彼此之间没有连接。这种网络结构很难处理如文本处理,语音翻译等任务。
循环神经网络的解决方法,是通过让隐藏层不仅只考虑上一层的输出,还包括了上一时刻该隐藏层的输出。理论上,循环神经网络能够包含前面任意多个时刻的状态。
相比于传统的神经网络,循环神经网络将不同时序的同一层前后连了起来,权值上就会通过引入另一个权值,来决定上一时刻的输出如何作为输入,并影响到下一时刻的输出。
于是就有了这样一个简单的基本结构:
左边表示一个循环的图像,右边则是网络在具体搭建时的思路,二者完全等价。假定上一时刻隐藏层的输出为,这一时刻的输入为,那么这一时刻隐藏层的输出应该为:
那么我们通过反向传播,不仅在层之间反向传播,也在时间上随时间反向传播,就可以不断更新优化,和的值,从而达到学习目的。
自然语言处理简介
用自然语言与计算机进行通信,这是人们长期以来所追求的。因为它既有明显的实际意义,同时也有重要的理论意义:人们可以用自己最习惯的语言来使用计算机,而无需再花大量的时间和精力去学习不很自然和习惯的各种计算机语言;人们也可通过它进一步了解人类的语言能力和智能的机制。
实现人机间自然语言通信意味着要使计算机既能理解自然语言文本的意义,也能以自然语言文本来表达给定的意图、思想等。前者称为自然语言理解,后者称为自然语言生成。
自然语言处理,即实现人机间自然语言通信,或实现自然语言理解和自然语言生成是十分困难的。造成困难的根本原因是自然语言文本和对话的各个层次上广泛存在的各种各样的歧义性或多义性(ambiguity)。
自然语言的形式(字符串)与其意义之间是一种多对多的关系。其实这也正是自然语言的魅力所在。但从计算机处理的角度看,我们必须消除歧义,而且有人认为它正是自然语言理解中的中心问题,即要把带有潜在歧义的自然语言输入转换成某种无歧义的计算机内部表示。
DeepNLP 的核心关键: 语言表示(Representation)
最近有一个新名词:Deep Learning + NLP = DeepNLP。当常规的机器学习 Machine Learning 升级发展到了一定的阶段后,慢慢的被后起的深度学习 Deep Learning 夺势而去,并如火如荼地引领了一波新高潮,因为 Deep Learning 有 machinelearning 过而不及之处!那当 Deep Learning 进入 NLP 领域,自然是要横扫 ACL 一批 paper 才是。事实也是这样的。
先提下数据特征表示问题。数据表示是机器学习的核心问题,在过去的 Machine Learning 阶段,大量兴起特征工程,人工设计大量的特征解决数据的有效表示问题。而到了 Deep Learning,想都别想,end-2-end,一步到位,hyper-parameter 自动帮你选择寻找关键的特征参数。
那么,Deep Learning 如何能在 NLP 中发挥出应有的 real power 呢?很明显,先不提如何设计出很强势的网络结构,不提如何在 NLP 中引入基于 NN 的解决例如情感分析、实体识别、机器翻译、文本生成这些高级任务,咱们首先得把语言表示这一关过了——如何让语言表示成为 NN 能够处理的数据类型。
我们看看图像和语音是怎么表示数据的:
在语音中,用音频频谱序列向量所构成的 matrix 作为前端输入喂给 NN 进行处理,good;在图像中,用图片的像素构成的 matrix 展平成 vector 后组成的 vector 序列喂给 NN 进行处理,good;那在自然语言处理中呢?噢你可能知道或者不知道,将每一个词用一个向量表示出来!想法是挺简单的,对,事实上就是这么简单,然而真有这么简单吗?可能没这么简单。
有人提到,图像、语音属于比较自然地低级数据表示形式,在图像和语音领域,最基本的数据是信号数据,我们可以通过一些距离度量,判断信号是否相似,在判断两幅图片是否相似时,只需通过观察图片本身就能给出回答。而语言作为人类在进化了几百万年所产生的一种高层的抽象的思维信息表达的工具,其具有高度抽象的特征,文本是符号数据,两个词只要字面不同,就难以刻画它们之间的联系,即使是 “麦克风” 和 “话筒” 这样的同义词,从字面上也难以看出这两者意思相同(语义鸿沟现象),可能并不是简单地一加一那么简单就能表示出来,而判断两个词是否相似时,还需要更多的背景知识才能做出回答。
那么据上是不是可以自信地下一个结论呢:如何有效地表示出语言句子是决定 NN 能发挥出强大拟合计算能力的关键前提!
NLP 词的表示方法类型
接下来将按照上面的思路,引出各种词的表示方法。按照现今目前的发展,词的表示分为独热表示 one-hot、分布式表示 distributed。
1、词的独热表示 one-hot representation
NLP 中最直观,也是到目前为止最常用的词表示方法是 One-hot Representation,这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个维度就代表了当前的词。关于 one-hot 编码的资料很多,街货,这里简单举个栗子说明:
“话筒” 表示为 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ...]
“麦克” 表示为 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...]
每个词都是茫茫 0 海中的一个 1。这种 One-hot Representation 如果采用稀疏方式存储,会是非常的简洁:也就是给每个词分配一个数字 ID。比如刚才的例子中,话筒记为 3,麦克记为 8(假设从 0 开始记)。如果要编程实现的话,用 Hash 表给每个词分配一个编号就可以了。这么简洁的表示方法配合上最大熵、SVM、CRF 等等算法已经很好地完成了 NLP 领域的各种主流任务。
现在我们分析他的不当处。
- 向量的维度会随着句子的词的数量类型增大而增大
- 任意两个词之间都是孤立的,根本无法表示出在语义层面上词语词之间的相关信息,而这一点是致命的
2、词的分布式表示 distributed representation
传统的独热表示( one-hot representation)仅仅将词符号化,不包含任何语义信息。如何将语义融入到词表示中?Harris 在 1954 年提出的分布假说( distributional hypothesis)为这一设想提供了理论基础:上下文相似的词,其语义也相似。Firth 在 1957 年对分布假说进行了进一步阐述和明确:词的语义由其上下文决定( a word is characterized by thecompany it keeps)。
到目前为止,基于分布假说的词表示方法,根据建模的不同,主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示。尽管这些不同的分布表示方法使用了不同的技术手段获取词表示,但由于这些方法均基于分布假说,它们的核心思想也都由两部分组成:一、选择一种方式描述上下文;二、选择一种模型刻画某个词(下文称 “目标词”)与其上下文之间的关系。
NLP 语言模型
语言模型包括文法语言模型和统计语言模型。一般我们指的是统计语言模型。之所以要将语言模型摆在词表示方法之前,是因为后面的表示方法马上要用到这一概念。
统计语言模型: 统计语言模型把语言(词的序列)看作一个随机事件,并赋予相应的概率来描述其属于某种语言集合的可能性。给定一个词汇集合 V,对于一个由 中的词构成的序列 ,统计语言模型赋予这个序列一个概率 ,来衡量 符合自然语言的语法和语义规则的置信度。
用一句简单的话说,就语言模型就是计算一个句子的概率大小的这种模型。有什么意义呢?一个句子的打分概率越高,越说明他是更合乎人说出来的自然句子。
就是这么简单。常见的统计语言模型有 元文法模型(N-gram Model),最常见的是 unigram model、bigram model、trigram model 等等。形式化讲,统计语言模型的作用是为一个长度为 的字符串确定一个概率分布 ,表示其存在的可能性,其中 到 依次表示这段文本中的各个词。一般在实际求解过程中,通常采用下式计算其概率值:
同时通过这些方法均也可以保留住一定的词序信息,这样就能把一个词的上下文信息 capture 住。
词的分布式表示
- 基于矩阵的分布表示
基于矩阵的分布表示通常又称为分布语义模型,在这种表示下,矩阵中的一行,就成为了对应词的表示,这种表示描述了该词的上下文的分布。由于分布假说认为上下文相似的词,其语义也相似,因此在这种表示下,两个词的语义相似度可以直接转化为两个向量的空间距离。
常见到的 Global Vector 模型( GloVe 模型)是一种对 “词 - 词” 矩阵进行分解从而得到词表示的方法,属于基于矩阵的分布表示。
- 基于神经网络的分布表示,词嵌入( word embedding)
基于神经网络的分布表示一般称为词向量、词嵌入( word embedding)或分布式表示( distributed representation)。这正是我们的主角 today。
神经网络词向量表示技术通过神经网络技术对上下文,以及上下文与目标词之间的关系进行建模。由于神经网络较为灵活,这类方法的最大优势在于可以表示复杂的上下文。在前面基于矩阵的分布表示方法中,最常用的上下文是词。如果使用包含词序信息的 n-gram 作为上下文,当 n 增加时, n-gram 的总数会呈指数级增长,此时会遇到维数灾难问题。而神经网络在表示 n-gram 时,可以通过一些组合方式对 n 个词进行组合,参数个数仅以线性速度增长。有了这一优势,神经网络模型可以对更复杂的上下文进行建模,在词向量中包含更丰富的语义信息。
词嵌入( word embedding)
1、概念
基于神经网络的分布表示又称为词向量、词嵌入,神经网络词向量模型与其它分布表示方法一样,均基于分布假说,核心依然是上下文的表示以及上下文与目标词之间的关系的建模。
前面提到过,为了选择一种模型刻画某个词(下文称 “目标词”)与其上下文之间的关系,我们需要在词向量中 capture 到一个词的上下文信息。同时,上面我们恰巧提到了统计语言模型正好具有捕捉上下文信息的能力。那么构建上下文与目标词之间的关系,最自然的一种思路就是使用语言模型。从历史上看,早期的词向量只是神经网络语言模型的副产品。
2001 年, Bengio 等人正式提出神经网络语言模型( Neural Network Language Model ,NNLM),该模型在学习语言模型的同时,也得到了词向量。所以请注意一点:词向量可以认为是神经网络训练语言模型的副产品。
神经网络语言模型与 word2vec
好了,到目前为止我们已经对的分布式表示以及词嵌入的概念的层级关系有了个理性的认识了,那这跟 word2vec 有什么联系?
1、神经网络语言模型
上面说,通过神经网络训练语言模型可以得到词向量,那么,究竟有哪些类型的神经网络语言模型呢?个人所知,大致有这么些个:
- Neural Network Language Model ,NNLM
- Log-Bilinear Language Model, LBL
- Recurrent Neural Network based Language Model,RNNLM
- Collobert 和 Weston 在 2008 年提出的 C&W 模型
- Mikolov 等人提出了 CBOW( Continuous Bagof-Words)和 Skip-gram 模型
到这,估计有人看到了两个熟悉的 term:CBOW、skip-gram,有看过 word2vec 的同学应该对此有所了解。我们继续。
- word2vec 与 CBOW、Skip-gram
现在我们正式引出最火热的另一个 term:word2vec。
上面提到的 5 个神经网络语言模型,只是个在逻辑概念上的东西,那么具体我们得通过设计将其实现出来,而实现 CBOW( Continuous Bagof-Words)和 Skip-gram 语言模型的工具正是 well-known word2vec!另外,C&W 模型的实现工具是 SENNA。
所以说,分布式词向量并不是 word2vec 的作者发明的,他只是提出了一种更快更好的方式来训练语言模型罢了。分别是:连续词袋模型 Continous Bag of Words Model(CBOW) 和 Skip-Gram Model,这两种都是可以训练出词向量的方法,再具体代码操作中可以只选择其一,不过据论文说 CBOW 要更快一些。
顺便说说这两个语言模型。统计语言模型 statistical language model 就是给你几个词,在这几个词出现的前提下来计算某个词出现的(事后)概率。CBOW 也是统计语言模型的一种,顾名思义就是根据某个词前面的 个词或者前后 个连续的词,来计算某个词出现的概率。Skip-Gram Model 相反,是根据某个词,然后分别计算它前后出现某几个词的各个概率。
以 “我爱北京天安门” 这句话为例。假设我们现在关注的词是 “爱”, 时它的上下文分别是 “我”,“北京天安门”。CBOW 模型就是把 “我” “北京天安门” 的 one hot 表示方式作为输入,也就是 个 1xV 的向量,分别跟同一个 VxN 的大小的系数矩阵 相乘得到 个 1xN 的隐藏层 hidden layer,然后 个取平均所以只算一个隐藏层。这个过程也被称为线性激活函数 (这也算激活函数?分明就是没有激活函数了)。然后再跟另一个 NxV 大小的系数矩阵 相乘得到 1xV 的输出层,这个输出层每个元素代表的就是词库里每个词的事后概率。输出层需要跟 ground truth 也就是 “爱” 的 one hot 形式做比较计算 loss。这里需要注意的就是 通常是一个很大的数比如几百万,计算起来相当费时间,除了 “爱” 那个位置的元素肯定要算在 loss 里面,word2vec 就用基于 huffman 编码的 Hierarchical softmax 筛选掉了一部分不可能的词,然后又用 nagetive samping 再去掉了一些负样本的词所以时间复杂度就从 变成了 。Skip gram 训练过程类似,只不过输入输出刚好相反。
补充下,Word embedding 的训练方法大致可以分为两类:一类是无监督或弱监督的预训练;一类是端对端(end to end)的有监督训练。无监督或弱监督的预训练以 word2vec 和 auto-encoder 为代表。这一类模型的特点是,不需要大量的人工标记样本就可以得到质量还不错的 embedding 向量。不过因为缺少了任务导向,可能和我们要解决的问题还有一定的距离。因此,我们往往会在得到预训练的 embedding 向量后,用少量人工标注的样本去 fine-tune 整个模型。
相比之下,端对端的有监督模型在最近几年里越来越受到人们的关注。与无监督模型相比,端对端的模型在结构上往往更加复杂。同时,也因为有着明确的任务导向,端对端模型学习到的 embedding 向量也往往更加准确。例如,通过一个 embedding 层和若干个卷积层连接而成的深度神经网络以实现对句子的情感分类,可以学习到语义更丰富的词向量表达。
- 对 word embedding 的理解
现在,词向量既能够降低维度,又能够 capture 到当前词在本句子中上下文的信息(表现为前后距离关系),那么我们对其用来表示语言句子词语作为 NN 的输入是非常自信与满意的。