赞
踩
当前,自然语言处理(Natural Language Processing,NLP)技术的发展可谓日新月异,尤其是近些年来层出不穷的预训练模型及其变体更是让人眼花缭乱。对于想要踏入这一领域并想深入了解的人——比如我——来说,可能会想要搞清楚这门技术是如何发展成现在这个样子的,这其中又经历了怎样的波折。
前一段时间,我把NLP技术的发展史做了简略的梳理,并在内部做了分享,现将分享的内容以图文方式整理出来,希望可以帮助那些有困惑的同仁。
本文所有的图片来自网络,主要参考文献为吴军的《数学之美》。
谈论NLP,首先需要从「语言」入手。今天,世界上已查明的语言超过5000种,这些语言支撑着人们的日常交流与工作沟通。毫不夸张地说,正是语言的出现,才使得人类得以进化成比其他动物更高级的存在。
本质上来说,语言主要作用就是承载信息。这是一卷现收藏于大英博物馆的名为《亚尼的死者之书》的长卷。根据考古结论,它距今约3300年,比中国目前发现的最早的甲骨文还略微早些。这轴长卷是绘制在纸莎草上的,长约20米,共有60多幅绘画故事和象形文字说明,用于记载当时古埃及人认为的人死之后的事情。所谓「死者之书」,可以简单理解为死者去往另一个世界的通行证。
毫无疑问,古埃及的「死者之书」试图通过绘画和象形文字来记载人在死后的经历和行为,这与现代人使用语言的目的是毫无二致的。
其核心模型可以简化成如图所示的内容,即:信息的发送人把想要发送的信息通过一种编码方式(绘画、文字、声音等)进行编码,被编码后的信息通过信道传给接收人,接收人对其进行解码从而获取信息的内容。
古埃及人用的编码方式是绘画和象形文字,得益于计算机技术的发展,今天我们已经可以使用数字来对文字进行编码,其传输效率自然高得多,但本质上与几千年前并没什么不同。
搞清楚语言的本质和目的,我们先宏观看一下NLP技术的发展历史。
可以粗略的将NLP技术的发展分为四个阶段,我对应地使用了四个词来形容它们,分别是:缘起、探索、重生、飞跃。
缘起: 人们一般认为,1950年,计算机科学之父阿兰图灵发表的《计算的及其与智能》文章,标志着NLP技术的开始。这篇文章最重要的价值之一,就是提出了一种后来被称为「图灵测试」的试验。通过图灵测试,人们可以判断一个机器是否具有了智能。
探索: 从1950年开始一直到20世纪70年代,人们一直受直觉启发(现在来看,称之为「误导」或许更加准确),试图用电脑模拟人脑的方式来研究NLP技术,这种方法后来被称为“鸟飞派”,本意是指试图通过仿生学的研究来让人类飞上天空的那批人所采取的方法,后来延伸为受直觉影响,在惯性思维的误导下而采取的不正确的研发方法。
重生: 1970年以后,以贾里尼克为首的IBM科学家们采用了统计的方法来解决语音识别的问题,最终使准确率有了质的提升。至此,人们才纷纷意识到原来的方法可能是行不通的,采用统计的方法才是一条准确的路。
飞跃: 在确定了以统计学方法为解决NLP问题的“主武器”后,再加上计算能力的提升,有了深度学习技术加持的NLP也迎来的其飞速发展的阶段,在某些任务上的表现甚至已经超过人类。
所谓「图灵测试」,简而言之就是把一个人和一个机器关在两个房间了,另外一个人来对他(它)提问相同的问题。如果提问者通过得到的答案无法区分哪个是人哪个是机器的话,那么就可以认为机器通过了测试,具有了“智能”。
为什么说图灵测试的提出是NLP发展的起点呢?因为要想避免非智能决定因素的影响,提问者不能通过声音来提问,而是通过类似写纸条的方式;而且,得到的答案也必须是采用类似于写在打印纸上等方式来传递给提问者。这样,机器要想正确回答问题,首先就需要去“理解”提问者的问题。
在NLP出现后的前20年,人们一直在用惯性思维的方式去研究相关问题。举个例子,要翻译一篇文章,人会怎么做?公认的一个前提是,翻译者必须对两种语言都很熟悉才可以。于是,人们认为,机器要具备翻译的能力,也必须先理解两种语言才行。
这就是典型的「鸟飞派」方法,即受惯性思维的影响而做出的决定。
从早期人们对NLP的理解的结构图中可以看出,这与人类在学习语言的路径几乎是一样的:先学很多单词,然后是句法结构,然后才能理解句子的含义,最后才能基于这些语言去完成相应的任务。
事实上,这种方法的第一步就遇到了一个不可克服的障碍。
拿句法分析而言,机器想要记住自然语言的句法结构,需要语言学家首先将句子按照人类的理解进行句法拆分,然后处理成机器能够存储的格式。如果人类语言非常简单且数量不多,这种方法倒还可行,可惜,以上两个条件没有一个是满足的。
以图中的例子来看,如此简单的一个陈述句,还必须拆分成八条规则才能让机器进行处理,而且,这些规则中的绝大部分都是需要人工编写的。由此可知,要解决实际问题,所需要花费的人工成本就太高了。此外,一词多义、一义多词等现象,也会导致规则出现矛盾。
传统的人工构建规则模板之路看样子是行不通了,于是,一些聪明人开始找寻其他的方向,并发现了统计学这一处理自然语言的利器。
提到统计自然语言处理,就不得不提一下贾里尼克。正是因为他和他的团队在上世纪70年代的工作,开拓了统计自然语言处理的先河。他不仅是世界著名的自然语言处理专家,而且还培养出了一大批世界一流的自然语言处理学者。值得一提的是,他真正地工作到了生命的最后一刻,最后是在实验室突发急病去世的。
现在,人们发现,基于统计的自然语言处理的方法,从模型上看,和语言的初衷——通信,是完全一致的。关于这一点,我们在后面介绍统计模型的时候来阐述。
我们前面已经说过,自然语言的最显著的特性,就是其具有上下文相关性。传统的方法之所以效果不好,很大程度上是因为没有办法处理这种上下文相关性。而基于统计的自然语言处理,或者说,统计语言模型,就是利用统计学的方法,来建立自然语言模型。
我们在小学语文考试的时候,经常会遇到一类题:给你一组乱序的词语,让你组成一句通顺的话。假设给定如图中所示的一组词语,那么大家能组成什么样的话呢?我这里给出两种组合的方法,相信大家比较这两个句子就能发现,
s
1
s_1
s1比
s
2
s_2
s2更好。这里说的「好」,意思就是通顺,那么如何用数学的方法来表示
s
1
s_1
s1比
s
2
s_2
s2更通顺呢?
回到「通顺」这个描述本身。我们为什么会觉得 s 1 s_1 s1比 s 2 s_2 s2通顺,其实就是因为 s 1 s_1 s1的表达方式更接近于我们的常识,也就是说,句子 s 1 s_1 s1体现的这种词语组合方式比包含 s 2 s_2 s2在内的其他的组合方式出现的概率更大。
至此,我们已经得到统计语言模型中最精髓的一句话。基于此,贾里尼克假设,一个句子是否合理,取决于其出现在自然语言中的可能性的大小。越常见的句子越合理,这是不争的事实。
接下来,我们就会涉及一些简单的数学推导。只要是学过高等数学和概率统计的基本知识,理解起来都是没有任何问题的。
假设
S
S
S表示一个句子,本质上它就是由一定数量的词语按照特定顺序排列好的字符串而已。假定这个字符串用
w
1
,
w
2
,
.
.
.
,
w
n
w_1,w_2,...,w_n
w1,w2,...,wn表示,那么,判断
S
S
S是否合理,就变成了判断字符串
w
1
,
w
2
,
.
.
.
,
w
n
w_1,w_2,...,w_n
w1,w2,...,wn出现的概率。
要想得到最真实的概率值,办法只有一个,那就是统计人类有文字以来的所有的句子,自然就可以得到 S S S的概率。但实际上,这个办法只是理论上可行,实际上没人做得到。
于是,我们只能想办法来近似,即,牺牲一点精度,来换取一种切实可行的方法。只要精度损失不大,那么这种牺牲是可以接受的。这里用到的统计方法主要有条件概率公式和马尔科夫假设。通过这两步,我们就得到了以下近似:
P ( w 1 , w 2 , . . . , w n ) ≈ P ( w 1 ) P ( w 2 ∣ w 1 ) . . . P ( w n ∣ w n − 1 ) ) P(w_1,w_2,...,w_n)\approx P(w_1)P(w_2|w_1)...P(w_n|w_{n-1})) P(w1,w2,...,wn)≈P(w1)P(w2∣w1)...P(wn∣wn−1))
这里得到的这个近似,被称为二元模型(bigram model),它假定每个词出现在特定位置的概率只和它的上一个词(按照目前大多数语言的书写习惯,就是指左侧那个词)有关。
于是,你可以猜到,一元模型(每个词出现的概率只与它本身有关,即完全不考虑上下文信息)、三元模型(每个词出现的概率与它前两个词有关)以及更多元的模型分别是什么样子的。
按照二元模型的近似,求一个句子的概率变成了求有限个条件概率的乘积。根据条件概率的定义可知,计算一个条件概率,只需要计算一个联合概率以及一个边缘概率即可。在这个例子里,联合概率为两个词组成的词对在语料库中出现的概率,而边缘概率就更简单了,是一个词在语料库中的概率。
这里又可以利用大数定律来用频率近似代替概率,经过约分,最终,求一个条件概率简化成了一项数数的工作。
至此,我们通过一系列统计理论和假设,先把一个自然语言问题抽象成了一个求概率的问题,又把概率问题简化成一个数数的操作,从而使复杂的问题变得可解。
这就是数学的力量。
上面我们已经找到了一条解决问题的道路,但这条路上仍然许多会让我们行走得磕磕绊绊的障碍必须被剔除,其中,最具有代表性的就是「零概率问题」。
在解决这个问题前,我们先看一下问题为什么会出现。
通过前面的分析可知,模型的训练其实就是计算所有条件概率的过程——计算到了任意两个词的条件概率,那么就可以得到任意一个字符串(句子)出现的概率。
在我们采用了大数定律把求概率变成数数的时候,这里有一个潜在的问题:如果分子为0,即特定组合的词对在语料库中没有出现,这时候是否可以认为该条件概率为0,进而整个字符串(句子)出现的概率也为0?
直觉上,得到这样的结论肯定是不妥的,而不妥的原因,就是「统计不可靠」。关于统计不可靠,一个耳熟能详的例子就是抛硬币试验,假设你抛了三次,硬币都是正面朝上,那么你得出这枚硬币是不均匀的结论显然是不能让人信服的。因为你试验的次数太少了。
同理,特定组合的词对没有出现,不一定是因为这种组合不存在,而更可能是因为你的语料库太小了,导致没有涵盖所有的可能。
明白了上述原因,解决方案也自然出现了:增大数据量,这里就是语料库的规模。然而,通过简单的计算你就会发现,增大数据量在这个场景下所起到的作用,似乎并不是很大。
假设汉语的词汇共有20万个,如果我要构建一个三元模型,那么参数的总量就是 20000 0 3 200000^3 2000003(参数即所有可能的条件概率,由于每个位置上可能出现的词的数量都是20万,三元模型的参数量就是20万的三次方),这个数字的量级是 1 0 15 10^{15} 1015。再假设整个互联网上有100亿个网页,每个网页上平均有1000个词(这是一种很宽的假设,很多网站达不到这个标准),那么互联网上的词的总量也才 1 0 13 10^{13} 1013个,考虑到三元模型用到的都是双词词对和三词词对,可利用的词对总量也才 2 ∗ 1 0 13 2*10^{13} 2∗1013,远小于参数量。
既然单纯的增大数据量的方式行不通,那么就要另谋出路。当一条路行不通时,就要思考一下问题出现的根本原因是什么。
在这个场景下,问题出现的根本原始是:由于语料库的限制,导致未出现的词(词对)的概率被认为是零。
这里又有一个隐含的信息在里面:未出现的词,其概率一定是零吗?很显然不是这样。举一个极端一些的例子,假如你的语料库取自小学生语文课本,那么肯定不会出现高中生物中的一些词汇。
由于我们总是受到语料库规模的限制,因此,不应该把未出现的词的概率简单地视为0,而是要给它们一个概率值。这个概率值怎么给呢?前人已经给出了一种解决方案,即“古德-图灵”估计。
图灵就是前面提到的计算机科学之父,古德是他的学生。他们提出的这个方法的整体思路是:把看见的事件的概率总量分出一部分,给那些未看见的(即,未出现的)的事件。划分的原则就是,已看见的事件中概率越低的,调给未看见时间的概率越多。
这和我们想的可能不一样,我们总是认为应该“杀富济贫”,但在这个问题中,那些概率更低的事件意味着更高的不可靠性,因此,需要从这种不可靠中分出一部分给那些看不见的事件。
反正你本身就已经很不可靠了,总不介意更加不可靠一些。
上一页讲了古德图灵估计的思想,事实上他们还给出了具体的实施方式,即,如何调低那些已观测到的事件的概率。
前面粗略地对统计语言模型的发展进行了简单的梳理,虽然这确实是NLP发展的一次飞跃,但细心的人肯定马上就发现问题:利用n元模型来处理自然语言,也只是处理邻接词的依赖关系,无法处理自然语言的长程依赖。
不过,得益于深度学习技术的发展,它在很大程度上密度了统计语言模型的上述短板。
总结来说,前面提到的统计语言模型技术面临以下问题:
1、采用独热向量的方式来对句子进行编码,无法衡量各个词之间的语义相似度,且在面对大规模词表时还会出现数据稀疏的问题。
2、n元模型实际上也是一种提取句子特征的特征模板,因此它也具有所有依赖特征模板的机器学习方法的弊端:效果非常依赖人工设置的模板的好坏。
3、很多下游的NLP任务,如实体抽取、关系抽取等,是依赖于上游的任务——分词、词性标注——成果的,因此,如果前面没做好,后面会受到很大的影响。
为了解决上述问题,人们采用了深度学习技术。
词向量,或者叫词嵌入,就是一种用来进行词表示的技术,它克服了传统方法所面临的数据稀疏、语义特征丢失的问题。简而言之,这种方法把每个词表示成了一个特定长度(如50、300)的向量,这样做有两个显而易见的好处:1、向量的维度固定,不因词表的规模而变化;2、利用向量计算,可以近似代替词语间的语义相关性。
对于第2点,一个非常典型的例子如图所示:king的词向量减掉man的词向量再加上woman的词向量,近似等于queen的词向量。
词向量的发展过程,大概如图中所示。一开始词向量其实只是作为神经语言模型的副产品,而且受限于当时的硬件条件,效果并不是很好。
后来,专门针对词向量训练的模型与方法被不断提出,且计算能力的不断提升,这些都是词向量技术不断发展的催动力。
在对深度学习技术的利用上,相较于NLP,计算机视觉技术是走在前列的。由于卷积神经网络在计算机视觉领域取得了里程碑式的巨大成功,NLP领域的学者们首先想到的就是利用CNN来处理自然语言,也取得了一些不错的成果。但真正让深度学习技术在NLP领域大放光彩的,还要属下一页的模型。
我们前面说,统计语言模型无法捕获自然语言的长程依赖。事实上,卷积神经网络在这一点上做得也不够好。于是,人们提出了新的网络模型,循环神经网络——RNN。
实际上,有许多RNN的变种神经网络被提出,来解决各种问题。比较出名的,有GRU和LSTM。
目前,NLP中大量应用的模型多为seq2seq架构的,即,sequence to sequence。翻译为序列到序列。以中英翻译模型为例,输入为中文字符序列,输出为英文字符序列,因此,称之为序列到序列的模型。
此类模型借鉴了编码器-解码器的思想,即对输入的序列进行编码,获取序列本身所包含的语义信息,然后利用解码器根据输入的语义信息进行解码,获取目标结果。
了解计算机视觉的人应该会理解,如果不加任何干涉,计算机在处理图片数据时,会逐像素点进行计算,事实上这在某些情况下是一种浪费。我们人类在观察图片时,一定先被某些元素吸引,从而给与它们更多的关注多。
图中右侧的图片显示了人们在看到左侧的图片时,注意力所放的位置。颜色越浅,表明关注度越多。这种注意力机制对于人们去了解一个事务的概况,是有非常大的帮助的。受此启发,人们在NLP领域也研究出了各种各样的注意力机制。
它们的核心都是,试图想让模型在完成一项NLP任务时,更多地关注那些对完成这项任务有所帮助的信息,而非视全部字符为同等重要的。
我们前面说,注意力机制是一种思想,而基于这种思想所实现的具体计算模型,可以有很多种,其中,比较有代表性的,self-attention可以算一种。基于self-attention的Transformer,更是大名鼎鼎:它是BERT的基础。
RNN以及类RNN模型,由于引入了时间步的操作,因此,它们必须等待上一步的操作结果才能进行下一步的计算,这就导致了它们的并行化计算很难实现。而Transformer模型,试图仅用注意力机制来捕获输入和输出之间的关系,从而使得整个架构更加并行化。
接下来,我们要介绍预训练模型,这是目前NLP领域的效果最好的模型。
一词多义问题,是自然语言中一个非常常见的现象,也是NLP领域的难点之一。我们前面提到的词向量,由于一个词只映射到了一个固定的词向量,因此,假如这个词是多义词,那么上述方法很明显丢失了其他的语义。为了解决这个问题,ELMo模型提出了一种思想:事先利用模型得到一个单词的词向量,这时,一词只有一义;在具体要利用这个词向量的时候,就要根据这个词所在的上下文的语义来调整该词的向量表示。经过调整后的词向量,能够更加适应其所在的语义环境。
上述过程其实已经体现了预训练方法的核心思想:预先训练一个模型,然后根据具体的任务对模型进行微调。
熟悉预训练模型的人,一定不会对BERT感到陌生。实际上,GPT1比BERT还要早一些,但是提出GPT1的公司的宣传能力,显然相较于Google要逊色了许多,以致于人们“只知有BERT,无论GPT1”
最后,来看一张比较让人绝望的图:各模型的参数量对比。尽管不是严格的线性关系,但仍然可以看出,NLP模型的规模是随着其发展而不断增加的。GPT3的参数量甚至达到了恐怖的1750亿!训练一次的成本高达上百万美元!
这对于个人研究者来说,无疑是绝望的:很少有人或者小公司能够负担的其这么庞大的研究成本。NLP也越来越成为巨头公司的专享游戏了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。