GPT-2解读(论文 + TensorFlow实现)

GPT-2是对GPT的一个升级,并且更着重于将思路放在为何pretrain是有用的上面,认为LM本身是一个Multi-task Learner,并且大力用ZSL实验来佐证这个思路。

一. 前言

GPT-2相比于GPT,笔者感觉主要有三点改进:1)大数据;2)大模型;3)很好的一个insight观点。还不熟悉GPT的读者可以戳这里

前两点就不用说了,最后一点其实在GPT-2的论文题目中就已经体现出来了,也是贯彻全文的一个重要观点:《Language Models are Unsupervised Multitask Learners》,不像是之前的讲Pretrain+Finetune的论文,都只是套用了这个思路,然后实验说:哦这样很好,而没有一个理论层面的升华。

这篇GPT-2,笔者看下来,感觉对NLP领域中pretrain+finetune这一套流程为啥有用,又有了些不一样的认识。

笔者自己对于这个观点的理解就是:一般之前对于pretrain为何有用的解释都是猜测说,找到了一个很好的初始化点。这里是认为LM在学习的过程中,自然能学到那些有监督任务所需要的信息,即LM本身就是一个无监督的多任务学习者,也就能证明为何pretrain对后面的任务是有用的,即为何能找到一个很好的初始化点。更具体一些,论文中提到有监督的任务其实都只是语言模型序列中的一个子集,这里笔者脑补了一些例子,比如对于“The translation of apple in Chinese is 苹果”这个序列进行LM建模,自然能学到翻译的知识;对于“姚明的身高是2.26米”这个序列进行建模,自然能学到问答相关的知识,诸如此类。。

二. GPT-2原理

理解了上面的思路之后,就可以来看GPT-2的原理了,虽然原理上没有太多的创新。这里主要讲相比于GPT的改进点。

1. 数据集

作者从网上爬了一大堆语料,用来进行LM的pretrain,他们最后的数据集叫WebText,有800万左右的文档,40G的文本,并且还移除了Wikipedia的数据,因为后面要ZSL的任务里面有很多都是基于Wikipedia的语料的,这里其实就是保证了ZSL任务的前提。

PS:ZSL就是Zero-shot Learning。

2. 输入表征

对于输入的text不做任何的预处理(比如大小写转换啊,切分啊这种的),直接弄成bpe扔进去。

3. 模型

基本还是与GPT一致,但将LayerNorm移到了每层的输入,并且在最后一层attention后面加上了LayerNorm。同时在residual层初始化的时候,将其乘了 1 / N 1/\sqrt{N} 1/N ,这里的N是residual的层数(这里没看懂?有大神看懂可以解答一下,residual不就是一个相加?哪里有参数?)。词表扩大到了50257。上下文长度从512扩展到1024;batchsize扩大到512。

三. 实验

作者用了几种不同size的模型,见下图:

作者指出的是,最小的模型就是GPT,第二小的与大BERT是一个量级,最大的模型称为GPT-2。**所有的model,在LM训练的时候,都处于欠拟合的状态。**说明他们爬的这个大数据还是很好的!

作者直接将这个pretrain的模型,不用finetune的跑了各个下游的NLP任务,即ZSL设定,结果如下:

这里的WikiText2、PTB、enwiki8、text8、WikiText103、1BW是几个测试语言模型的数据集;LAMBADA是测试建模长句子能力的数据集,用于预测一句话的最后一个词;CBT是用于检验在不同类型的词上LM的表现,主要是Cloze任务。

作者还测试了一些其他的任务,比如推理的任务Winograd Schema Challange,结果如下:

还有阅读理解CoQA、摘要、翻译、QA等任务,比如摘要的结果:

最后,作者还给出了一个说明训练难度的表格,用于说明这些任务的训练集与测试集的文本重合度比较高,所以SoTA的效果要打一些折扣,而GPT-2这里用到的训练数据则与测试集重合度较低,所以就更能说明GPT-2的提升效果啦!

四. TensorFlow实现

看源码的意思,好像与GPT一样,也是没有放出pretrain的训练代码,而且在例子上也只是给出了文本续写的部分。但依然不影响笔者想一探究竟,那么这里就从pretrain的模型结构和文本续写的generate来讲吧。其实,按照GPT-2本身论文的侧重点,是想证明pretrain的LM就可以用ZSL完成其他的任务,因此,这里给出的这两部分源码其实对于实际应用来说也足够了!

1. 模型结构

在模型结构上,主体还是与GPT很像,都是transformer的decoder形式,只不过在规模上扩大了,其具体代码如下:

def model(hparams, X, past=None, scope='model', reuse=False):
    with tf.variable_scope(scope, reuse=reuse):
        results = {
   
   }
        batch, sequence = shape_list(X)

        # Embedding
        wpe = tf.get_variable('wpe', [hparams.n_ctx, hparams.n_embd],
                             initializer=tf.random_normal_initializer(stddev=0.01))
        wte = tf.get_variable('wte', [hparams.n_vocab, hparams.n_embd],
                             initializer=tf.
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值