当前位置: 首页 > 编程日记 > 正文

ELECTRA:超越BERT,2019年最佳NLP预训练模型

640?wx_fmt=jpeg

作者 | 李如
来源 | NLPCAB(ID:rgznai100)

【导读】BERT推出这一年来,除了XLNet,其他的改进都没带来太多惊喜,无非是越堆越大的模型和数据,以及动辄1024块TPU,让工程师们不知道如何落地。今天要介绍的ELECTRA是我在ICLR盲审中淘到的宝贝(9月25日已截稿),也是BERT推出以来我见过最赞的改进,通过类似GAN的结构和新的预训练任务,在更少的参数量和数据下,不仅吊打BERT,而且仅用1/4的算力就达到了当时SOTA模型RoBERTa的效果。

1. 简介

ELECTRA的全称是Efficiently Learning an Encoder that Classifies Token Replacements Accurately,先来直观感受一下ELECTRA的效果:

640?wx_fmt=jpeg

右边的图是左边的放大版,纵轴是GLUE分数,横轴是FLOPs (floating point operations),Tensorflow中提供的浮点数计算量统计。从上图可以看到,同等量级的ELECTRA是一直碾压BERT的,而且在训练更长的步数之后,达到了当时的SOTA模型——RoBERTa的效果。从左图曲线上也可以看到,ELECTRA效果还有继续上升的空间。

2.模型结构

NLP式的Generator-Discriminator

ELECTRA最主要的贡献是提出了新的预训练任务和框架,把生成式的Masked language model(MLM)预训练任务改成了判别式的Replaced token detection(RTD)任务,判断当前token是否被语言模型替换过。那么问题来了,我随机替换一些输入中的字词,再让BERT去预测是否替换过可以吗?可以的,因为我就这么做过,但效果并不好,因为随机替换太简单了

那怎样使任务复杂化呢?。。。咦,咱们不是有预训练一个MLM模型吗?

于是作者就干脆使用一个MLM的G-BERT来对输入句子进行更改,然后丢给D-BERT去判断哪个字被改过,如下:

640?wx_fmt=jpeg

于是,我们NLPer终于成功地把CV的GAN拿过来了!

Replaced Token Detection

但上述结构有个问题,输入句子经过生成器,输出改写过的句子,因为句子的字词是离散的,所以梯度在这里就断了,判别器的梯度无法传给生成器,于是生成器的训练目标还是MLM(作者在后文也验证了这种方法更好),判别器的目标是序列标注(判断每个token是真是假),两者同时训练,但判别器的梯度不会传给生成器,目标函数如下:

640?wx_fmt=png

因为判别器的任务相对来说容易些,RTD loss相对MLM loss会很小,因此加上一个系数,作者训练时使用了50。

另外要注意的一点是,在优化判别器时计算了所有token上的loss,而以往计算BERT的MLM loss时会忽略没被mask的token。作者在后来的实验中也验证了在所有token上进行loss计算会提升效率和效果。

事实上,ELECTRA使用的Generator-Discriminator架构与GAN还是有不少差别,作者列出了如下几点:

640?wx_fmt=png

3.实验及结论

创新总是不易的,有了上述思想之后,可以看到作者进行了大量的实验,来验证模型结构、参数、训练方式的效果。

Weight Sharing

生成器和判别器的权重共享是否可以提升效果呢?作者设置了相同大小的生成器和判别器,在不共享权重下的效果是83.6,只共享token embedding层的效果是84.3,共享所有权重的效果是84.4。作者认为生成器对embedding有更好的学习能力,因为在计算MLM时,softmax是建立在所有vocab上的,之后反向传播时会更新所有embedding,而判别器只会更新输入的token embedding。最后作者只使用了embedding sharing。

Smaller Generators

从权重共享的实验中看到,生成器和判别器只需要共享embedding的权重就足矣了,那这样的话是否可以缩小生成器的尺寸进行训练效率提升呢?作者在保持原有hidden size的设置下减少了层数,得到了下图所示的关系图:

640?wx_fmt=jpeg

可以看到,生成器的大小在判别器的1/4到1/2之间效果是最好的。作者认为原因是过强的生成器会增大判别器的难度(判别器:小一点吧,我太难了)。

Training Algorithms

实际上除了MLM loss,作者也尝试了另外两种训练策略:

  1. Adversarial Contrastive Estimation:ELECTRA因为上述一些问题无法使用GAN,但也可以以一种对抗学习的思想来训练。作者将生成器的目标函数由最小化MLM loss换成了最大化判别器在被替换token上的RTD loss。但还有一个问题,就是新的生成器loss无法用梯度下降更新生成器,于是作者用强化学习Policy Gradient的思想,将被替换token的交叉熵作为生成器的reward,然后进行梯度下降。强化方法优化下来生成器在MLM任务上可以达到54%的准确率,而之前MLE优化下可以达到65%。
  2. Two-stage training:即先训练生成器,然后freeze掉,用生成器的权重初始化判别器,再接着训练相同步数的判别器。
对比三种训练策略,得到下图:
640?wx_fmt=jpeg
可见“隔离式”的训练策略效果还是最好的,而两段式的训练虽然弱一些,作者猜测是生成器太强了导致判别任务难度增大,但最终效果也比BERT本身要强,进一步证明了判别式预训练的效果。
Small model? Big model?
这两节真是吊打之前的模型,作者重申了他的主要目的是提升预训练效率,于是做了GPU单卡就可以愉快训练的ELECTRA-Small和BERT-Small,接着和尺寸不变的ELMo、GPT等进行对比,结果如下:
640?wx_fmt=jpeg
数据简直优秀,仅用14M参数量,以前13%的体积,在提升了训练速度的同时还提升了效果,这里我疯狂点赞。
小ELECTRA的本事我们见过了,那大ELECTRA行吗?直接上图:
640?wx_fmt=jpeg
上面是各个模型在GLUE dev/text上的表现,可以看到ELECTRA仅用了1/4的计算量就达到了RoBERTa的效果。而且作者使用的是XLNet的语料,大约是126G,但RoBERTa用了160G。由于时间和精力问题,作者们没有把ELECTRA训练更久(应该会有提升),也没有使用各种榜单Trick,所以真正的GLUE test上表现一般(现在的T5是89.7,RoBERTa是88.5,没看到ELECTRA)。
Efficiency Analysis
前文中提到了,BERT的loss只计算被替换的15%个token,而ELECTRA是全部都计算的,所以作者又做了几个实验,探究哪种方式更好一些:
  1. ELECTRA 15%:让判别器只计算15% token上的损失
  2. Replace MLM:训练BERT MLM,输入不用[MASK]进行替换,而是其他生成器。这样可以消除这种pretrain-finetune直接的diff。
  3. All-Tokens MLM:接着用Replace MLM,只不过BERT的目标函数变为预测所有的token,比较接近ELECTRA。
三种实验结果如下:
640?wx_fmt=jpeg
可以看到:
  1. 对比ELECTRA和ELECTRA 15%:在所有token上计算loss确实能提升效果
  2. 对比Replace MLM和BERT:[MASK]标志确实会对BERT产生影响,而且BERT目前还有一个trick,就是被替换的10%情况下使用原token或其他token,如果没有这个trick估计效果会差一些。
  3. 对比All-Tokens MLM和BERT:如果BERT预测所有token 的话,效果会接近ELECTRA
另外,作者还发现,ELECTRA体积越小,相比于BERT就提升的越明显,说明fully trained的ELECTRA效果会更好。另外作者推断,由于ELECTRA是判别式任务,不用对整个数据分布建模,所以更parameter-efficient

4.总结

无意中发现了这篇还在ICLR盲审的ELECTRA,读完摘要就觉得发现了新大陆,主要是自己也试过Replaced Token Detection这个任务,因为平时任务效果的分析和不久前看的一篇文章,让我深刻感受到了BERT虽然对上下文有很强的编码能力,却缺乏细粒度语义的表示,我用一张图表示大家就明白了:
640?wx_fmt=jpeg
这是把token编码降维后的效果,可以看到sky和sea明明是天与海的区别,却因为上下文一样而得到了极为相似的编码。细粒度表示能力的缺失会对真实任务造成很大影响,如果被针对性攻击的话更是无力,所以当时就想办法加上更细粒度的任务让BERT去区分每个token,不过同句内随机替换的效果并不好,弱鸡的我也没有再往前想一步,不然就也ICLR了。相信这个任务很多人都想到过,不过都没有探索这么深入,这也告诫我们,idea遍地都是,往下挖才能有SOTA。
ELECTRA是BERT推出这一年来我见过最赞的idea,它不仅提出了能打败MLM的预训练任务,更推出了一种十分适用于NLP的类GAN框架。毕竟GAN太牛逼了,看到deepfake的时候我就想,什么时候我们也能deepcheat,但听说GAN在NLP上的效果一直不太好(只懂皮毛,要学起来了,轻拍),这次ELECTRA虽然只用了判别器,但个人认为也在一定程度上打开了潘多拉魔盒。
另外,整篇文章都干货满满,不再像之前的BERT+模型一样可以用“more data+params+steps+GPU+MONEY”简单概括。推荐大家去通读正文+附录,里面还有一些失败尝试我没有讲。
如果ELECTRA去直播,我一定给它刷一辆游艇。

参考资料:

ELECTRA: PRE-TRAINING TEXT ENCODERS AS DISCRIMINATORS RATHER THAN GENERATORS

(*本文为AI科技大本营转载文章,转载联系原作者


精彩推荐



2019 中国大数据技术大会(BDTC)再度来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货+技术剖析+行业实践立体解读,深入解析热门技术在行业中的实践落地。6.6 折票限时特惠(立减1400元),学生票仅 599 元!

640?wx_fmt=png


推荐阅读

相关文章:

安装node和spm过程

2019独角兽企业重金招聘Python工程师标准>>> 安装nodejs 官网下载nodejs,我下的是v0.10.33版本,安装到d:\nodejs下。 1.新建目录d:\nodejs,在其中建立node_cache、node_global、node_modules三个目录。 2,将C:\Users…

经典网络LeNet-5介绍及代码测试(Caffe, MNIST, C++)

LeNet-5:包含7个层(layer),如下图所示:输入层没有计算在内,输入图像大小为32*32*1,是针对灰度图进行训练和预测的。论文名字为” Gradient-Based Learning Applied to Document Recognition”,可以直接从ht…

根据经纬度获取用户当前位置信息

根据上篇文章获取的经纬度获取用户当前的位置信息 //获取用户所在位置信息ADDRESS func getUserAddress() { let latitude : CLLocationDegrees LATITUDES! let longitude : CLLocationDegrees LONGITUDES! print("latitude:\(latitude)") print("longitude…

刷了几千道算法题,我私藏的刷题网站都在这里了

作者 | Rocky0429 来源 | Python空间(ID: Devtogether)遥想当年,机缘巧合入了 ACM 的坑,周边巨擘林立,从此过上了"天天被虐似死狗"的生活...然而我是谁,我可是死狗中的战斗鸡,智力不够…

js实现点击li标签弹出其索引值

据说这是一道笔试题&#xff0c;以下是代码&#xff0c;没什么要文字叙述的&#xff0c;就是点击哪个<li>弹出哪个<li>的索引值即可&#xff1a; <html> <head> <style> li{width:50px;height:30px;margin:5px;float:left;text-align: center;li…

定时器开启和关闭

写程序时遇见了定时器&#xff0c;需要写入数据库用户的经纬 &#xff0c;还要读取&#xff0c;写好之后发现很费电 总结原因&#xff1a; 1&#xff1a;地图定位耗电&#xff08;这个根据程序要求&#xff0c;不能关闭&#xff0c;需要实时定位&#xff0c;很无奈&#xff…

一览群智胡健:在中国完全照搬Palantir模式,这不现实

作者 | Just出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;神秘的硅谷大数据挖掘公司 Palantir 是国内众多创业公司看齐的标杆&#xff0c;其业务是为政府和金融领域的大客户提供数据分析服务&#xff0c;帮助客户作出判断&#xff0c;甚至“预知未来”&#xff0c;…

ImageNet图像数据集介绍

ImageNet图像数据集始于2009年&#xff0c;当时李飞飞教授等在CVPR2009上发表了一篇名为《ImageNet: A Large-Scale Hierarchical Image Database》的论文&#xff0c;之后就是基于ImageNet数据集的7届ImageNet挑战赛(2010年开始)&#xff0c;2017年后&#xff0c;ImageNet由Ka…

cocos2dx 场景的切换

我们知道cocos2dx中可以由多个场景组成&#xff0c;那么我是如何来切换场景的呢首先我们先新建一个新的场景类&#xff0c;我推荐的方式是&#xff0c;在你工程的目录中找到一个classes的文件夹&#xff0c;里面有AppDelegate.cpp和AppDelegate.h还有HelloWorldScene.cpp和Hell…

IOS 后台挂起程序 当程序到后台后,继续完成定位任务

// 当应用程序掉到后台时&#xff0c;执行该方法 - (void)applicationDidEnterBackground:(UIApplication *)application { } 当一个 iOS 应用被送到后台,它的主线程会被暂停。你用 NSThread 的 detachNewThreadSelector:toTar get:withObject:类方法创建的线程也被挂起了。 我…

任正非:华为5G是瞎猫碰死老鼠

喜欢话糙理不糙的任正非&#xff0c;又飙金句。11月6日&#xff0c;在和彭博社记者对话时&#xff0c;谈到华为5G&#xff0c;他说&#xff1a;“回顾这个过程&#xff0c;我们也没有什么必胜的信心&#xff0c;有时候也是瞎猫碰上了死老鼠&#xff0c;刚好碰上世界是这个需求。…

网络文件系统(NFS)简介

网络文件系统(Network File System, NFS)是一种分布式文件系统协议&#xff0c;最初由Sun Microsystems公司开发&#xff0c;并于1984年发布。其功能旨在允许客户端主机可以像访问本地存储一样通过网络访问服务器端文件。NFS和其他许多协议一样&#xff0c;是基于开放网络运算远…

JAVA Static方法与单例模式的理解

最近用sonar测评代码质量的时候&#xff0c;发现一个问题&#xff0c;工程中一些util类&#xff0c;以前写的static方法都提示最好用单例的方式进行改正。为此&#xff0c;我仔细想了想&#xff0c;发现还是很有道理的。这里谈谈我个人对static方法与单例模式的理解。所谓单例模…

程序员的自我修养--链接、装载与库笔记:目标文件里有什么

编译器编译源代码后生成的文件叫做目标文件。目标文件从结构上讲&#xff0c;它是已经编译后的可执行文件格式&#xff0c;只是还没有经过链接的过程&#xff0c;其中可能有些符号或有些地址还没有被调整。其实它本身就是按照可执行文件格式存储的&#xff0c;只是跟真正的可执…

swift 中拨电话的实现

//MARK:_一键报警设置//MARK: - 弹出视图func createView() {var alertView : UIAlertView?alertView UIAlertView(title: "110", message: "", delegate: self, cancelButtonTitle: "取消", otherButtonTitles: "呼叫")alertView?…

T5,一个探索迁移学习边界的模型

作者 | Ajit Rajasekharan译者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】10月&#xff0c;Google 在《Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer》这篇论文中提出了一个最新的预训练模型 T5&#xff…

【Chat】实验 -- 实现 C/C++下TCP, 服务器/客户端 多人聊天室

本次实验利用TCP/IP, 语言环境为 C/C 利用套接字Socket编程&#xff0c;以及线程处理&#xff0c; 实现Server/CLient 之间多人的聊天系统的基本功能。 结果大致如&#xff1a; 下面贴上代码&#xff08;参考参考...) Server 部分&#xff1a; 1 /* TCPdtd.cpp - main, TCPdayt…

TeamViewer介绍:远程控制计算机

TeamViewer是一个可以远程控制计算机的程序&#xff0c;它也可以进行远程文件传输。TeamViewer支持的平台比较多&#xff0c;如Windows, Mac, Linux, ChromeOs, Android, iOS等&#xff0c;最新发布版本为14.x&#xff0c;它有个人免费和商业付费两种。只要对方告诉你他的TeamV…

PyTorch攻势凶猛,程序员正在抛弃TensorFlow?

来源 | The Gradient译者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;自 2012 年深度学习重新获得重视以来&#xff0c;许多机器学习框架便争相成为研究人员和行业从业人员的新宠。从早期的学术成果 Caffe 和 Theano &#xff0c;到背靠庞大工业支持的 PyT…

swift 错误集合 ------持续更新中

从今天开始凡是在用swift中遇到的错误都会在本博客持续更新 便于自己学习和快速开发 2017.7.20 如果你的程序写的有进入后台的方法&#xff0c;例如我的博客中点击home进入后台持续定位的那篇文章&#xff0c;发信进入后台后定位没有按得定时器规定的时间走&#xff0c;这…

【转载】【贪心】各种覆盖问题

1、独立区间问题 在N个区间里找出最多的互不覆盖的区间 对结束点进行排序&#xff0c;然后从结束点最小的区间开始进行选择即可 2、覆盖区间问题 给一个大区间&#xff0c;再给出N个小区间&#xff0c;求出最少用多少个区间可以把大区间覆盖完 先选出开始的一个&#xff0c;然后…

使用Python3发送邮件测试代码

SMTP(Simple Mail Trasfer Protocol)即简单邮件传输协议&#xff0c;它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;用它来控制信件的中转方式。Python3对SMTP的支持有smtplib和email两个模块&#xff0c;smtplib负责发送电子邮件&#xff0c; email负责组织邮件内…

swift 通知中心 进入后台多久会通知用户关闭此功能

//添加本地通知 func addLocalNotification() { //定义本地通知对象 let notification : UILocalNotification UILocalNotification() //设置调用时间 notification.fireDate NSDate.init(timeIntervalSinceNow: 1800.0)//通知触发的时间&#xff0c;10s以后 notification.…

Python之父退休,C语言之父与世长辞,各大编程语言创始人现状盘点

作者 | 年素清 编辑 | 伍杏玲 来源 | 程序人生&#xff08;ID&#xff1a;coder_life&#xff09;从世界上第一台计算机(ENIAC) 于1946年2月在美国诞生至今的七十多年里&#xff0c;涌现出了许多优秀的计算机编程语言。程序员们在使用它们编写程序的时候&#xff0c;一定很好奇…

linux修正系统错误指令fsck和badblocks

fsck [-t文件系统][-ACay]装置名称-t 指定文件系统-A 扫描需要的装置-a 自动修复检查到有问题的扇区-y 与-a类似-C 在检查过程中&#xff0c;显示进度********************************************************** EXT2/EXT3额外选项功能&#xff1a;-f 强制检查-D 针对文件系…

Ubuntu定时任务crontab命令介绍

通过Linux上的crontab命令&#xff0c;我们可以在规定的间隔时间执行指定的系统指令或脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。 crontab默认在Ubuntu上是已经安装的&#xff0c;若未安装&#xff0c;则可执行以下命令进行安装&#xff1a; sudo …

swift 进入后台或者点击home键是程序进入后台后,持续定位

进入后台的方法 import UIKit UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate,CLLocationManagerDelegate { var locationManager : CLLocationManager? var window: UIWindow? var notificationDict NSDictionary() func applicationDidEnterBa…

求助:我有一辆机器人小车,怎么让它跑起来,还会避障、目标跟踪、路径规划?...

也许&#xff0c;你曾见过能灵活地绕开障碍物的它在桌子边缘“疯狂试探”的它它是谁&#xff1f;没错&#xff0c;它就是是英伟达推出的一款入门级人工智能小车——Jetbot &#xff0c;估计对机器人&#xff0c;尤其是对车械感兴趣的朋友们一定对它不陌生。组装完成后能够通过摄…

Python-常用字符串转换实例

当字符串是&#xff1a;\u4e2d\u56fd >>>s[\u4e2d\u56fd,\u6e05\u534e\u5927\u5b66]>>>strs[0].decode(unicode_escape) #.encode("EUC_KR")>>>print str 中国 当字符串是: >>>print unichr(19996) 东 ord()支持unicode&…

什么是静态UItableView

iOS开发UI篇—简单介绍静态单元格的使用 iOS开发UI篇—简单介绍静态单元格的使用 一、实现效果与说明 说明&#xff1a;观察上面的展示效果&#xff0c;可以发现整个界面是由一个tableview来展示的&#xff0c;上面的数据都是固定的&#xff0c;且几乎不会改变。 要完成上面的…