一、概述
NLP 领域中只有小部分标注过的数据,而有大量的数据是未标注,如何只使用标注数据将会大大影响深度学习的性能,所以为了充分利用大量未标注的原始文本数据,需要利用无监督学习来从文本中提取特征,最经典的例子莫过于词嵌入技术。但是词嵌入只能 word-level 级别的任务(同义词等),没法解决句子、句对级别的任务(翻译、推理等)。出现这种问题原因有两个:
- 首先,是因为不清楚要下游任务,所以也就没法针对性的进行行优化;
- 其次,就算知道了下游任务,如果每次都要大改模型也会得不偿失。
为了解决以上问题,作者提出了 GPT 框架,用一种半监督学习的方法来完成语言理解任务,GPT 的训练过程分为两个阶段:无监督Pre-training 和 有监督Fine-tuning。目的是在于学习一种通用的 Representation 方法,针对不同种类的任务只需略作修改便能适应。
接下来我们详细介绍下 GPT。
二、GPT
GPT 训练过程分为两个阶段:
第一个阶段是 Pre-training 阶段,主要利用大型语料库完成非监督学习;
第二阶段是 Fine-tuning,针对特定任务在相应数据集中进行监督学习,通过 Fine-tuning 技术来适配具体任务。
下图为 GPT 的架构图:
1) Pre-training
从上图我们可以看出,GPT 采用 Transformer 来代替 LSTM 作为特征提取器,并基于语言模型进行训练(即根据前面的词预测后面的词)。这里只使用了 Transformer 的 Decoder 部分,并且每个子层只有一个 Masked Multi Self-Attention(768 维向量和 12 个 Attention Head)和一个 Feed Forward,共叠加使用了 12 层的 Decoder。
这里简单解释下为什么只用 Decoder 部分:语言模型是利用上文预测下一个单词的,因为 Decoder 使用了 Masked Multi Self-Attention 屏蔽了单词的后面内容,所以 Decoder 是现成的语言模型。又因为没有使用 Encoder,所以也就不需要 encoder-decoder attention 了。
对于给定的非监督语料库的 Token 序列 U={u1,u2,...,un} ,基于语言模型的目标函数:
其中,k 是上下文窗口的大小,P 为条件概率,θ 为条件概率的参数,参数更新采用 SGD。
GPT 输入文本和位置 Embedding(采用使用 one-hot 编码),经过 12 层的 Transformer 的 Decoder 后通过 Softmax 得到输出:
其中, U={u-k,...,u-1}是当前单词的前面 k 个 Token,n 为神经网络的层数,We是 Token 的 Embedding 矩阵, Wp是位置编码的 Embedding 矩阵,在GPT中,作者对position embedding矩阵进行随机初始化,并让模型自己学习,而不是采用正弦余弦函数进行计算。
举例解释GPT的预训练:
比如:原文本序列是【1,2,3,4,5】,在训练的时候就错开一位进行训练,输入就是【SEP,1,2,3,4,5】,输出就是【1,2,3,4,5,EOS】,这样其实每一位的输出就只依赖于前面的一位,个人理解相当于上下文窗口为1了,也就是变成bigram模型(二元模型)了。参考n-gram模型https://www.jianshu.com/p/e0598adb07ad
2)Fine-tuning
完成预训练后,我们会得到一个训练好的 Transformer 模型,接下来我们要用这个训练好的模型来完成特定的监督学习的任务。
假设我们有个带标签的数据集 C,即每一个 Token 序列 x1,x2,...,xm 都有一个标签 y。我们将 Token 序列输入,并通过 Transformer 模型得到输出的状态 hlm,然后把这个加到线性层进行输出并预测标签 y:
其中, Wy是线性层的权重。
所以针对该监督学习,我们也有新的目标函数:
另外,将预训练好的语言模型作为辅助目标进行 Fine-tuning 不仅可以使监督模型更具泛化性,还可以加速收敛。于是我们有:
其中, λ为权重,一般设置为0.5。