ALBERT: A Lite BERT for Self-supervised Learning of Language Representations
ALBert是ICLR的一篇投稿论文,目前还没有被录用,但是却引起很多人的关注,这到底是为什么呢?
事情经过是这样的:
有 Reddit 网友发现,一个叫做 ALBERT 的模型,在 SQuAD 2.0 leaderboard 和 GLUE benchmark 都达到了最佳水准。这是一个前所未见的新模型,引起了大家的好奇。
不久,终于有网友扒出了这个模型的论文,原来是 ICLR 2020 的一篇投稿,出自谷歌。
ALBERT 又叫 A LITE BERT,顾名思义就是一个轻量级的 BERT 模型。模型大固然效果好,但也超吃资源。训练一次不仅耗时、更费钱。甚至在某些情况下,由于 GPU/TPU 内存限制、训练时间延长以及意外的模型退化等原因,更难提升模型大小。谷歌研究人员对此提出了通过两种参数约简技术来降低内存消耗,加快 BERT 的训练速度的思路,于是就有了 ALBERT。
ALBERT的模型,比 BERT-large 参数更少,却在 GLUE 基准远远甩开 BERT-Large 拿到榜首。不仅如此,该模型横扫 GLUE、RACE 和 SQuAD,以显著的优势稳坐第一。
预训练也叫做Pre-training, 是迁移学习中很重要的一项技术。在自然语言处理中主要以词向量为主。单词我们一般可以用两种不同的方式来表示,一种方式为"one-hot encoding",另外一种方式为分布式表示(通常也叫作词向量/Word2Vec)。 由于单词是所有文本的基础,所以如何去更好地表示单词变得尤其重要。
那如何去理解预训练呢? 举个例子,比如我们用BERT训练了一套模型,而且已经得到了每个单词的词向量, 那这时候我们可以直接把这些词向量用在我们自己的任务上,不用自己重新训练,这就类似于迁移学习的概念。 或者通过BERT已经训练好的模型去动态地去得出上下文中的词向量。
预训练在通常情况下既可以提升训练效率也可以提高模型效果,因为使用预训练的结果本身其实就是去试图寻找最好的最优解。
通过词向量技术我们可以把一个单词表示为向量的形式,然后接着应用在后续的模型当中。我们可以认为词向量表示的是单词的语义(semantic)。 我们可以按照不同的类别区分词向量技术。
常用的词向量模型比如SkipGram, CBOW, Glove 是不考虑上下文的,也就是一个单词有个固定(Fixed)的向量,不依赖于上下文的改变而改变。比如“I back my car"和 "I hurt my back"里,单词"back"在不同的语境下的含义是不一样的 。
近2,3年很多工作的重点放在了学习考虑上下文的词向量。在这个领域产生了诸多很有突破性的进展,从ELMo,BERT, XLNet到今日刚刚发布的ALBERT,无一不是以这个为重点。利用这些模型,我们可以动态地去学出一个单词在不同上下文之间的词向量。当然,这些向量在不同的语境下的表示肯定是不一样的。
BERT是一种基于Transformer Encoder来构建的一种模型,它整个的架构其实是基于DAE(Denoising Autoencoder)的,这部分在BERT文章里叫作Masked Lanauge Model(MLM)。MLM并不是严格意义上的语言模型,因为整个训练过程并不是利用语言模型方式来训练的。BERT随机把一些单词通过MASK标签来代替,并接着去预测被MASK的这个单词,过程其实就是DAE的过程。BERT有两种主要训练好的模型,分别是BERT-Small和BERT-Large, 其中BERT-Large使用了12层的Encoder结构。 整个的模型具有非常多的参数。
BERT在2018年提出,当时引起了爆炸式的反应,因为从效果上来讲刷新了非常多的记录,之后基本上开启了这个领域的飞速的发展。
BERT之后的一个爆发节点发生在XLNet发布的时候,因为它刷新了BERT保留的很多记录。除了效果之外,那为什么要提出XLNet呢?这就需要从BERT的缺点说起。
虽然BERT有很好的表现,但本身也有一些问题。总结起来有以下几点:
训练数据和测试数据之间的不一致性,这也叫作Discrephancy。当我们训练BERT的时候,会随机的Mask掉一些单词的,但实际上在使用的过程当中,我们却没有MASK这类的标签,所以这个问题就导致训练的过程和使用(测试)的过程其实不太一样,这是一个主要的问题。
并不能用来生成数据。由于BERT本身是依赖于DAE的结构来训练的,所以不像那些基于语言模型训练出来的模型具备很好地生成能力。之前的方法比如NNLM[12],ELMo是基于语言模型生成的,所以用训练好的模型可以生成出一些句子、文本等。但基于这类生成模型的方法论本身也存在一些问题,因为理解一个单词在上下文里的意思的时候,语言模型只考虑了它的上文,而没有考虑下文!
基于这些BERT的缺点,学者们提出了XLNet, 而且也借鉴了语言模型,还有BERT的优缺点。最后设计出来的模型既可以很好地用来执行生成工作,也可以学习出上下文的向量表示。那如何做的呢?
首先,生成模型是单向的,即便我们使用Bidirectional LSTM类模型,其实本质是使用了两套单向的模型。那又如何去解决呢?答案是他们使用了permutation language model, 也就是把所有可能的permutation全部考虑进来。这个想法源自于hugo之前的工作叫作NADE,感兴趣的读者可以去看一下。
另外,为了迎合这种改变,他们在原来的Transformer Encoder架构上做了改进,这不分叫作Two-stream attention, 而且为了更好地处理较长的文本,进而使用的是Transformer-XL。 这就是XLNet的几大核心!
接着看一下那为什么要提出ALBERT呢?其实他们的想法很简单就是想让模型更轻,训练更快,效果更好!
过去几年深度学习圈子里一直出现了一些“怪象”,就是堆数据,让模型更复杂,训练出来的效果更好! 但真正的智能应该是用更简单的模型,用更少量的数据,得到更好的结果! 可以想一下人类是如何学习的?我们的学习不需要大量的样本,而且有举一反三的能力,这才叫作真正的智能! 我们的研究在这个道路上还有很长的路要走。
之前的BERT,XLNet为什么效果好? 这绝对离不开模型本身的复杂度,一个模型拥有上百亿的参数,效果不好就太对不起我们的资源了。我们要知道训练一套这类模型需要花费甚至几百万美金的成本。
所以这时候提出ALBERT也不奇怪的,就是试图解决上述的问题: 1. 让模型的参数更少 2. 使用更少的内存 3. 提升模型的效果。就是这么简单!
这一部分中,我们将简要介绍 ALBERT 的三大模块,并提供与标准 BERT 的量化对比。
ALBERT 架构的骨干网络与 BERT 是相似的,即使用 Transformer 编码器和 GELU 非线性激活函数。现在先约定一下 BERT 的表示方式,即指定词嵌入大小为 E、编码器层数为 L、隐藏层大小为 H。与 Devlin 等人的研究一样,这篇论文将前馈网络/滤波器大小设置为 4H,将注意力 Head 的数量设置为 H/64。
接下来介绍这三点改进。
在 BERT 以及后续的 XLNet 和 RoBERTa 中,WordPiece 词嵌入大小 E 和隐藏层大小 H 是相等的,即 E ≡ H。由于建模和实际使用的原因,这个决策看起来可能并不是最优的。这个选择有两方面缺点:
因此,对于 ALBERT 而言,研究者对词嵌入参数进行了因式分解,将它们分解为两个小矩阵。研究者不再将 one-hot 向量直接映射到大小为 H 的隐藏空间,而是先将它们映射到一个低维词嵌入空间 E,然后再映射到隐藏空间。通过这种分解,研究者可以将词嵌入参数从 O(V × H) 降低到 O(V × E + E × H),这在 H 远远大于 E 的时候,参数量减少得非常明显。
从后续的实验中来看,E的大小与实验效果也不是完全正相关,因此其他实验中E都取的128。
对于 ALBERT,研究者提出了另一种跨层参数共享机制来进一步提升参数效率。其实目前有很多方式来共享参数,例如只贡献前馈网络不同层之间的参数,或者只贡献注意力机制的参数,而 ALBERT 采用的是贡献所有层的所有参数。
这种机制之前也是有的,但研究者的度量发现词嵌入的 L2 距离和余弦相似性是震荡而不是收敛。如下图 2 展示了每一层输入与输出嵌入矩阵间的 L2 距离与余弦相似性。
研究者发现 ALBERT 从一层到另一层的转换要比 BERT 平滑得多,结果表明,权重共享有效地提升了神经网络参数的鲁棒性。即使相比于 BERT 这两个指标都有所下降,但在 24 层以后,它们也不会收敛到 0。
除了自编码语言建模损失外,BERT 还是用了额外的下一句预测损失。下一句预测损失本来是为了提升下游任务的性能,但是后来很多研究者发现这种机制并不是很高效,因此决定去除它。
研究者猜测,下一句预测任务低效的原因,主要是它的难度太小。因为下一句预测将主题预测和连贯性预测结合到单个任务中,然而主题预测比连贯性预测简单得多,因此它与语言建模损失函数学到的内容是有重合的。
研究者表示,句间建模在语言理解中是非常重要的,因此他们提出了一种基于语言连贯性的损失函数。对于 ALBERT,研究者使用了一个句子顺序预测(SOP)损失函数,它会避免预测主题,而只关注建模句子之间的连贯性。
具体的损失函数表达式读者可以查阅原论文,但研究者表示,在使用了该损失函数后,ALBERT 能显著提升下游多句子编码任务的性能。
为了进行更公平的对比,研究者在原始 BERT 的配置下训练试验模型效果。研究者使用了 BOOKCORPUS 和 English Wikipedia 共计 16GB 的纯文本作为预训练任务的数据。它们在 Cloud TPU V3 上训练所有的模型,TPU 数量从 64 到 1024 会根据模型大小进行选择。
如下表 3 所示,只有 BERT-Large 70% 的参数量,ALBERT-xxlarge 能实现显著的性能提升。
表 3:模型在 BOOKCORPUS 和 Wikipedia 数据集训练 125k 步后的开发集结果。
如上所示,ALBERT 相比 BERT 有更高的数据吞吐量,其中最慢的就是 BERT-xLarge,它也作为了基线结果。随着模型越来越大,BERT 和 ALBERT 之间的差别也越来越大。
前面介绍过嵌入矩阵分解的优势,如下表 4 展示了修改词嵌入大小 E 带来的影响,它们的参数量及下游任务效果也都展示在内。
表 4:ALBERT-base 随词嵌入大小的改变,其性能与参数量的变化。
对于 ALBERT 的第二个基础——跨层参数共享,下面表 5 展示了该机制的效果,其同样使用 ALBERT-base 作为示例模型。
表 5:跨层参数共享策略的效果,此处用到的模型是 ALBERT-base。
对于 ALBERT 的第三大基础——句间连贯性损失(SOP),下表 6 展示了其与下一句预测损失(NSP)的对比效果。
表 3 中的加速结果表明,BERT-large 的数据吞吐量是 ALBERT-xxlarge 的 3.17 倍。我们知道,延长训练时间通常能提升模型的表现,因此研究者决定让模型训练差不多相同的时间来观察其表现。下图 7 展示了实验结果:
图 7:BERT-large 和 ALBERT-xxlarge 在控制训练时间时的效果。
在训练了差不多相同的时间之后,ALBERT-xxlarge 明显优于 BERT-large。
上述实验都是在 Wikipedia 和 BOOKCORPUS 数据集上进行的,那么,如果增加额外的数据会对结果产生怎样的影响?
图 3a 表明,添加额外数据后,模型的开发集 MLM 准确率显著提升。
此外,研究者还观察了添加额外数据后模型在下游任务中的性能情况,如下表 8 所示:
表 8:有/无额外训练数据的结果,此处使用的模型是 ALBERT-base。
研究者还注意到,即使在训练了 100 万步之后,最大的模型仍然没有过拟合。因此,他们决定删除 dropout,以进一步提高模型能力。如下图 3b 所示,去掉 dropout 可以显著提高 MLM 准确度。
表 9:移除 dropout 前后的结果,此处使用的模型是 ALBERT-xxlarge。
除了上述实验之外,ALBERT 在 GLUE、SQuAD 和 RACE 基准测试中都取得了 SOTA 结果,如下图 10、11 所示: