基于随机token MASK是Bert能实现双向上下文信息编码的核心。但是MASK策略本身存在一些问题
MASK有这么多的问题,那能否绕过MASK策略来捕捉双向上下文信息呢?下面介绍两种方案XLNET,Electra,它们使用两种截然不同的方案实现了在下游迁移的Encoder中完全抛弃MASK来学习双向上下文信息。正在施工中的代码库也接入了这两种预训练模型,同时支持半监督,领域迁移,降噪loss等模型优化项,感兴趣的戳这里>>SimpleClassification
XLNET主要的创新在于通过排列组合的乱序语言模型,在不依赖MASK的情况下捕捉双向上下文信息,从而避免了MASK存在带来的不一致性。
常规语言模型的目标是按输入顺序进行因式分解,把文本联合概率拆分成条件概率的乘积
而其实对于长度为T的序列,总共有T!种不同的排列组合方式,语言模型只是使用了输入顺序对应的一种分解顺序。而XLNET为了捕捉双向的上下文信息,把目标调整为最大化所有排列组合的以上概率。
以下\(Z_T\)来指代不同的排列组合,\(z \lt t\)是指在z的排列组合中t之前的元素
为了控制计算量,XLNET并不会计算所有排列组合而是只采样一部分进行计算。因为不同的排列组合共用一套参数,也就隐形实现了双向上下文信息的获取。
这里需要注意的是所谓的乱序,并不是对输入样本进行打乱,输入样本会保持原始顺序,而乱序的计算是通过Attention MASK来实现。例如用‘1->3->2’的顺序,生成第3个token会先mask第2个token只使用1个token的信息。这个实现是非常必要,一方面对输入保序,保证了预训练和下游迁移时文本输入是一致的都是正常顺序。另一方面,如果对输入进行直接打乱,会丢失文本的正常顺序,导致模型不知道正常的文本是什么样子的。
从信息传递的角度来看,BERT在还原每个MASK token时都使用了全部的上下文信息,而XLNET的每一种排列组合在预测当前token时只采样了当前排列组合下的部分信息,从这个角度来讲乱序语言模型应该要比MLM更加稳健以及更容易学到更丰富的文本语义
但以上的乱序AR存在一个问题,也就是当顺序是‘3->2->4’时预测4用到的信息,和‘3->2->1’预测1时的信息是一样的。也就是模型无法区分4和1不同位置带来信息差异。为什么只有XLNET会存在这个问题,GPT和BERT就不存在这个问题呢?
在BERT之中是通过MASK来标注哪些位置是需要AE预测的位置,而MASK只修改了对应位置的token embedding,而position embedding是保留了原始位置的信息的,这样在进行self-attention计算时,模型只是不能有效获取MAS
K位置的token信息但是可以获取位置信息。不过其实我对BERT的底层位置信息在经过多层transfromer block之后MASK部分的位置信息是否还能都得到有效的保留,个人感觉是存疑的
而在GPT中因为默认了向前递归,对于所有文本在预训练任务和下游迁移中这个顺序都没有发生改变,所以模型对位置信息的依赖只在x<t的部分,因为向前递归预测的永远是下一个位置,所以位置信息被隐含在了向前递归中。
但是在XLNET中,它既没有按照固定的向前传递顺序,也同时没有像Bert一样保留预测位置的的position embedding,这就导致模型无法知道下一个要预测的位置和已有信息间的关系。
为了解决这个问题XLNET引入了双流机制,其实就是在原始的transformer中加入一个额外的流,这个流不包含当前token的内容信息但是包含当前token的位置信息。
以上初始化\(h_{z_t}\)是用word embedding进行初始化,而\(g_{z_t}\)是随机初始化的。
XLNET的位置编码沿用了Transformer-XL提出的相对位置编码,不熟悉的同学戳这里中文NER的那些事儿5. Transformer相对位置编码&TENER代码实现,不过这部分提升主要针对长文本,和乱序语言模型没有必然的绑定关系,所以后面一起放到长文本建模中再说吧~
由于以上的乱序语言模型的拟合难度较高,如果对全文本都进行拟合,会导致模型难以收敛。所以XLNET引入了hyperparams K,每次只对当前排列组合下最后的\(1/K\)个token进行拟合。所以这里k越小训练难度越高。最终作者选择的K在6~7附近,所以和BERT 15%MASK的训练效率相似,每次只能对15%左右的token进行训练。
XLNET在下游任务迁移中的使用方式和Bert基本是完全一样的,以上的双流机制和乱序语言模型只使用在预训练阶段,来帮助模型参数学习到上下文信息。而在迁移到下游时,只有content流被使用,迁移方式也和Bert一致。XLNET在GLUE评估中基本全面超越BERT
和RoBERTa。
当然以上效果增益部分来自XLNET的乱序语言模型,部分来自Transformer-XL相对位置编码对长文本的效果,部分来自XLNET借鉴了Roberta用了比Roberta略小但远大于BERT的训练数据。不过文中作者做很严谨的对比实验,在相同数据量下XLNET依旧超越BERT和DAE+Transformer-XL。顺便也跟着Roberta验证了NSP对于XLNET任务也是没有效果的...不过我继续持保留意见嘿嘿~
Electra主要针对MLM只对15%MASK的token进行训练导致训练低效的问题,通过两段式的训练,也实现了在下游任务中和MASK解耦,按论文的效果是只用1/4的时间就可以媲美Bert。
Eletra的预训练模块由以下两部分构成,分别是生成replace token的Generator,以及判别每个token是否是原始token的Descriminator,我们分别看下各自的实现
Generator的部分和Bert是基本一致,每次随机MASK15%的token,然后Generator去预测可能的原始token,所以Generator部分就是Bert的MLM任务。
Descriminator的输入是Generator的预测结果,判别器负责判断每个token是否是原始的token,注意如果generator预测正确,则该token也是原始token,所以是一个二分类的判别任务
最终的Loss是Generator和Descriminator Loss的结合
看上模型实现很简单,但细节里全是魔鬼。。。我们来细数下Electra实现过程的细节,以及可能的问题
作者对比了生成器和判别器之间模型大小对效果的影响,整体上生成器大小在判别器的[1/4,1/2]之间最优,虽然size选择有点玄学,不过部分逻辑是讲的通的,节省空间的目的咱就不提了,无论如何预训练内存都是Bert的一倍多,除此之外
生成器和判别器因为以上Size差异的原因,没有共享全部参数,而是共享了Embedding部分,包括token和position embedding的权重。这里共享权重是必要的,因为只有生成器的部分因为要预测token所以会对全Vocab embedding进行更新,而判别器只会对输入部分的token进行更新,考虑下游使用只使用判别器,如果不共享权重,部分低频token可能会存在训练不足的问题。
作者对比了几种生成器和判别器的训练方式
效果如下图是Electra>GAN>两阶段。不过后两种训练方式都还有进一步探索的空间,例如两阶段训练的核心是让生成器先训练一段时间来生成更加Hard的样本,但是会和以上模型size选择存在相同的问题就是生成器太强会导致判别器难以拟合,所以什么时候交换到判别任务的时间点可能很关键。而GAN的部分如果只是让生成器最大化判别器的Loss则难以保证生成器生成的样本多样性,不过我对GAN并不太了解这块就先不展开了。
作者通过对比不同的训练策略,对Electra的效果进行了归因,大头的效果提升来自于在判别器阶段对所有token进行训练
Electra在下游迁移的时候只使用判别器的部分,因此和MASK实现了解耦。但Electra的判别器也是质疑声音最大的地方,Bert的Embedding Output有丰富的上下文语义的一个前提是每个token的预测都是在全Vocab上做softmax,所以Embedding需要包含相对复杂&多样的信息才能完成这个任务,而Electra只是简单的二分类任务,对Embedding表征信息的要求要低的多。所以实践中被吐槽在NER这类对输入Embedding信息量有高要求的任务,以及更加复杂的文本理解任务上Electra表现并不好。
整体上Electra两段式的训练方式去和MASK解耦,对全token进行训练提高训练效率,以及用生成器做进行类似数据增强的操作是相对有亮点的地方,不过把MLM替换成二分类的判别器的选择,以及Electra的训练方式还是值得再进一步深入研究的~
BERT手册相关论文和博客详见BertManual
Reference
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳