论文地址:《Improving Language Understanding by Generative Pre-Training》
最近一直忙着打比赛,好久没更文了。这两天突然想再回顾一下GPT-1和GPT-2的论文, 于是花时间又整理了一下,也作为一个记录~话不多说,让我们一起来品读一下GPT经典之作吧!
Abstract
摘要部分其实是介绍了一下GPT研究的动机,值得一提的是,GPT可以算是预训练+微调这种范式在NLP领域成功应用的先河,它比BERT还早几个月。摘要中提到,无标注数据是很多的,但是特定领域带标数据匮乏,这对于许多NLP任务中模型的训练是一个很大的挑战。 接下来作者提到了他们的解决方案:先在大规模无标注数据集上训练一个预训练模型,接着再将此预训练模型放到特定任务中用少量数据微调。这个方案放在现在来看,再熟悉不过了,但是在当时,这种方法确实是新颖之作,因为在此之前,利用无标注数据建模的先例有著名的Word2Vector,但具体到下游任务,基本上都是特定任务特别训练,这里作者也提到了,对比前人的工作,他们方法的不同之处在于微调的时候直接构造和任务相关的输入进行的,换句话说,直接从输入形式来区分不同的任务,这样一来,他们只需要对模型结构做微小的改动就能达到想要的效果。
1 Instruction
第一段总结来说,作者提到了无监督训练方式的重要性,能够有效的从原始训练语料中(通常认为是无标注的)学习的能力可以减轻模型对于下游有监督训练的依赖性,作者认为,即使在可以进行有监督学习的场景下,使用无监督的方式学到很好的语言表征也会让模型的表现更好。这一点在近两年的许多研究成果中也得到了印证。
这一段作者提到了从无标注数据中学习词级别信息是具有挑战性的,并且列举了产生挑战性的两点原因:
(1)优化目标不统一。也就是说,对于无监督训练来讲,可以设计出诸多不同的优化目标,但是究竟哪种类型的优化目标是有效的,目前还不清晰。显然,作者提了一个很好的问题,Bert、GPT、Bart、T5、XLNet等等,它们的建模过程都要经历无监督训练阶段,它们无监督预训练所设计的训练目标不尽相同,比如bert采用了LM和NSP的预训练方式,Bart去掉了NSP,还增加了文档旋转,子序列掩码等预训练方式,XLNet更是采用了类似排列组合的预训练方式,它们都不完全一样,也都取得了很好的效果。可是究竟哪一种或者哪几种方式才最有效,目前尚不清楚(截止该论文)。
(2)如何有效的将学习到的文本表示迁移到下游特定任务中目前业界还没有一个共识。说白了,就是目前业界还没有得出一个结论,什么结论呢?就是如何利用预训练语言模型进行下游任务的微调是最有效的,通常都需要根据不同下游任务做一些模型结构上的改动。
作者认为这两点不确定使得半监督学习技术的发展遇到了很大的困难,作者在这里提到了半监督学习,其实就是“无监督预训练+有监督微调”。
这段话其实阐述了一下作者提出的一种半监督学习方式,总的来说,他们的半监督学习方式虽然也是无监督预训练+下游微调两步走的方式,但是他们在下游微调任务上,采用的是带有手动注释(也就是提示)的样例学习来将无监督学习到的表示嵌入到不同的下游任务中。这就是后来的提示学习。
作者说明了一下模型架构的选择,之所以选择Transformer作为基模,作者认为,还是因为transformer强大的序列特征提取能力。这段没啥说的。
这一段其实就是作者说了一下他们的方法在几个NLP任务上的效果,在12个任务中有9个任务都达到了sota的效果。值得注意的是,作者提到了零样本学习,看来作者们在GPT-1的时候就已经在思考这一思路了,果然大牛都是提前布局。
2 Related Work
这一章节主要介绍了与作者所研究的相关的先前工作。它介绍了半监督学习在自然语言处理中的应用,并提到了使用无标签数据进行词级别和短语级别的统计计算以及使用词嵌入来改善性能的方法。此外,作者还提到了无监督学习是半监督学习的一种特殊情况,其目标是寻找一个好的初始化方法来避免对监督学习过程中的目标进行改动,简而言之就是,通过无监督学习的方法就能够使得文本表示很好的迁移到下游任务中,而不是来一个下游任务就设置一个学习目标,这太繁琐了。与其他方法相比,作者选择了Transformer模型,并使用任务特定的输入转换来适应不同的任务,以实现有效的迁移学习。
3 Framework
这一章节比较重要,主要介绍了论文核心思想的实现方法。
3.1 Unsupervised Pre-training
GPT-1的思路其实就是利用了语言模型的思路,语言模型是什么呢?它其实就是通过对先验知识的条件概率计算获得预测词的这么一个东西,如上述式子,在i-1个词的出现的情况下来计算第i个词出现的概率,因为这一过程是依靠神经网络来完成的,因此上式还有个θ。
了解transformer的原理后,上式其实就很好理解,先通过词向量和位置向量来构建模型的输入,transformer_block是指transformer的各个模块,包括自注意力层,归一化层等,经过transformer各个模块计算后,最后再通过softmax来计算输出的概率分布,值得注意的是,GPT系列的模型都只用了transformer的解码器部分,并非标准的transformer,不存在类似bert的那种掩码机制,而必须是单向输出的,所以GPT-1这里,作者在无监督预训练的时候用的是滑窗机制来计算语言模型的条件概率,个人感觉这种方式在训练样本足够大的情况下,效果会比“完形填空”形式的LM掩码机制要好,而且这种形式确实更适用于生成任务。
3.2 Supervised fine-tuning
这一节介绍的是有监督微调的过程。
输入经由预训练语言模型计算后,取最有一层的向量作为微调的输入,微调就是用一个线性层将输入映射到目标任务所需要的空间中。比如我们的输入是256个词,向量维度定义为768维,那么最终Transformer的输出就是256·768,但是我们只取最后一个维度作为一句话的向量表示,即1·768,假如是二分类问题,那么我们的线性层就是768·2,这样线性映射后我们得到了一个1·2大小的向量,再做softmax后,就能得到两个概率值[p1, p2],取最大的概率值对应的索引,就得到了我们的预测值。
这个公式其实是无监督预训练和有监督微调统一训练的方法,作者用了一个λ来调节两者的平衡。作者也提到了,将无监督语言模型的学习作为有监督学习的辅助学习目标会带来两个好处,一个是改善有监督学习的性能,一个是加速收敛。
无监督预训练和有监督的微调介绍完,作者贴上了一个图来说明他们是如何将输入转化为与下游具体任务相关的输入形式的。
左边是论文提到的模型结构图,右边是具体输入输出的结构,可以看到,不同任务的输入形式也不尽相同,除了单句分类任务,其它的都有固定格式:start、text1、text2、delim、extract。要注意,start、delim和extract在实际代码中是用某些特殊符号给予标记的,从而避免了训练语料中存在这些单词。
从上图中我们可以看到后起之秀bert的影子,在bert中,针对不同任务的微调的输入输出也是像这样构造的。
3.3 Task-specific input transformations
这一节其实就是对上图的进一步解释,感兴趣的照着图看就好,这里不作重点记录。
4 Experiments
这一章将实验部分,涉及到具体模型参数的设置以及数据部分,值得品读。
4.1 Setup
GPT-1用了BooksCorpus数据集进行无监督预训练的,同时,作为其它数据集的选择,GPT-1页使用了10亿个单词的Word Benchmark,这和ELMo这个模型使用的数据集类似,只不过本文的方法是打乱了句子破坏了句子的长距离结构。说实话,我们看懂,GPT-1是只用了前一个数据集,还是两个数据集都用了,还是分开用的?
这一段是模型的参数设置,首先,前面提到过,GPT-1使用了transformer结构中的Decoder,是一个12层的解码器,解码器参数设置细节如下:
- 状态向量维度为768,注意力头数为12,这和bert是一样的。
- 在位置编码方面,使用了3072维的内部状态。
- 优化算法采用了Adam,并设置了最大学习率为2.5e-4。
- 学习率在前2000次更新中线性增加,然后使用余弦调度将其退火为0。
- 模型使用64个随机采样的连续序列的小批量数据进行训练,每个序列包含512个token。
- 模型中广泛使用了layernorm,因此简单的权重初始化N(0, 0.02)就足够了。
- 模型使用了40,000个合并的字节对编码(BPE)词汇表,并使用了残差、嵌入和注意力的dropout来进行正则化,失活率为0.1。
- 模型还使用了[37]中提出的修改版L2正则化,对所有非偏置或增益权重设置了w = 0.01。
- 激活函数使用了高斯误差线性单元(GELU)。
- 模型使用了学习的位置嵌入,而不是原始版本提出的固定正弦值。
- 使用了ftfy库来清理BooksCorpus中的原始文本,标准化一些标点符号和空白符,并使用spaCy分词器进行处理。
这是微调阶段的一些参数设置,作者大部分复用了无监督预训练阶段的参数设置方式,只有几个不同的地方:大多数任务的学习率设置为6.25e-5,batchsize设为了32,基本上迭代个3个epoch足矣。 公式(5)中的λ设为0.5。
4.2 Supervised fine-tuning
这一节主要是介绍了在几种不同任务上以及不同数据集上的实验测试和分析对比,结论是GPT-1在12种数据集中有9种数据集的表现达到了SOTA。这块内容不做重点介绍,感兴趣的可以自己看下。
5 Analysis
前面提到,GPT-1用了12层的transformer layer,作者在这里做了一个实验:层数从1-12增加,看看不同层数对于无监督预训练模型向有监督任务微调的迁移能力的影响,结果发现,12层中,每一层都对这种迁移能力的提升有正向作用。作者想说明12层的设计是正确的?
上图其实是作者想要更好的理解为什么基于transformer的预训练模型它是有效的而做的实验。作者提出了一个假设,即基础生成模型学习执行许多需要评估的任务,以提高其语言建模能力,并且transformer的更加结构化的注意力机制相对于LSTM有助于迁移学习。上图中,作者设计了一系列启发式解决方案,利用基础生成模型执行任务而无需监督微调,并证实了这些启发式解决方案在生成预训练过程中的有效性。观察到这些启发式解决方案的性能稳定,并且随着训练的进行逐渐提高,这表明生成预训练具备支持学习各种与任务相关的功能。同时观察到LSTM的零样本性能具有较高的方差,这表明Transformer架构的归纳偏差有助于迁移学习。
作者进行的三个消融实验研究。首先,作者在微调过程中没有使用辅助的语言模型目标,观察到辅助目标对NLI任务和QQP有帮助,但对较小的数据集没有帮助。其次,作者通过将Transformer与使用相同框架的单层2048单元LSTM进行比较,分析了Transformer的效果。结果显示,使用LSTM而不是Transformer时,平均得分下降了5.6。只有在一个数据集MRPC上,LSTM的表现优于Transformer。最后,作者还将他们的模型与Transformer架构直接在有监督目标任务上进行训练,即去掉无监督预训练的过程进行了比较。结果显示,缺乏预训练过程对所有任务的性能有所损害,与完整模型相比,性能下降了14.8%。
6 Conclusion
作者做了一下总结,总的来说,这篇论文提出了一个NLP领域全新的训练思路,即通过良好的无监督训练过程结合任务相关的有监督微调以达到多个NLP任务中的SOTA结果。作者的这套方案后来成为了业界主流模式,包括如今的chatGPT,可以说是开山之作。结尾处作者前瞻性的预见了在无监督训练领域仍然存在很大的潜在的研究价值,看来作者这么说了也这么做了,没有放弃,所以有了如今的chatGPT,牛!