赞
踩
在预训练语言模型出现之前,统计语言模型(如N-gram模型)是主流方法。这些模型利用统计方法来预测文本中的下一个词,但它们对长距离依赖和上下文理解能力有限。
2013年,Google提出的Word2Vec模型利用神经网络来学习词的分布式表示(词向量),使得相似词在向量空间中彼此接近。这是预训练词嵌入技术的开端。斯坦福大学提出的GloVe(Global Vectors for Word Representation)模型通过结合全局词共现统计信息来生成词向量,进一步提升了词表示的质量。
2018年,ELMo(Embeddings from Language Models)由AllenNLP团队提出,它通过双向LSTM来生成上下文感知的词表示。这标志着从静态词向量到动态上下文词向量的转变。2017年,Google提出的Transformer模型引入了自注意力机制,极大地提升了处理长距离依赖和并行计算的能力,为后续的大规模预训练模型奠定了基础。2018年,Google提出BERT(Bidirectional Encoder Representations from Transformers),它是首个双向Transformer模型,能够利用句子中所有词的上下文信息进行预训练。BERT在多项NLP任务中取得了显著的效果。2018年,OpenAI提出的GPT(Generative Pre-trained Transformer)采用了单向Transformer结构,通过生成式任务进行预训练。GPT-2(2019)和GPT-3(2020)进一步扩大了模型规模,展示了预训练模型在生成任务中的强大能力。2019,Google提出的T5(Text-To-Text Transfer Transformer)将各种NLP任务统一为文本到文本的格式,展示了预训练模型在多任务学习中的潜力。
Deep contextualized word representations
ELMo(Embeddings from Language Models)是由AllenNLP团队在2018年提出的一种预训练语言模型。它是首个通过上下文感知的词嵌入来显著提升自然语言处理任务性能的模型之一。
ELMo的核心思想是生成上下文感知的词表示,这意味着同一个词在不同的上下文中会有不同的表示。传统的词嵌入方法(如Word2Vec和GloVe)生成的是固定的词向量,而ELMo则通过考虑句子的上下文,使得词表示更加动态和灵活。
ELMo的训练过程包括以下步骤:
双向语言模型:
p ( t 1 , t 2 , ⋯ , t N ) = ∑ k = 1 N p ( t k ∣ t 1 , t 2 , ⋯ , t k − 1 ) p ( t 1 , t 2 , ⋯ , t N ) = ∑ k = 1 N p ( t k ∣ t k + 1 , t t + 2 , ⋯ , t N ) p(t1,t2,⋯,tN)=N∑k=1p(tk|t1,t2,⋯,tk−1)p(t1,t2,⋯,tN)=N∑k=1p(tk|tk+1,tt+2,⋯,tN) p(t1,t2,⋯,tN)p(t1,t2,⋯,tN)=k=1∑Np(tk∣t1,t2,⋯,tk−1)=k=1∑Np(tk∣tk+1,tt+2,⋯,tN)
目标函数:
∑ k = 1 N ( log p ( t k ∣ t 1 , ⋯ , t k − 1 ; Θ x , Θ → L S T M , Θ s ) + log p ( t k ∣ t k + 1 , ⋯ , t N ; Θ x , Θ ← L S T M , Θ s ) ) N∑k=1(logp(tk|t1,⋯,tk−1;Θx,→ΘLSTM,Θs)+logp(tk|tk+1,⋯,tN;Θx,←ΘLSTM,Θs)) k=1∑N(logp(tk∣t1,⋯,tk−1;Θx,Θ LSTM,Θs)+logp(tk∣tk+1,⋯,tN;Θx,Θ LSTM,Θs))
ELMo 的计算流程:
R k = { x k L M , h → k j L M , h ← k j L M ∣ j = 1 , ⋯ , L } = { h k , j L M ∣ j = 1 , ⋯ , L } Rk={xLMk,→hLMkj,←hLMkj|j=1,⋯,L}={hLMk,j|j=1,⋯,L} Rk={xkLM,h kjLM,h kjLM∣j=1,⋯,L}={hk,jLM∣j=1,⋯,L}
ELMo k t a s k = E ( R k ; Θ t a s k ) = γ t a s k ∑ j = 0 L s j t a s k h k , j L M ELMotaskk=E(Rk;Θtask)=γtaskL∑j=0staskjhLMk,j ELMoktask=E(Rk;Θtask)=γtaskj=0∑Lsjtaskhk,jLM
ELMo的优势:
Improving Language Understanding by Generative Pre-Training
GPT(Generative Pre-trained Transformer)是由OpenAI提出的一系列预训练语言模型,这些模型在自然语言生成和理解任务中表现出了卓越的能力。GPT系列包括GPT、GPT-2、GPT-3和GPT-4,每一代都在规模和性能上有显著提升。
GPT模型的核心架构基于Transformer的解码器部分,专注于生成式任务。与BERT不同,GPT采用单向的自回归方法,即在生成当前词时仅依赖于左侧的上下文。GPT的预训练任务是语言建模,即通过预测序列中的下一个词来训练模型。这种自回归的方法使得GPT能够生成连贯和上下文相关的文本。
GPT的架构特点如下:
GPT的训练分为两个阶段:
预训练阶段损失函数:
L 1 ( U ) = ∑ i log P ( u i ∣ u i − k , ⋯ , u i − 1 ; Θ ) L_1(\mathcal{U}) = \sum_i \log P(u_i | u_{i-k}, \cdots, u_{i-1}; \Theta) L1(U)=i∑logP(ui∣ui−k,⋯,ui−1;Θ)
GPT的前向计算过程:
h 0 = U W e + W p h l = transformer_block ( h i − 1 ) , ∀ i ∈ [ 1 , n ] P ( u ) = softmax ( h n W e T ) h0=UWe+Wphl=transformer\_block(hi−1),∀i∈[1,n]P(u)=softmax(hnWTe) h0hlP(u)=UWe+Wp=transformer_block(hi−1),∀i∈[1,n]=softmax(hnWeT)
GPT微调的前向计算,需要在最后一层隐藏层再额外增加一层线性层:
P ( y ∣ x 1 , ⋯ , x m ) = softmax ( h l m W y ) P(y|x^1, \cdots, x^m) = \text{softmax}(h_l^m W_y) P(y∣x1,⋯,xm)=softmax(hlmWy)
微调阶段损失函数:
L 2 ( C ) = ∑ ( x , y ) log P ( y ∣ x 1 , ⋯ , x m ) L_2(\mathcal{C}) = \sum_{(x,y)} \log P(y|x^1, \cdots, x^m) L2(C)=(x,y)∑logP(y∣x1,⋯,xm)
实验发现将语言建模作为模型微调的辅助目标,可以改善监督模型的泛化能力,即在未见过的数据上表现更好,并且可以加快模型的收敛速度。即新的目标函数集合了预训练和微调两个阶段的损失函数:
L 3 ( C ) = L 2 ( C ) + λ L 1 ( C ) L_3(\mathcal{C}) = L_2(\mathcal{C}) + \lambda L_1(\mathcal{C}) L3(C)=L2(C)+λL1(C)
GPT的优势:
GPT的限制:
BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
BERT(Bidirectional Encoder Representations from Transformers)是由Google在2018年提出的一种预训练语言模型,它在自然语言处理任务中引入了革命性的进步。BERT的设计使得它能够在多种NLP任务上实现显著的性能提升。
BERT的核心创新是其双向Transformer架构,这使得模型可以同时考虑上下文中的前后信息,从而生成更加准确和丰富的词表示。BERT的架构基于Transformer的编码器部分,具体特点如下:
BERT通过两个主要任务进行预训练:
BERT的训练分为两个阶段:
BERT的优势:
BERT的影响:
Sequence to Sequence Learning with Neural Networks
Seq2Seq(Sequence to Sequence,序列到序列)模型是一类用于处理序列数据的模型,特别适用于需要将一个序列转换为另一个序列的任务。该模型最初由Ilya Sutskever等人在2014年提出,广泛应用于机器翻译、文本摘要、对话系统等领域。
Seq2Seq模型主要由两个部分组成:编码器(Encoder)和解码器(Decoder)。
编码器的作用是将输入序列编码成一个固定长度的上下文向量(context vector)。编码器通常采用RNN如LSTM或GRU。其过程如下:
解码器的任务是根据上下文向量生成目标序列。解码器同样采用RNN结构,其过程如下:
早期的Seq2Seq模型存在一个问题,即只能依赖固定长度的上下文向量,这在处理长序列时效果不佳。为了解决这个问题,Bahdanau等人在2015年引入了注意力机制。注意力机制允许解码器在生成每个输出时,动态地关注输入序列的不同部分。具体来说:对于解码器的每个时间步,计算一组注意力权重,这些权重表示当前时间步应关注编码器输出的哪些部分。使用这些权重计算一个加权和,作为当前时间步的上下文向量。
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
class Seq2Seq(nn.Module):
def __init__(self, input_dim, output_dim, hidden_dim, n_layers):
super(Seq2Seq, self).__init__()
self.encoder = nn.LSTM(input_dim, hidden_dim, n_layers, batch_first=True)
self.decoder = nn.LSTM(output_dim, hidden_dim, n_layers, batch_first=True)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, src, tgt):
# 编码器
_, (hidden, cell) = self.encoder(src)
# 解码器
outputs, _ = self.decoder(tgt, (hidden, cell))
# 全连接层
predictions = self.fc(outputs)
return predictions
# 超参数
input_dim = 10 # 输入的特征维度
output_dim = 10 # 输出的特征维度
hidden_dim = 16 # 隐藏层维度
n_layers = 2 # LSTM层数
seq_len = 5 # 序列长度
batch_size = 2 # 批次大小
# 创建示例数据(随机生成)
np.random.seed(0)
torch.manual_seed(0)
src_data = torch.randn(batch_size, seq_len, input_dim) # 输入序列
tgt_data = torch.randn(batch_size, seq_len, output_dim) # 目标序列
# 打印数据形状
print("Source data shape:", src_data.shape)
print("Target data shape:", tgt_data.shape)
# 初始化模型、损失函数和优化器
model = Seq2Seq(input_dim, output_dim, hidden_dim, n_layers)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
n_epochs = 100
for epoch in range(n_epochs):
model.train()
optimizer.zero_grad()
output = model(src_data, tgt_data)
loss = criterion(output, tgt_data)
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch + 1}/{n_epochs}], Loss: {loss.item():.4f}')
Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer
T5(Text-To-Text Transfer Transformer)是由Google Research提出的一种基于Transformer架构的预训练模型,旨在统一处理各种自然语言处理(NLP)任务。T5的核心理念是将所有的NLP任务都视为一个文本到文本的转换问题,这样可以使用同一个模型框架处理不同的任务,比如机器翻译、文本摘要、问答系统等。
T5模型的一个重要特点是将所有任务都转换为文本到文本的形式。例如:
T5基于标准的Transformer模型,采用了全连接的自注意力机制,可以高效地处理序列数据。Transformer模型包括编码器和解码器两个部分,T5使用的是完整的编码器-解码器架构。T5在一个名为C4(Colossal Clean Crawled Corpus)的数据集上进行了大规模的预训练。C4数据集包含了从互联网收集的大量文本,经过清洗和过滤后用于模型训练。T5的预训练任务是“填空”(fill-in-the-blank),即在输入文本中随机遮蔽部分单词,并让模型预测这些被遮蔽的单词。在预训练之后,T5通过多任务学习对多个下游任务进行微调。每个任务都被转换为文本到文本的形式,并通过统一的损失函数进行优化。
from transformers import T5Tokenizer, T5ForConditionalGeneration
# 加载T5模型和分词器
model_name = 't5-small'
tokenizer = T5Tokenizer.from_pretrained(model_name)
model = T5ForConditionalGeneration.from_pretrained(model_name)
# 输入文本
text = "It is reported that a major fire broke out in Victoria Harbor in Hong Kong on December 12, which injured 100 people and caused 10 billion yuan in damage"
# 将任务和输入文本结合
input_text = "summarize: " + text
# 编码输入文本
input_ids = tokenizer.encode(input_text, return_tensors='pt')
# 生成摘要
summary_ids = model.generate(input_ids, max_length=50, num_beams=2, early_stopping=True)
# 解码生成的摘要
summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True)
print("Summary:", summary)
BART(Bidirectional and Auto-Regressive Transformers)是由Facebook AI Research(FAIR)提出的一种序列到序列(Seq2Seq)模型。BART结合了BERT(Bidirectional Encoder Representations from Transformers)和GPT(Generative Pre-trained Transformer)的优点,通过双向编码器和自回归解码器进行预训练和微调。BART在文本生成任务(如文本摘要、机器翻译和文本生成)以及其他NLP任务上表现出色。
BART的架构基于标准的Transformer编码器-解码器架构,但它在设计上具有一些独特之处:
BART的预训练任务旨在让模型学习如何恢复被破坏的输入序列。具体来说,BART采用了一种“去噪自编码器”(Denoising Autoencoder)的预训练方法,模型需要从损坏的输入中恢复原始文本。预训练任务包括:
Neural Machine Translation of Rare Words with Subword Units
Byte Pair Encoding is Suboptimal for Language Model Pretraining
Tokenization(分词)是将输入文本转换为模型可以处理的格式的关键步骤。Tokenization的好坏直接影响模型的性能和效果。
Tokenization是将输入的自然语言文本拆分为更小的单位(token),这些单位可以是单词、子词或字符等。对于大多数现代大模型而言,tokenization过程包括以下步骤:
常见的Tokenization方法:
text = "The quick brown fox jumps over the lazy dog."
tokens = text.split()
# ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
text = "hello"
tokens = list(text)
# ['h', 'e', 'l', 'l', 'o']
BPE(Byte Pair Encoding)是一种基于频率的子词分词算法。BPE通过逐步合并出现频率最高的字符对来创建子词单元,从而生成子词词典。BPE将文本拆分为子词单元,这些子词单元可以是字符、部分单词或整个单词。这种方法可以有效地处理未见过的词汇,提高模型的泛化能力。BPE通过逐步合并出现频率最高的字符对来生成子词单元。每次合并后,频率最高的字符对变成一个新的子词单元,直到达到预定的词汇表大小。
BPE算法步骤:
WordPiece和BPE的流程几乎一致,主要的区别在于,BPE每次按照出现频数最高这一原则来选取pair,而WordPiece则是按照能够最大
限度提升语言模型概率这一原则来选取pair。
BPE和WordPiece都是从一个小的基础词表开始不断去扩充这个词表表,而Unigram则与之相反,Unigram会先初始化一个大的词表,然后
不断从中删去子词直至词表达到指定的大小。Unigram初始化词表的方式有很多种,例如我们可以在预分词的结果上应用BPE算法并设置较大的merges以获得初始词表,或者计算预分词结果的所有严格子串并从中选取一些出现频率最高的子串作为初始词表。
SentencePiece是一个通用的文本分词和子词化库,它结合了BPE和WordPiece的优点,并支持多种分词算法。SentencePiece可以根据任务需求选择合适的分词方法,包括BPE、Unigram等。它提供了一个统一的接口,使得使用不同的分词方法变得更加方便和灵活。SentencePiece还支持自定义的标记化规则和训练参数,可以适应各种语言和文本类型的需求。
模型的tokenization过程通常包括一些特殊token,用于处理特定任务和文本边界:
from transformers import BertTokenizer
# 加载BERT分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 输入文本
text = "The quick brown fox jumps over the lazy dog."
# 分词
tokens = tokenizer.tokenize(text)
print(tokens)
# ['the', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog', '.']
# 编码
input_ids = tokenizer.encode(text, add_special_tokens=True)
print(input_ids)
# [101, 1996, 4248, 2829, 4419, 2169, 2058, 1996, 13971, 3899, 1012, 102]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。