GPT

GPT全称为Generative Pre-trained Transformer,它运用了Transformer中的Decoder架构,并经过大规模的无监督预练习来提高模型的表现力。在预练习阶段,GPT经过处理很多的无标示文本数据,学习到了言语的统计规则和上下文信息。在实践应用时,GPT能够经过微调(fine-tuning)的方式,依据具体使命的需求,对预练习的模型进行细小的调整,从而习惯不同的文本生成、问答等使命。GPT在自然言语生成和处理使命上表现出色,在多个公开数据集上都取得了很好的成绩。如果对于Transformer架构不是很熟悉,[能够参阅我的这篇文章](Transformer导论之Transformer – ())。

无监督的预练习

GPT的无监督预练习便是让模型自己学习言语的规则和上下文信息,而无需人为标示数据。在预练习阶段,GPT运用了很多的无标示文本数据进行练习,例如维基百科、互联网新闻等大规模语料库。GPT将这些文本数据输入到模型中,经过不断地学习言语中的统计规则和上下文信息,提高模型的表现力。

在这个阶段中,GPT最早期运用的是一种基于自回归模型的言语模型,它经过最大化给定输入序列的下一个单词呈现的概率来预练习模型。

自回归模型的方针是最大化模型对无标示文本数据的似然性,即最大化模型在给定无标示文本数据下的对数似然函数。咱们期望练习出来的模型能够在当时输入文本序列的基础上,猜测下一个单词呈现的概率。而猜测概率的一个重要方针便是似然性,即当时模型猜测的结果与实践观测值之间的类似程度。

Transformer导论之GPT

假定咱们有一个无标示文本数据集D=x1,x2,…,xND = {x_1, x_2, …, x_N},其间每个xix_i是一个长度TiT_i的文本序列,而模型的参数为\theta。假定咱们的模型能够将xix_i中的每个单词表明为wi,1,wi,2,…,wi,Ti{w_{i,1}, w_{i,2}, …, w_{i,T_i}},那么模型对于xix_i的对数似然函数能够表明为:

log⁡p(xi∣)=∑t=1Tilog⁡p(wi,t∣wi,<t,)\log p(x_i|\theta)=\sum_{t=1}^{T_i}\log p(w_{i,t}|w_{i,<t},\theta)

其间,p(wi,t∣wi,<t,)p(w_{i,t}|w_{i, <t},\theta)表明给定上文wi,<tw_{i, <t}的情况下,模型对于wi,tw_{i,t}的条件概率散布。这种基于自回归的方法使得GPT 只需求一个 decoder,它就能够依据前面已经生成的单词来猜测下一个单词,生成整个言语模型。这一点和Bert便是不同的,Bert选用的是encoder架构。

Transformer导论之GPT

在GPT2,GPT3中在预练习阶段还引入了掩码言语模型(MLM,Masked Language Model,和Bert中的相同)

MLM的方针是在输入序列中随机隐瞒一些单词,并让模型猜测这些被隐瞒的单词。

掩码言语模型(Masked Language Model,MLM)的似然函数表明为:

LMLM=∏i=1NP(wi∣w<i,w>i)L_{MLM}=\prod_{i=1}^{N}P(w_{i}|w_{<i},w_{>i})

其间,wiw_{i}表明第ii个位置的被遮盖的单词,通常在文本顶用一个特殊符号“[MASK]”符号,w<iw_{<i}表明第ii个位置之前的单词序列,w>iw_{>i}表明第ii个位置之后的单词序列,NN表明文本序列的长度。这些都是经过多层级联的Transformer的decoder完结的。经过梯度下降的练习方法,能够使得似然函数最大。

Transformer导论之GPT

有监督的微调

GPT中的Supervised fine-tuning是指在完结了无监督的预练习后,运用有标示数据对模型进行有监督的微调,以习惯特定的下流使命。

假定咱们有一个已经预练习好的GPT模型,它的参数为\theta。现在,咱们想将这个模型应用于一个下流使命,例如文本分类使命。在文本分类使命中,咱们有一个由NN个样本组成的练习集,其间第ii个样本的输入为xix_i,对应的标签为yiy_i

Transformer导论之GPT
在进行Supervised fine-tuning时,咱们需求对GPT模型进行微调,以习惯特定的下流使命。咱们能够将GPT模型的输出层进行修改,例如增加一个全衔接层,并将其衔接到GPT模型的最终一个躲藏层。咱们能够将这个修改后的模型表明为GPTft(⋅;ft)GPT_{\text{ft}}(\cdot;\theta_{\text{ft}}),其间ft\theta_{\text{ft}}是微调后的参数。

对于文本分类使命,咱们能够界说一个丢失函数LclsL_{\text{cls}},cls代表输入的初步,丢失函数用于衡量模型在分类使命上的性能。常见的丢失函数包含穿插熵丢失和均方差错丢失等。咱们的方针是最小化丢失函数LclsL_{\text{cls}},以习惯特定的下流使命。咱们能够经过以下进程来完结Supervised fine-tuning:

  1. 将预练习好的GPT模型的输出层进行修改,得到修改后的模型GPTft(⋅;ft)GPT_{\text{ft}}(\cdot;\theta_{\text{ft}})
  2. 在练习集上对修改后的模型进行练习,这儿和预练习的文本调集不同,Fine-Tuning运用的是带有标签的数据集,如情感分类、文本生成、问答等使命的标示数据集,而预练习的调集是无标签的。最小化丢失函数LclsL_{\text{cls}}。能够运用随机梯度下降等优化算法进行练习。
  3. 微调完结后,运用测验集对模型进行评价,并计算模型在下流使命上的性能方针,例如准确率、F1值等。

Supervised fine-tuning的数学表明能够如下表明:

min⁡ft1N∑i=1NLcls(GPTft(xi;ft),yi)\min_{\theta_{\mathrm{ft}}}\frac{1}{N}\sum_{i=1}^N L_{\mathrm{cls}}(GPT_{\mathrm{ft}}(x_i;\theta_{\mathrm{ft}}),y_i)\quad\quad\text{}

其间,Lcls(⋅,⋅)L_{\text{cls}}(\cdot, \cdot)表明分类使命的丢失函数,xix_i表明第ii个样本的输入,yiy_i表明第ii个样本的标签。咱们的方针是找到微调后的参数ft\theta_{\text{ft}},使得模型在练习集上的丢失函数最小。

在 Improving Language Understanding by Generative Pre-Training 这篇论文中,作者提出了一种自习惯的学习率战略,用于在 GPT 中进行练习。练习的进程中只用到了1212层的decoder网络。

GPT的pytorch完结

首要,需求导入需求用到的库和模块:

import torch
import torch.nn as nn
from torch.nn import functional as F

接下来,界说GPT模型的首要组成部分——Transformer Decoder。这儿咱们参阅GPT-2,运用12个Transformer Decoder来构建整个模型。在每个Transformer Decoder中,都包含一个多头自注意力机制(multi-head self-attention),一个前馈神经网络(feedforward neural network)和一个残差衔接(residual connection):

class TransformerDecoder(nn.Module):
    def __init__(self, hidden_dim, num_heads, ff_dim, dropout):
        super().__init__()
        self.multihead_attn = nn.MultiheadAttention(hidden_dim, num_heads)
        self.dropout1 = nn.Dropout(dropout)
        self.layer_norm1 = nn.LayerNorm(hidden_dim)
        self.ff = nn.Sequential(
            nn.Linear(hidden_dim, ff_dim),
            nn.ReLU(),
            nn.Dropout(dropout),
            nn.Linear(ff_dim, hidden_dim),
        )
        self.dropout2 = nn.Dropout(dropout)
        self.layer_norm2 = nn.LayerNorm(hidden_dim)
    def forward(self, x, mask):
        # Multi-head self-attention
        attn_out, _ = self.multihead_attn(x, x, x, attn_mask=mask)
        attn_out = self.dropout1(attn_out)
        x = self.layer_norm1(x + attn_out)
        # Feedforward neural network
        ff_out = self.ff(x)
        ff_out = self.dropout2(ff_out)
        x = self.layer_norm2(x + ff_out)
        return x

接下来,咱们将这些Transformer Decoder串联起来,构成整个GPT模型:

class GPT(nn.Module):
    def __init__(self, num_tokens, hidden_dim, num_heads, num_layers, seq_len, dropout):
        super().__init__()
        self.token_emb = nn.Embedding(num_tokens, hidden_dim)
        self.pos_emb = nn.Parameter(torch.zeros(1, seq_len, hidden_dim))
        self.dropout = nn.Dropout(dropout)
        self.decoders = nn.ModuleList([
            TransformerDecoder(hidden_dim, num_heads, hidden_dim * 4, dropout)
            for _ in range(num_layers)
        ])
        self.output_layer = nn.Linear(hidden_dim, num_tokens)
        self.softmax = nn.Softmax(dim=-1)
    def forward(self, x):
        # Token embeddings
        x = self.token_emb(x)
        # Add position embeddings
        x += self.pos_emb[:, :x.shape[1]]
        # Transformer Decoder layers
        mask = torch.triu(torch.ones(x.shape[1], x.shape[1]), diagonal=1).bool().to(x.device)
        for decoder in self.decoders:
            x = decoder(x, mask)
        # Output layer
        x = self.output_layer(x)
        x = self.softmax(x)
        return x

最终,咱们能够界说练习进程,包含丢失函数、优化器等:

model = GPT(num_tokens, hidden_dim, num_heads, num_layers, seq_len, dropout)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
for epoch in range(num_epochs):
    for inputs, labels in dat