当前位置: 首页 > >

NLP之BERT和GPT

发布时间:

NLP之BERT和GPT杂谈

我们介绍了好几种获取句子表征的方法,然而值得注意的是,我们并不是只对如何获取更好的句子表征感兴趣。


在评估他们各自模型性能的时候所采取的方法,回过头去进行梳理,发现,无论是稍早些的 InferSent,还是 2018 年提出的 Quick-thoughtsMulti-task Learning 获取通用句子表征的方法,他们无一例外都使用了同一种思路:将得到的句子表征,在新的分类任务上进行训练,而此时的模型一般都只用一个全连接层,然后接上softmax进行分类。


分类器足够简单,足够浅层,相比那些在这些分类任务上设计的足够复杂的模型来说简直不值一提。然而令人大跌眼镜的是,这些简单的分类器都能够比肩甚至超越他们各自时代的最好结果,这不能不说是个惊喜。而创造这些惊喜的背后功臣,就是迁移学*。更进一步地,迁移学*的本质,就是给爬上“巨人的肩膀”提供了一架结实的梯子。


在这些句子级别的任务中,属于 InferSentQuick-thoughts 这些模型的“巨人肩膀”便是他们各自使用的训练数据,迁移学*最后给他们搭了一个梯子。


2017 年,Salesforce 的 Bryan McCann 等人发表了一篇文章 Learned in Translation: Contextualized Word Vectors,论文首先用一个 Encoder-Decoder 框架在机器翻译的训练语料上进行预训练,而后用训练好的模型,只取其中的 Embedding 层和 Encoder 层,同时在一个新的任务上设计一个 task-specific 模型,再将原先预训练好的 Embedding 层和 Encoder 层的输出作为这个 task-specific 模型的输入,最终在新的任务场景下进行训练。


他们尝试了很多不同的任务,包括文本分类Question AnsweringNatural Language InferenceSQuAD 等,并在这些任务中,与 GloVe 作为模型的输入时候的效果进行比较。实验结果表明他们提出的** Context Vectors 在不同任务中都带来了不同程度效果的提升**。


注:


Global Vector融合了矩阵分解Latent Semantic Analysis (LSA)的全局统计信息和local context window优势。融入全局的先验统计信息,可以加快模型的训练速度,又可以控制词的相对权重。

可能是skip-gram,CBOW每次都是用一个窗口中的信息更新出新的词向量,但是Glove则是用了全局的信息(共线矩阵),也就是多个窗口进行更新

LSA虽然充分利用了统计信息,但在词语类比上没有好的表现。Word2vec在类比任务上有好的性能,但由于仅利用了分离的窗口训练而忽略了全局共现信息。而Glove模型的方法利用词共现矩阵充分利用了统计信息,高效地对语义进行编码。

整个模型通过不断优化这个损失函数来调整词向量,使得模型通过学*语料中的词频信息来捕捉语义信息。


ELMo


2018年的早些时候, AllenNLP的Matthew E.Peters等人在论文***Deep Contextualized word representations***(该论文同时被ICLR和NAACL接受,并且获得了NAACL最佳论文奖,可见其含金量)中首次提出了***ELMo***,其全称是 Embeddings from language Models,从名称上可以看出,ELMo为了利用无标记数据,使用了语言模型,


基本框架是一个双层的 Bi-LSTM,不过在第一层和第二层之间加入了一个残差结构(一般来说,残差结构能让训练过程更稳定)。做预训练的时候,ELMo 的训练目标函数为:


前后有两个概率,第一个概率是来自于正向的由左到右的 RNN 结构,在每一个时刻上的 RNN 输出(也就是这里的第二层 LSTM 输出),然后再接一个 Softmax 层将其变为概率含义,就自然得到了;与此类似,第二个概率来自反向的由右到左的 RNN 结构,每一个时刻 RNN 的输出经过 Softmax 层后也能得到一个概率大小,表示从某个词的下文推断该词的概率大小。


ELMo 的基本框架便是 2-stacked biLSTM + Residual 的结构,不过和普通 RNN 结构的不同之处在于,**ELMo 借鉴了 2016 年 Google Brain 的 Rafal Jozefowicz 等人发表的 Exploring the Limits of Language Modeling,其主要改进在于输入层和输出层不再是 word,而是变为了一个 char-based CNN 结构,ELMo 在输入层和输出层考虑了使用同样的这种结构.


在原论文中,把这种先经过CNN得到的词向量,然后再计算Softmax的方法叫做CNN Softmax.利用CNN解决有三点优势值得注意:


    CNN能减少普通做Softmax时全连接层中的必须要有的 |V|h 的参数规模,只需保持 CNN 内部的参数大小即可。一般来说,CNN 中的参数规模都要比 |V|h 的参数规模小得多;

    CNN 可以解决 OOV (Out-of-Vocabulary)问题,这个在翻译问题中尤其头疼;

    在预测阶段,CNN 对于每一个词向量的计算可以预先做好,更能够减轻 inference 阶段的计算压力。


普通 Softmax 在大词典上的计算压力,都是因为来自于这种方法需要把一个神经网络的输出通过全连接层映射为单个值(而每个类别需要一个映射一次。


一次 h 大小的计算规模,|V| 次映射便需要总共 |V|*h 这么多次的映射规模),对于每个类别的映射参数都不同,而 CNN Softmax 的好处就在于能够做到对于不同的词,映射参数都是共享的,这个共享便体现在使用的 CNN 中的参数都是同一套,从而大大减少参数的规模。


同样的,对于输入层,ELMo 也是用了一样的 CNN 结构,只不过参数不一样而已。和输出层中的分析类似,输入层中 CNN 的引入同样可以减少参数规模。不过 Exploring the Limits of Language Modeling 文中也指出了训练时间会略微增加,因为原来的 look-up 操作可以做到更快一些,对 OOV 问题也能够比较好的应对,从而把词典大小不再限定在一个固定的词典大小上。


最终 ELMo 的主要结构便如下图(b)所示,可见输入层和输出层都是一个 CNN,中间使用 Bi-LSTM 框架,至于具体细节便如上两张图中所示。




无论是基于传统统计的 N-gram 还是普通神经网络的 NNLM 结构,都会有一个很严重的问题,那就是计算复杂度随着上下文窗口 N 大小的增大急剧上升。其中 N-gram 是指数上升,NNLM 是以 |d| × N 的形式增加,|d| 是词向量的维度,虽然 NNLM 已经改观了很多,但依然是一个斜率很大的线性增加关系。


后来 CBOW 和 Skip-gram 以及再后来的 GloVe 终于做到了计算复杂度与所选窗口大小无关,只与词典大小和词向量维度相关。


不过需要指出的是,这里讨论的计算复杂度只是预测单个词的计算时间复杂度,如果是求整个输入序列的话,还是避免不了要与序列长度相关,在这一点上和下面要分析的 RNN 在横向的时间序列上有一个时间复杂度,其原因是一致的。


然而,在今天看来,无论 word2vec 中的模型、还是 GloVe 的模型,都过于简单,它们都受限于所使用的模型表征能力,某种意义上都只能得到比较偏上下文共现意义上的词向量,并且也很少考虑过词序对于词的意义的影响(比如 CBOW 从其名称来看就是一个 bag-of-words,在模型的输入中没有词序的概念)


2018 年初,这个也许在 NLP 历史上并没有多么显眼的年头,掀起了一阵不小的波澜,至少在 6 项 NLP 任务上横扫当时的最好结果,包括 SQuAD,SNLI,SRL,NER,Coref 和 SST-5


Transformer 里最为核心的机制是 Self-attention,正因为 Self-attention 的存在,才使得 Transformer 在做类似翻译问题的时候,可以让其 Encoder 不用做序列输入,而是将整个序列一次全输入,并且超长序列的输入也变得可能。而具体到 Self-attention 中,可以用下图表示:


2018 年 10 月 11 日,这似乎是个绝对*凡的日子。说句题外话,无独有偶,OpenAI 在其博客放出 GPT 的时间恰好不多不少是 4 个整月前,即 2018 年 6 月 11 日),然而 Google AI 的 Jacob Devlin 和他的合作者们悄悄地在 arXiv 上放上了他们的最新文章,名为 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding。


不过,为何 BERT 能如此引人注目,不妨来一探究竟。私以为,BERT 最主要的几个特征分别是:


利用了真双向的 Transformer;

为了利用双向信息,改进了普通语言模型成为完形填空式的 Mask-LM (Mask-Language Model);

利用 Next Sentence Prediction 任务学*句子级别信息;

进一步完善和扩展了 GPT 中设计的通用任务框架,使得 BERT 能够支持包括:句子对分类任务、单句子分类任务、阅读理解任务和序列标注任务。



除了用上 Mask-LM 的方法使得双向 Transformer 下的语言模型成为现实,BERT 还利用和借鉴了 Skip-thoughts 方法中的句子预测问题,来学*句子级别的语义关系。具体做法则是将两个句子组合成一个序列,组合方式会按照下面将要介绍的方式,然后让模型预测这两个句子是否为先后*邻的两个句子,也就是会把"Next Sentence Prediction"问题建模成为一个二分类问题。


最后,我们再次总结 BERT 的几个主要特点:


Transformer Encoder 因为有 Self-attention 机制,BERT 自带双向功能;

因为双向功能以及多层 Self-attention 机制的影响,使得 BERT 必须使用 Cloze 版的语言模型 Masked-LM 来完成 token 级别的预训练;

为了获取比词更高级别的句子级别语义表征,BERT 加入了 Next Sentence Prediction 来和 Masked-LM 一起做联合训练;

为了适配多任务下的迁移学*,BERT 设计了更通用的输入层和输出层。


然后,我们再来看看 BERT 都站在了哪些“巨人肩膀”上:


针对第一点,双向功能是 Transformer Encoder 自带的,因此这个“巨人肩膀”是 Transformer;

第二点中 Masked-LM 的巨人肩膀是语言模型、CBOW 以及 Cloze问题;

第三点中 Next Sentence Prediction 的“巨人肩膀”是 Skip-gram、Skip-thoughts 和 Quick-thoughts 等工作;

第四点中,对输入层和输出层的改造,借鉴了 T-DMCA 以及 GPT 的做法。


再来看看预训练使用的数据方面,ELMo 使用的是 1B Word Benchmark 数据集,词数为 10 亿,然而句子间的顺序是随机打乱的,无法建模句子级别的依赖关系,所以 GPT 和 BERT 都弃用这个数据集;GPT 使用的是 BooksCorpus,词数为 8 亿;BERT 除了使用 BooksCorpus 之外,还加入了 25 亿级别的 Wikipedia 数据集,因此整体使用的数据集为 33 亿个词。可见 BERT 使用的数据集是最大的。


模型方面,ELMo 使用的是一个 Bi-LSTM 结构,输入层和输出层使用 CNN 来进行建模。而 GPT 使用了 12 个 block,隐藏层节点数为 768,多头为 12,这也是 BERT 的 base 版本(base 版本就是为了跟 GPT 做对比),参数量按照 BERT base 版本估计为 110M。而 BERT 再次把模型变得更大了,使用 24 个 block,并且隐藏层节点数与多头都相应扩大,作者似乎想要表明他们设计的模型是有史以来最大的模型之一。


在计算资源比拼方面,GPT 在 8 块 GPU 上预训练了一个月。参数规模和 GPT 差不多的 BERT base 版本,在 16 块 TPU 上只花了 4 天,BERT 在论文中提到此处时,还不失时机给它们家的 TPU 放了个链接,打了一波广告。对于参数规模为 GPT 三倍之多的 BERT large 版本,在 64 块 TPU 上训练耗时也依然达到 4 天之久。


训练语言模型的优势在于:


*乎无限量的优质数据

无需人工标注

一次学*多次复用

学*到的表征可在多个任务中进行快速迁移


问题是如何利用这些训练好的模型,Google们已经给我们提供巨人的肩膀了,那“梯子”在哪呢?我们怎么爬上去这些“巨人肩膀”?也就是如何使用这些预训练好的模型。一般来说,可以有三种方式来使用。它们分别是:


    将预训练模型当作一个特征提取器,直接将预训练模型的输出层去掉,然后使用去掉输出层之后的最后一层输出作为特征,输入到我们自己精心设计好的Task-specific模型中去。在训练过程中,作为特征提取器的部分(比如BERT ENCODER)的参数是不变的。

    另外,特征提取器并不一定只能用最后一层的输出向量,也可以使用中间的某些层,甚至也可以借鉴 ELMo 的做法,在各层之间利用一个 softmax 来学*各自的权值,或者也可以尝试一些更为复杂的各层组合方式。

    将预训练模型整体接入Task-specific模型,继而重新在新的数据集上整体重新训练,当然训练技巧可以有很多种。

    除了 GLUE 外,GPT 额外刷过的数据集有 4 个:SNLI, SciTail, RACE 和 Stroy Cloze,其中 SNLI 和 SciTail 都是自然语言推断问题,本质上是一个句子级别的分类问题,RACE 和 Stroy Cloze是 QA 或阅读理解问题,本质上可以认为分别是一个 token 级别的分类以及句子级别的打分排序问题。


其流程是:从文本到语义表征,再从语义表征重新生成文本。这样看来,至少在 NLP 领域(CV 等其他 AI 领域,留给各位看官自行脑洞好了),未来大约还是很值得期待的一件事情。


闲话少叙,让我们开开脑洞,大言不惭的看看今后 NLP 的一些可能性。只不过我人微言轻,暂且幻想一下皇帝的金锄头吧。


一般来说,语言学流派大约可以分为五个流派:历史比较语言学、结构主义语言学、转换-生成语言学、系统功能语言学和认知语言学这五个大的学派,其中历史比较语言学年代比较久远了,注重搜集多种语言历史资料,通过对比归纳总结等等方法,进而理解语言的演化和发展历程,历史比较语言学的主要贡献在于它把语言学从其他学科里抽离出来成为一门独立的学科。


而结构主义语言学(大约兴起于20世纪20年代左右)的开山鼻祖索绪尔(同时他也是现代语言学之父),对于语言的理解,他有一个非常经典的类比,他认为语言就像是一盘象棋,棋盘上的每一个棋子都有特定的游戏规则,棋子只不过是这些特定游戏规则的一个实物标记而已,如果某天弄丢了某一个棋子,我们立马可以拿任何一个小物件来代替这个棋子的功能,只要游戏规则不变,那么棋局依然能够照常进行,棋子替换前后基本不会有任何差别。


索绪尔认为语言里的基本单位诸如词语*语等等都只不过是棋盘上的棋子(signifiant,能指),重要的不是棋子本身,而是棋子背后对应的一整套规则,也就是语言里的各种结构或约定俗称的指代或用法(signifié,所指)。象棋的整个规则便是我们所使用的一整套语言系统,比如象棋的规则便是我们的汉语,而国际象棋的规则便是英语,两种象棋各自使用的棋子各有不同,规则自然也有所区别。


到了 1957 年,乔姆斯基出版《句法结构》一书,标志着转换生成语言学的诞生。乔姆斯基的主要观点则认为人类天生有一套普遍语法,我们日常的语言系统只不过是这套普遍语法的形式化体现而已。


因此他认为语言中存在着深层结构和表层结构,深层结构与意义和概念相关,而表层结构则与语音和符号相关,这两层结构由一套转换语法连接起来,也就是由深层结构生成表层结构。他为此还特别举了一些例子,为了说明两个句子表层结构类似乃至完全一样,但是深层语义完全不相关的现象,比如:Flying planes can be dangerous.


这个句子可以因为同一份表层结构对应到两套不同的深层结构,而表达出完全不一样的意义,第一种是 flying 作为形容词,那么此时句子想表达的意义是在天上正在飞行的飞机很危险;而第二种是把"flying planes"解构成一种动宾结构,那么这个句子表达的意思就成了开飞机这个动作很危险。


乔姆斯基举这个例子,就是为了说明传统的结构主义语言学对于这种句子根本无能为力,因为它们的表层结构是完全一致的,从而得出语言有一种更为本质的深层结构的结论。


但是个人理解,与其说是语言学的深层结构,还不如说是人类认知体系或者客观世界的结构化表示,因为深层结构必然对应到人类的认知体系。并且乔姆斯基过于强调了普遍语法的天生性,而忽略了后天语言的塑造和*得。


后来乔姆斯基的众多弟子(乔治莱考夫等人)也公开宣判与自己老师乔姆斯基的语言学观点决裂,并各自独立发展出了一些新的语言学理论,比如乔治莱考夫的认知语言学流派。


而到了 20 世纪八九十年代,以韩礼德为代表的一些语言学家,逐渐注意到无论是结构主义还是转换生成语言学,它们都片面的强调语言学的理论形式,而忽视了语言的社会的功能属性,韩礼德认为这语言的结构和语法等等理论形式,以及社会功能属性是语言的两个方面,这二者都很重要,他想要把二者统一起来。


因此发展了他自己的语言学观点,他提出了系统语法和功能语法的概念,前者强调语言的内在结构和形式理论,这点和索绪尔的结构主义一脉相承,但他同时还提出了功能语法,着重语言的社会属性,说明语言是社会交流和沟通的媒介,不过由于在系统语法上的影响力远不如乔姆斯基等流派的影响力,功能语法的建树倒是别的流派所缺乏的,因此把韩礼德的学说就叫做系统功能语言学了。


而上文提到的乔姆斯基的弟子之一乔治莱考夫,认为他的老师对于人类天生具有普遍语法的观点是大错特错,尤其是转换生成语法中认为深层结构由一些有限的普遍语法组成,着重语言规则的形式化。


乔治莱考夫严厉抨击了他老师的观点,与转换生成语法着重形式和规则的探讨相反,认知语言学认为语言不是人类的一个独立系统,人类的一切语言行为都只不过是人类对于客观世界和精神世界亲身体验的外化,也就是说,语言无论把它叫做符号也好,叫做语法结构也好,叫做系统也好,都逃离不了语言是人类认知系统的一部分,语言并不独立存在。


然而回到当下的自然语言处理,似乎现在谈认知,有点为时尚早。在自然语言处理的发展历程中,除了乔姆斯基的转换生成语言学曾经在上世纪六七十年代大放异彩,一度成为当时自然语言处理的主流方法,除此之外,似乎理论语言学界一直和自然语言处理脱钩比较严重,这一方面揭示了人类语言系统的复杂,另一方面,也预示着现在的自然语言处理缺乏严密的理论支持。


说白了,现在的 NLP 界,尤其以 BERT 为代表的做法,实际上是简单粗暴的代名词,它们把人类语言*得过程中的轻量、泛化和低功耗,用大数据、大模型和大计算量炮轰的荡然无存。


站在眼力所及之处的满目疮痍上,我们依然无法让机器真正明白“喵星人”这个词对于人类而言,其背后究竟意味着一个怎样的复杂情绪和体验(更有趣的是,即便对于每个人类个体而言,其背后的体验也是千差万别的,可见语言笼阔了符号性、认知性、社会性和个体性之后的复杂程度)。


然而在身后留下一片废墟和尸骨的 BERT,正准备重建一个伟大新帝国的 BERT,它究竟是要选择开心呢还是难过?对于人类母亲而言,这大概会是个问题。


不过无论如何,帝国的建立总是艰难的。让人类母亲足可欣慰的是,即便步履维艰,托儿所里的 AI 儿子们依然一步一步坚定的踩上了简陋的梯子。


站在巨人的肩膀上回首,我们发现,和人类母亲的语言*得方式依靠某一个机缘巧合的基因突变不同,AI 踏出了一条只属于它自己的路,未来的巨人肩膀和梯子在哪里,我们是否需要选用新的巨人肩膀和梯子,这都是成长的必经之痛,一切都留给未来去证实或证伪吧。


人类在长期的自然演化中,形成了一套自己独有的认知系统,而通过这套认知系统,人类可以获得对于身边客观环境以及自己内部精神世界的一套独特体验,这套体验如果映射到外在的语音或文上,便形成了我们人类的语言系统。因此人类的语言与人类其他认知能力没有本质上的区别。


不过,认知语言学并没有一味地架空自己的语言学观念,它也适时地道出了语法规则和人类的认知系统有一定的对应性,言下之意便是说语法规则是人类认知系统抽象化的外在体现。


可以看出,在这一点上,认知语言学比转换生成语言学又更进了一步,直接从研究人类的认知角度来研究人类的语言学。乔治莱考夫在语言学中引入了隐喻的概念,认为隐喻是人类最重要的认知活动之一,也是语言中最普遍的现象。



友情链接: