夕小瑶作者

NLP的游戏规则从此改写?从word2vec, ELMo到BERT

前言

还记得不久之前的机器阅读理解领域,微软和阿里在SQuAD上分别以R-Net+和SLQA超过人类,百度在MS MARCO上凭借V-Net霸榜并在BLEU上超过人类。这些网络可以说一个比一个复杂,似乎“如何设计出一个更work的task-specific的网络"变成了NLP领域政治正确的研究方向。而在这种风向下,不管word2vec也好,glove也好,fasttext也好,都只能充当一个锦上添花的作用。说好的迁移学习、预训练呢?在NLP似乎始终没成主角。

小夕写这篇文章时也有点惭愧,搞了好一段时间的表示与迁移,虽然早在直觉上感觉这应该是NLP的核心问题,但是也没做出一些令自己满意的实验结果,直到几天前的BERT出来,才感觉是贫穷限制了我的想象力╮( ̄▽ ̄””)╭(划掉),才感觉自己着眼的点还是太窄了。

每个人对于BERT的理解都不一样,本文就试着从word2vec和ELMo的角度说说BERT。下面先简单回顾一下word2vec和ELMo中的精华,已经理解很透彻的小伙伴可以快速下拉到BERT章节啦。

word2vec

来也都是些俗套而乐此不疲一遍遍写的句子,2013年Google的word2vec一出,让NLP各个领域遍地开花,一时间好像不用上预训练的词向量都不好意思写论文了。而word2vec是什么呢?

模型

显然就是一个“线性”语言模型。既然我们的目标是学习词向量,而且词向量在语义上要支持一些”线性的语义运算“,如”皇帝-皇后=男-女“(忽略武则天),那么使用一个线性模型自然足够了,跑的又快又能完成任务,非常优雅。

另外word2vec的一个精髓是把语言模型的那一套softmax加速方法也给顺便优化了,用一个看似开脑洞的“负采样”方法来代替传统的层级softmax和NCE做法。而这个名字高大上的“负采样”到底是什么呢?

负采样

我们知道对于训练语言模型来说,softmax层非常难算,毕竟你要预测的是当前位置是哪个词,那么这个类别数就等同于词典规模,因此动辄几万几十万的类别数,算softmax函数当然很费力啦。但是,如果我们的目标不在于训练一个精准的语言模型,而只是为了训练得到语言模型的副产物-词向量,那么其实只需要用这里隐含的一个计算代价更小的“子任务”就好啦。

想一想,给你10000张写有数字的卡片,让你找出其中的最大值,是不是特别费力?但是如果把里面的最大值事先抽出来,跟五张随机抽取的卡片混到一起,让你选出其中的最大值,是不是就容易多啦?

负采样就是这个思想,即不直接让模型从整个词表找最可能的词了,而是直接给定这个词(即正例)和几个随机采样的噪声词(即采样出来的负例),只要模型能从这里面找出正确的词就认为完成目标啦。所以这个想法对应的目标函数即:

这里是正例,是随机采样出来的负例(采样k个),是sigmoid函数。然后即最大化正例的似然,最小化负例的似然。

这种负采样的思想被成功的应用在了BERT模型中,只不过粒度从词变成了句子。不要急,慢慢往后看~

char-level与上下文

虽然2015年到2017年也有不少工作试图从char-level入手,另辟蹊径,摆脱预训练词向量的游戏规则,然而实测只是昙花一现,很快被怼了[8][9]。不过,人们同时也意识到了char-level的文本中也蕴含了一些word-level的文本所难以描述的模式,因此一方面出现了可以学习到char-level特征的词向量FastText[5],另一方面在有监督任务中开始通过浅层CNN、HIghwayNet、RNN等网络引入char-level文本的表示。

不过,至此为止,词向量都是上下文无关的。也就是说,同一个词在不同的语境中总是相同的词向量,很明显这就导致词向量模型缺乏词义消歧(WSD)的能力。于是,人们为了让词向量变得上下文相关,开始在具体的下游任务中基于词向量sequence来做encoding。

最常见的encoding方法当然就是用RNN系的网络,除此之外还有成功的用深层CNN来encoding的工作(如文本分类[6],机器翻译[7],机器阅读理解[4]),然!而!Google说了,CNN也太俗了,我们要用全连接网络!(划掉)self-attention!于是就有了为NLP深度定制的Transformer模型[11],Transformer的提出是在机器翻译任务上,但是其在其他领域如检索式对话[3]上也发挥了巨大的威力。

不过,既然发现在各个NLP任务中基本都有encoding的需要,那么为啥不在最开始就让词向量拥有上下文相关的能力呢?于是有了ELMo[2]。

ELMo

当然,实际上ELMo不是第一个试图产生上下文相关的词向量的模型,不过确是一个让你有充分理由放弃word2vec的模型(手动微笑),毕竟牺牲点推理速度换来辣么多的性能提升,大部分情况下超值呀~ELMo在模型层上就是一个stacked bi-lstm(严格来说是训练了两个单向的stacked lstm),所以当然有不错的encoding能力。同时其源码实现上也支持用Highway Net或者CNN来额外引入char-level encoding。训练它的话自然也是语言模型标准的最大化似然函数,即

不过这个ELMo的亮点当然不在于模型层,而是其通过实验间接说明了在多层的RNN中,不同层学到的特征其实是有差异的,因此ELMo提出在预训练完成并迁移到下游NLP任务中时,要为原始词向量层和每一层RNN的隐层都设置一个可训练参数,这些参数通过softmax层归一化后乘到其相应的层上并求和便起到了weighting的作用,然后对“加权和”得到的词向量再通过一个参数来进行词向量整体的scaling以更好的适应下游任务。

ps:其实最后这个参数还是非常重要的,比如word2vec中,一般来说cbow和sg学出来的词向量方差差异比较大,这时那个方差跟适合下游任务后续层方差匹配的词向量就收敛更快,更容易有更好的表现

数学表达式如下

其中L=2就是ELMo论文中的设定,j=0时代表原始词向量层,j=1是lstm的第一隐层,j=2是第二隐层。参数被softmax归一化之后的结果(也就是说)。

通过这样的迁移策略,那些对词义消歧有需求的任务就更容易通过训练给第二隐层一个很大的权重,而对词性、句法有明显需求的任务则可能对第一隐层的参数学习到比较大的值(实验结论)。总之,这样便得到了一份”可以被下游任务定制“的特征更为丰富的词向量,效果比word2vec好得多也就不足为奇了。

不过话说回来,ELMo的目标也仅仅是学习到上下文相关的、更强大的词向量,其目的依然是为下游任务提供一个扎实的根基,还没有想要弑君称王的意思

而我们知道,仅仅是对文本进行充分而强大的encoding(即得到每个词位非常精准丰富的特征)是远不够覆盖所有NLP任务的。在QA、机器阅读理解(MRC)、自然语言推理(NLI)、对话等任务中,还有很多更复杂的模式需要捕捉,比如句间关系。为此,下游任务中的网络会加入各种花式attention(参考NLI、MRC、Chatbot中的SOTA们)。

而随着捕捉更多神奇模式的需要,研究者们为每个下游任务定制出各种各样的网络结构,导致同一个模型,稍微一换任务就挂掉了,甚至在同一个任务的情况下换另一种分布的数据集都会出现显著的性能损失,这显然不符合人类的语言行为呀~要知道人类的generalization能力是非常强的,这就说明,或许现在整个NLP的发展轨迹就是错的,尤其是在SQuAD的带领下,穷尽各种trick和花式结构去刷榜,真正之于NLP的意义多大呢?

好像扯远了,不过所幸,这条越走越偏的道路终于被一个模型shutdown了,那就是几天前Google发布的Bidirectional Encoder Representations from Transformers (BERT)[1].

BERT

这篇paper的最重要意义不在于用了什么模型,也不在于怎么训练的,而是它提出一种全新的游戏规则。

开始游戏之前,先帮小夕点一下小广告好不好呀\(//∇//)\

像之前说的,为每个NLP任务去深度定制泛化能力极差的复杂模型结构其实是非常不明智的,走偏了方向的。既然ELMo相比word2vec会有这么大的提升,这就说明预训练模型的潜力远不止为下游任务提供一份精准的词向量,所以我们可不可以直接预训练一个龙骨级的模型呢?如果它里面已经充分的描述了字符级、词级、句子级甚至句间关系的特征,那么在不同的NLP任务中,只需要去为任务定制一个非常轻量级的输出层(比如一个单层MLP)就好了,毕竟模型骨架都已经做好了嘛。

BERT正是做了这件事情,或者说,它真的把这件事情做成了,它作为一个general的龙骨级模型轻松的挑战了11个任务上的深度定制的模型。。。

所以它怎么完成的呢?

深层双向的encoding

首先,它指出,对上下文相关的词向量的学习上,先前的预训练模型还不够!虽然在下游有监督任务中,encoding的方式已经是花里胡哨非常充分了,深度双向encoding基本成了许多复杂下游任务的标配(比如MRC, dialogue)。但是在预训练模型上,先前的最先进模型也只是基于传统的语言模型来做,而传统的语言模型是单向的(数学上已经定义了),即

而且往往都很浅(想象一下LSTM堆三层就train不动了,就要上各种trick了),比如ELMo。

另外,虽然ELMo有用双向RNN来做encoding,但是这两个方向的RNN其实是分开训练的,只是在最后在loss层做了个简单相加。这样就导致对于每个方向上的单词来说,在被encoding的时候始终是看不到它另一侧的单词的。而显然句子中有的单词的语义会同时依赖于它左右两侧的某些词,仅仅从单方向做encoding是不能描述清楚的。

那么为什么不像下游监督任务中那样做真正的双向encoding呢?

原因一想就很清楚了,毕竟传统的语言模型是以预测下一个词为训练目标的,然而如果做了双向encoding的话,那不就表示要预测的词已经看到了嘛╮( ̄▽ ̄””)╭这样的预测当然没有意义了。所以,在BERT中,提出了使用一种新的任务来训练监督任务中的那种真正可以双向encoding的模型,这个任务称为Masked Language Model (Masked LM)。

Masked LM

顾名思义,Masked LM就是说,我们不是像传统LM那样给定已经出现过的词,去预测下一个词,而是直接把整个句子的一部分词(随机选择)盖住(make it masked),这样模型不就可以放心的去做双向encoding了嘛,然后就可以放心的让模型去预测这些盖住的词是啥。这个任务其实最开始叫做cloze test(大概翻译成“完形填空测试”)。

这样显然会导致一些小问题。这样虽然可以放心的双向encoding了,但是这样在encoding时把这些盖住的标记也给encoding进去了╮( ̄▽ ̄””)╭而这些mask标记在下游任务中是不存在的呀。。。那怎么办呢?对此,为了尽可能的把模型调教的忽略这些标记的影响,作者通过如下方式来告诉模型“这些是噪声是噪声!靠不住的!忽略它们吧!”,对于一个被盖住的单词:

  • 有80%的概率用“[mask]”标记来替换

  • 有10%的概率用随机采样的一个单词来替换

  • 有10%的概率不做替换(虽然不做替换,但是还是要预测哈)

Encoder

在encoder的选择上,作者并没有用烂大街的bi-lstm,而是使用了可以做的更深、具有更好并行性的Transformer encoder来做。这样每个词位的词都可以无视方向和距离的直接把句子中的每个词都有机会encoding进来。另一方面我主观的感觉Transformer相比lstm更容易免受mask标记的影响,毕竟self-attention的过程完全可以把mask标记针对性的削弱匹配权重,但是lstm中的输入门是如何看待mask标记的那就不得而知了。

等下,小夕在之前的文章中也说过了,直接用Transformer encoder显然不就丢失位置信息了嘛?难道作者这里也像Transformer原论文中那样搞了个让人怕怕的sin、cos函数编码位置?并木有,作者这里很简单粗暴的直接去训练了一个position embedding ╮( ̄▽ ̄””)╭ 这里就是说,比如我把句子截断到50的长度,那么我们就有50个位置嘛,所以就有50个表征位置的单词,即从位置0一直到位置49。。。然后给每个位置词一个随机初始化的词向量,再随他们训练去吧(很想说这特喵的也能work?太简单粗暴了吧。。。)。另外,position embedding和word embedding的结合方式上,BERT里选择了直接相加。

最后,在深度方面,最终BERT完全版的encoder丧心病狂的叠加了24层的multi-head attention block(要知道对话里的SOTA模型DAM也才用了5层…)。。。而且每个block包含16抽头、1024隐单元╮( ̄▽ ̄””)╭此处打出标语:money is all you need (划掉)

学习句子与句对关系表示

像之前说的,在很多任务中,仅仅靠encoding是不足以完成任务的(这个只是学到了一堆token级的特征),还需要捕捉一些句子级的模式,来完成SLI、QA、dialogue等需要句子表示、句间交互与匹配的任务。对此,BERT又引入了另一个极其重要却又极其轻量级的任务,来试图把这种模式也学习到。

句子级负采样

还记得小夕在前面word2vec章节说过的,word2vec的一个精髓是引入了一个优雅的负采样任务来学习词向量(word-level representation)嘛。那么如果我们把这个负采样的过程给generalize到sentence-level呢?这便是BERT学习sentence-level representation的关键啦。

BERT这里跟word2vec做法类似,不过构造的是一个句子级的分类任务。即首先给定的一个句子(相当于word2vec中给定context),它下一个句子即为正例(相当于word2vec中的正确词),随机采样一个句子作为负例(相当于word2vec中随机采样的词),然后在该sentence-level上来做二分类(即判断句子是当前句子的下一句还是噪声)。通过这个简单的句子级负采样任务,BERT就可以像word2vec学习词表示那样轻松学到句子表示啦。

句子级表示

等等,前面说了这么半天,还没有说句子该怎么表示呢。。。

BERT这里并没有像下游监督任务中的普遍做法一样,在encoding的基础上再搞个全局池化之类的,它首先在每个sequence(对于句子对任务来说是两个拼起来的句子,对于其他任务来说是一个句子)前面加了一个特殊的token,记为[CLS],如图

ps:这里的[sep]是句子之间的分隔符,BERT同时支持学习句对的表示,这里是[SEP]便是为了区分句对的切割点。

然后让encoder对[CLS]进行深度encoding,深度encoding的最高隐层即为整个句子/句对的表示啦。这个做法乍一看有点费解,不过别忘了,Transformer是可以无视空间和距离的把全局信息encoding进每个位置的,而[CLS]作为句子/句对的表示是直接跟分类器的输出层连接的,因此其作为梯度反传路径上的“关卡”,当然会想办法学习到分类相关的上层特征啦。

另外,为了让模型能够区分里面的每个词是属于“左句子”还是“右句子”,作者这里引入了“segment embedding”的概念来区分句子。对于句对来说,就用embedding A和embedding B来分别代表左句子和右句子;而对于句子来说,就只有embedding A啦。这个embedding A和B也是随模型训练出来的。

ps: 这做法跟position embedding一样感觉简单粗暴,实在很费解为什么BERT用在“quora question pairs”这种理论上需要网络保持对称的任务上依然能work,心情复杂

所以最终BERT每个token的表示由token原始的词向量token embedding、前文提到的position embedding和这里的segment embedding三部分相加而成,如图:

简洁到过分的下游任务接口

真正体现出BERT这个模型是龙骨级模型而不再是词向量的,就是其到各个下游任务的接口设计了,或者换个更洋气的词叫迁移策略。

首先,既然句子和句子对的上层表示都得到了,那么当然对于文本分类任务和文本匹配任务(文本匹配其实也是一种文本分类任务,只不过输入是文本对)来说,只需要用得到的表示(即encoder在[CLS]词位的顶层输出)加上一层MLP就好了呀~

既然文本都被深度双向encoding了,那么做序列标注任务就只需要加softmax输出层就好了呀,连CRF都不用了呀~

让小夕更木有想到的是,在span抽取式任务如SQuAD上,把深度encoding和深度attention这俩大礼包省掉就算了,甚至都敢直接把输出层的pointer net给丢掉了?直接像DrQA那样傲娇的用两个线性分类器分别输出span的起点和终点?不多说了,已跪m(_ _)m

最后来看一下实验效果

嗯,这很Google。

此论文一出,小夕非常开心,因为很多之前的想法都不用去做实验验证了,因为已经被BERT摁死了(。 ́︿ ̀。)分类、标注和迁移任务都可以从头开始了,SQuAD的造楼计划也可以停了,感谢BERT没有跑生成任务,这给人带来了一点想象空间。嗯,手动微笑流泪。

最后,喜欢小夕的小哥哥小姐姐们欢迎通过下方打赏按钮或者点击下方小广告鼓励小夕哦,爱你们🌹🌹~

参考文献

[1] 2018 | BERT- Pre-training of Deep Bidirectional Transformers for Language Understanding
[2] 2018NAACL | Deep contextualized word representations
[3] 2018 ACL | Multi-Turn Response Selection for Chatbots with Deep Attention Matching Network
[4] 2018ICLR | Fast and Accurate Reading Comprehension by Combining Self-Attention and Convolution
[5] 2017TACL | Enriching Word Vectors with Subword Information
[6] 2017ACL | Deep Pyramid Convolutional Neural Networks for Text Categorization
[7] 2017 | Convolutional Sequence to Sequence Learning
[8] 2017 | Do Convolutional Networks need to be Deep for Text Classification ?
[9] 2016 | Convolutional Neural Networks for Text Categorization/ Shallow Word-level vs. Deep Character-level
[10] 2013NIPS | Distributed-representations-of-words-and-phrases-and-their-compositionality

夕小瑶的科技屋
夕小瑶的科技屋

同步自微信订阅号“夕小瑶的卖萌屋”和知乎专栏“夕小瑶的科技屋”(作者知乎ID:夕小瑶)

入门BERTELMoWord2VecNLP
8
相关数据
来也机构

「来也」是国内领先的人工智能交互平台,由常春藤盟校(Ivy League)归国博士和MBA团队发起,核心技术涵盖自然语言处理(NLP)、多轮对话控制和个性化推荐系统等。公司已获得数十项专利和国家高新技术企业认证。 来也的愿景是通过AI赋能,让每个人拥有助理。C 端产品小来是智能化的在线助理,通过业内创新的AI+Hi模式,提供日程、打车、咖啡、差旅和个性化查询等三十余项技能(覆盖400w用户和数十万服务者),让用户用自然语言发起需求并得到高效的满足。B端品牌吾来输出知识型的交互机器人和智能客户沟通系统,帮助各领域企业客户打造行业助理。目前已经在母婴,商旅,金融和汽车等行业的标杆企业实现商业化落地。

https://www.laiye.com/
微软机构

微软是美国一家跨国计算机科技公司,以研发、制造、授权和提供广泛的计算机软件服务为主。总部位于美国华盛顿州的雷德蒙德,最为著名和畅销的产品为Microsoft Windows操作系统和Microsoft Office办公室软件,以及Xbox的游戏业务。微软是美国《财富》杂志2015年评选的世界500强企业排行榜中的第95名。

https://www.microsoft.com/en-us/about
线性分类器技术

机器学习通过使用对象的特征来识别它所属的类(或组)来进行统计分类。线性分类器通过基于特征的线性组合的值进行分类决策。 对象的特征也称为特征值,通常在称为特征向量的向量中呈现给机器。

基于Transformer 的双向编码器表征技术

BERT是谷歌发布的基于双向 Transformer的大规模预训练语言模型,该预训练模型能高效抽取文本信息并应用于各种NLP任务,并刷新了 11 项 NLP 任务的当前最优性能记录。BERT的全称是基于Transformer的双向编码器表征,其中“双向”表示模型在处理某一个词时,它能同时利用前面的词和后面的词两部分信息。

池化技术

池化(Pooling)是卷积神经网络中的一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效的原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

权重技术

线性模型中特征的系数,或深度网络中的边。训练线性模型的目标是确定每个特征的理想权重。如果权重为 0,则相应的特征对模型来说没有任何贡献。

词义消歧技术

在计算机语言学, 词义消歧(WSD) 是一个自然语言处理和本体论的开放问题 。 歧义与消歧是自然语言理解中最核心的问题,在词义、句义、篇章含义层次都会出现语言根据上下文语义不同的现象,消歧即指根据上下文确定对象语义的过程。 词义消歧即在词语层次上的语义消歧。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

文本分类技术

该技术可被用于理解、组织和分类结构化或非结构化文本文档。文本挖掘所使用的模型有词袋(BOW)模型、语言模型(ngram)和主题模型。隐马尔可夫模型通常用于词性标注(POS)。其涵盖的主要任务有句法分析、情绪分析和垃圾信息检测。

机器翻译技术

机器翻译(MT)是利用机器的力量「自动将一种自然语言(源语言)的文本翻译成另一种语言(目标语言)」。机器翻译方法通常可分成三大类:基于规则的机器翻译(RBMT)、统计机器翻译(SMT)和神经机器翻译(NMT)。

目标函数技术

目标函数f(x)就是用设计变量来表示的所追求的目标形式,所以目标函数就是设计变量的函数,是一个标量。从工程意义讲,目标函数是系统的性能标准,比如,一个结构的最轻重量、最低造价、最合理形式;一件产品的最短生产时间、最小能量消耗;一个实验的最佳配方等等,建立目标函数的过程就是寻找设计变量与目标的关系的过程,目标函数和设计变量的关系可用曲线、曲面或超曲面表示。

迁移学习技术

迁移学习是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务,虽然大多数机器学习算法都是为了解决单个任务而设计的,但是促进迁移学习的算法的开发是机器学习社区持续关注的话题。 迁移学习对人类来说很常见,例如,我们可能会发现学习识别苹果可能有助于识别梨,或者学习弹奏电子琴可能有助于学习钢琴。

似然函数技术

在数理统计学中,似然函数是一种关于统计模型中的参数的函数,表示模型参数中的似然性。 似然函数在统计推断中有重大作用,如在最大似然估计和费雪信息之中的应用等等。“ 似然性”与“或然性”或“概率”意思相近,都是指某种事件发生的可能性,但是在统计学中,“似然性”和“或然性”或“概率”又有明确的区分。

word2vec技术

Word2vec,为一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。 训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系。该向量为神经网络之隐藏层。 Word2vec依赖skip-grams或连续词袋(CBOW)来建立神经词嵌入。Word2vec为托马斯·米科洛夫(Tomas Mikolov)在Google带领的研究团队创造。该算法渐渐被其他人所分析和解释。

层归一化技术

深度神经网络的训练是具有高度的计算复杂性的。减少训练的时间成本的一种方法是对神经元的输入进行规范化处理进而加快网络的收敛速度。层规范化是在训练时和测试时对数据同时进行处理,通过对输入同一层的数据进行汇总,计算平均值和方差,来对每一层的输入数据做规范化处理。层规范化是基于批规范化进行优化得到的。相比较而言,批规范化是对一个神经元输入的数据以mini-batch为单位来进行汇总,计算平均值和方法,再用这个数据对每个训练样例的输入进行规整。层规范化在面对RNN等问题的时候效果更加优越,也不会受到mini-batch选值的影响。

语言模型技术

语言模型经常使用在许多自然语言处理方面的应用,如语音识别,机器翻译,词性标注,句法分析和资讯检索。由于字词与句子都是任意组合的长度,因此在训练过的语言模型中会出现未曾出现的字串(资料稀疏的问题),也使得在语料库中估算字串的机率变得很困难,这也是要使用近似的平滑n元语法(N-gram)模型之原因。

推荐文章
暂无评论
暂无评论~