首发于NLPCAB

谈谈我对ELECTRA源码放出的看法

还记得去年写下《ELECTRA: 超越BERT, 19年最佳NLP预训练模型》时兴奋的心情,在我等到都快复工的时候,终于看到了它的身影和源码[1]:

才第五吗?没事,期望越大,失望越大

谷歌在github放出的预训练模型效果(glue test)是这样的:

燃!鹅!在论文中声称的效果却是这样的:

逐个任务去比的话,以下是dev集上的结果,large还是比较接近,但base和small论文没放出详细的分数:

结果中尤其是RTE的波动还是很大的,对此,Github repo中官方的解释是精调的震荡比较大,他们测试了很多随机种子后取了中位数。

虽然ELECTRA的思想仍是很惊艳的,但这样的结果不免让我们对原论文的数据产生质疑。论文中,small和base是dev上的glue,large是dev和test上的avg。而github里给出的是glue,但没交代是dev还是test,如果是dev,那small和base明显跟论文中有diff,而large由于论文中没有给glue,有没有diff不得而知。

不过,有了word2vec和transformer的大家都懂的前车之鉴,我们这一次也理解为瑕不掩瑜了(* ̄m ̄)

03.14更新:

在12号对结果数据质疑后,谷歌在14号更新了github readme,给出了glue test总分和glue dev的各任务得分。就这些数据来看,large的dev结果可以对得上,但small和test仍不确定论文中的分数计算方法。

回顾目前单模型的进展(只参考原论文数据):

如果按照github中给出的85.2,ELECTRA跟RoBERTa还是有很大差距的。那今天我们就来分析讨论一下ELECTRA的优点和缺陷,欢迎在评论区一起讨论噢。

PS:不了解这个模型的同学可以先看第二章ELECTRA简介~

1. ELECTRA优缺点

通过自己的思考和知乎大佬们的提点[2],ELECTRA主要有如下优点:

  • 任务难度的提升(知乎@香侬科技)

原始的MLM任务是随机进行mask,样本预测难度是不一样的,比如“夕小瑶的卖[MASK]屋”和“夕[MASK]瑶的卖萌屋”中,卖萌是比较常见的词语,而夕小瑶则是命名实体,没见过的话更难预测出来。生成器相当于对输入进行了筛选,使判别器的任务更难,从而学习到更好的表示。

  • 效率的提升(知乎@徐啸)

运算上,判别器进行2分类而不是V分类,复杂度降低。参数利用上,判别器不需要对完整的数据分布进行建模,作者在实验中也发现越小的模型提升越明显,可见参数被更完整地训练了。

  • Token自身信息的利用(知乎@Towser)

做MLM的任务时,都是mask掉token自身,利用上下文对自己进行预测。而ELECTRA是同时利用自身和上下文预测,和NLU任务的Finetune阶段也比较一致。

  • 收敛速度

从论文中的分析实验来看:

  • ELECTRA 15%:让判别器只计算15% token上的损失
  • Replace MLM:两个生成器。一个生成器替换被mask的token,另一个生成器用替换后的输入继续进行15%的MLM训练。这样可以消除pretrain-finetune之间的diff
  • All-Tokens MLM:同Replace MLM,只不过BERT的目标函数变为预测所有的token,为了防止信息泄露加入了copy机制,以D的概率直接拷贝输入,以1-D的概率预测新token,相当于ELECTRA和BERT的结合

可以发现,对效果提升最重要的其实是all-tokens的loss计算,这种方式相比只计算15%的token,大大增加了模型收敛速度。

虽然ELECTRA有很多优点,但个人认为它还有以下缺陷:

  • 显存占用增多

之前都是训一个BERT,现在相当于两个,即使共享参数去训练,由于Adam等优化器的关系,需要保存的中间结果数量也是翻倍的。

  • 多任务学习超参数调整

ELECTRA的loss由生成器和判别器分别构成,原文中给判别器loss的权重是50,因为二分类的loss会比V分类低很多。但这个数值太过绝对,最好是变成可学习的参数动态调整。

  • 判别器的表示适合下游任务吗?

在BERT上进行MLM的训练,再放到下游任务是合理的,因为我们认为BERT的V分类任务给每个token生成了一个基于上下文的表示。可判别器的目标是2分类,也就是把token表示划分到两个空间中,使hidden space过早退化,遇到下游复杂任务时不足以生成丰富的表示。(参见评论区同学们的实践经验)

2. ELECTRA简介

2.1 模型结构

ELECTRA的全称是Efficiently Learning an Encoder that Classifies Token Replacements Accurately,以1/4的算力就达到了RoBERTa的效果。模型结构如下:

Generator和Discriminator可以看作两个BERT,生成器的任务是MLM,判别器的任务是Replaced Token Detection,判断哪个字被替换过。

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

\mathop{\min}_{\theta_G,\theta_D}\sum_{x\in\mathcal{X}}\mathcal{L}_{MLM}(x,\theta_G)+\lambda\mathcal{L}_{Disc}(x,\theta_D) \\

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

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

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

2.2 实验及结论

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

  • Weight Sharing

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

  • Smaller Generators

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

可以看到,生成器的大小在判别器的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掉,用生成器的权重初始化判别器,再接着训练相同步数的判别器。

对比三种训练策略,得到下图:

可见“隔离式”的训练策略效果还是最好的,而两段式的训练虽然弱一些,作者猜测是生成器太强了导致判别任务难度增大,但最终效果也比BERT本身要强,进一步证明了判别式预训练的效果。

  • Small model? Big model?

模型的效果可以参考文首的图片,ELECTRA-Small仅用14M参数量,以前13%的体积,就接近了BERT-Base的效果。ELECTRA-Base更是超越了BERT-Large。由于时间和精力问题,作者们没有把ELECTRA训练更久(应该会有提升),也没有使用各种榜单Trick,所以真正的GLUE test上表现一般。

参考文献:

[1]. github.com/google-resea

[2]. zhihu.com/question/3540

编辑于 03-14

文章被以下专栏收录