BERT变体(1):ALBERT、RoBERTa、ELECTRA、SpanBERT

Author:龙箬

Computer Application Technology

Change the World with Data and Artificial Intelligence !

CSDN@weixin_43975035
天下之大,虽离家万里,何处不可往!何事不可为!

1. ALBERT

\qquad ALBERT的英文全称为A Lite version of BERT ,意思是BERT模型的精简版。ALBERT模型对BERT的架构做了一些改变,以尽量缩短训练时间。
\qquad 与BERT相比,ALBERT的参数更少。它使用以下两种技术减少参数的数量。

·跨层参数共享

\qquad 在跨层参数共享的情况下,不是学习所有编码器层的参数,而是只学习第一层编码器的参数,然后将第一层编码器的参数与其他所有编码器层共享。在应用跨层参数共享时有以下几种方式。

全共享: 其他编码器的所有子层共享编码器1的所有参数。
共享前馈网络层: 只将编码器1的前馈网络层的参数与其他编码器的前馈网络层共享。
共享注意力层: 只将编码器1的多头注意力层的参数与其他编码器的多头注意力层共享。

默认情况下,ALBERT使用全共享选项,也就是说,所有层共享编码器1的参数

·嵌入层参数因子分解

\qquad 我们用 V V V 表示词表的大小。BERT的词表大小为30000。我们用 V V V 表示隐藏层嵌入的大小,用 E E E 表示WordPiece嵌入的大小。
\qquad 我们将独热编码向量投射到低维嵌入空间 ( V ∗ E ) (V*E) (V∗E),然后将这个低维嵌入投射到隐藏空间 ( E ∗ H ) (E*H) (E∗H),而不是直接将词表的独热编码向量投射到隐藏空间 ( V ∗ H ) (V*H) (V∗H)。也就是说,我们不是直接投射 ( V ∗ H ) (V*H) (V∗H),而是将这一步分解为 ( V ∗ E ) (V*E) (V∗E) 和 ( E ∗ H ) (E*H) (E∗H)。
\qquad ALBERT模型是使用掩码语言模型构建任务进行预训练的,但ALBERT没有使用下句预测任务,而是使用句序预测 (sentence order prediction, SOP)这一新任务。

python 复制代码
from transformers import AlbertModel, AlbertTokenizer

model = AlbertModel.from_pretrained(pretrained_model_name_or_path='/code/AlbertModel/')
tokenizer = AlbertTokenizer.from_pretrained(pretrained_model_name_or_path='/code/AlbertModel/spiece.model')
# 模型下载地址 https://huggingface.co/albert-base-v2/tree/main
sentence = "Beijing is a beautiful city"
inputs = tokenizer(sentence, return_tensors = "pt")
print(inputs)

ALBERT模型存储路径及目录如下:

python 复制代码
#输出结果:
{'input_ids': tensor([[   2, 6579,   25,   21, 1632,  136,    3]]), 
'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0]]), 
'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1]])}
python 复制代码
# 获取模型的输出  
outputs = model(**inputs) 
  
# hidden_rep包含最后一个编码器层的所有标记的隐藏状态特征  
hidden_rep = outputs.last_hidden_state  
  
# cls_head通常是用于分类任务的输出,这里假设你的模型有这样一个输出  
cls_head = outputs.pooler_output

print(hidden_rep, cls_head)
# [CLS] BeiJing is a beautiful city [SEP]
print(hidden_rep[0][0]) # [CLS]标记的上下文嵌入
print(hidden_rep[0][1]) # Paris标记的上下文嵌入
print(hidden_rep[0][2]) # is标记的上下文嵌入
print(hidden_rep[0][6]) # [SEP]标记的上下文嵌入

2. RoBERTa

\qquad RoBERTa模型,它是Robustly Optimized BERT Pretraining Approach (稳健优化的BERT预训练方法)的简写。RoBERTa是目前最流行的BERT变体之一,它被应用于许多先进的系统。

RoBERTa本质上是BERT,它只是在预训练中有以下变化。

·在掩码语言模型构建任务中使用动态掩码而不是静态掩码。

\qquad RoBERTa使用的是动态掩码,每个句子都有不同的标记被掩盖

·不执行下句预测任务,只用掩码语言模型构建任务进行训练。

\qquad 研究人员发现,下句预测任务对于预训练BERT模型并不是真的有用,因此只需用掩码语言模型构建任务对RoBERTa模型进行预训练。

·以大批量的方式进行训练。

\qquad 用较大的批量进行训练可以提高模型的速度和性能。

·使用字节级字节对编码作为子词词元化算法
python 复制代码
from transformers import RobertaConfig, RobertaModel, RobertaTokenizer

model = RobertaModel.from_pretrained('/code/roberta-base/')
tokenizer = RobertaTokenizer.from_pretrained('/code/roberta-base/')
# 模型下载地址 https://huggingface.co/roberta-base/tree/main

RoBERTa模型存储路径及目录如下:

python 复制代码
model.config

#RoBERTa模型输出参数:
RobertaConfig {
  "_name_or_path": "/code/roberta-base/",
  "architectures": [
    "RobertaForMaskedLM"
  ],
  "attention_probs_dropout_prob": 0.1,
  "bos_token_id": 0,
  "classifier_dropout": null,
  "eos_token_id": 2,
  "hidden_act": "gelu",
  "hidden_dropout_prob": 0.1,
  "hidden_size": 768,
  "initializer_range": 0.02,
  "intermediate_size": 3072,
  "layer_norm_eps": 1e-05,
  "max_position_embeddings": 514,
  "model_type": "roberta",
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  "pad_token_id": 1,
  "position_embedding_type": "absolute",
  "transformers_version": "4.34.0",
  "type_vocab_size": 1,
  "use_cache": true,
  "vocab_size": 50265
}
python 复制代码
tokenizer.tokenize('It was a great day') # Ġ表示一个空格,RoBERTa词元分析器将所有空格替换为Ġ字符

# 输出结果:
['It', 'Ġwas', 'Ġa', 'Ġgreat', 'Ġday']
python 复制代码
tokenizer.tokenize('I had a sudden epiphany') 
# 因为epiphany不存在于词表中,所以它被分割成子词ep和iphany。我们也可以看到空格被替换成了Ġ字符

# 输出结果:
['I', 'Ġhad', 'Ġa', 'Ġsudden', 'Ġep', 'iphany']

3. ELECTRA

\qquad ELECTRA模型,它的英文全称为Efficiently Learning an Encoder that Classifies Token Replacements Accurately (高效训练编码器如何准确分类替换标记)。与其他BERT变体不同,ELECTRA使用一个生成器(generator)和一个判别器(discriminator),并使用替换标记检测这一新任务进行预训练。
\qquad ELECTRA没有使用掩码语言模型构建任务作为预训练目标,而是使用一个叫作替换标记检测的任务进行预训练。替换标记检测任务与掩码语言模型构建任务非常相似,但它不是用[MASK]标记来掩盖标记,而是用另一个标记来替换,并训练模型判断标记是实际标记还是替换后的标记。
\qquad 由于掩码语言模型构建任务在预训练时使用了[MASK]标记,但在针对下游任务的微调过程中,[MASK]标记并不存在,这导致了预训练和微调之间的不匹配。在替换标记检测任务中,我们不使用[MASK]来掩盖标记,而是用不同的标记替换另一个标记,并训练模型来判断给定的标记是实际标记还是替换后的标记。这就解决了预训练和微调之间不匹配的问题。

python 复制代码
from transformers import ElectraModel, ElectraTokenizer

model = ElectraModel.from_pretrained('/code/ElectraModel/electra-small-discriminator/')
tokenizer = ElectraTokenizer.from_pretrained('/code/ElectraModel/electra-small-discriminator/')
# 模型下载地址 
# https://huggingface.co/google/electra-small-discriminator/tree/main
# https://huggingface.co/google/electra-small-generator/tree/main

ELECTRA模型存储路径及目录如下:

python 复制代码
model.config

# ELECTRA模型输出参数:
ElectraConfig {
  "_name_or_path": "/code/ElectraModel/electra-small-discriminator/",
  "architectures": [
    "ElectraForPreTraining"
  ],
  "attention_probs_dropout_prob": 0.1,
  "classifier_dropout": null,
  "embedding_size": 128,
  "hidden_act": "gelu",
  "hidden_dropout_prob": 0.1,
  "hidden_size": 256,
  "initializer_range": 0.02,
  "intermediate_size": 1024,
  "layer_norm_eps": 1e-12,
  "max_position_embeddings": 512,
  "model_type": "electra",
  "num_attention_heads": 4,
  "num_hidden_layers": 12,
  "pad_token_id": 0,
  "position_embedding_type": "absolute",
  "summary_activation": "gelu",
  "summary_last_dropout": 0.1,
  "summary_type": "first",
  "summary_use_proj": true,
  "transformers_version": "4.34.0",
  "type_vocab_size": 2,
  "use_cache": true,
  "vocab_size": 30522
}
python 复制代码
tokenizer('It was a great day', return_tensors="pt")

# 输出结果:
{'input_ids': tensor([[ 101, 2009, 2001, 1037, 2307, 2154,  102]]), 
'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0]]), 
'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1]])}

4. SpanBERT

\qquad SpanBERT,它被普遍应用于问答任务和关系提取任务。在SpanBERT中,我们不再随机地掩盖标记并替换为[MASK],而是将连续标记段替换为[MASK]。如下所示:

python 复制代码
tokens = [ you, are, expected, to, know, [MASK], [MASK], [MASK], [MASK], country ]
python 复制代码
from transformers import pipeline

qa_pipeline = pipeline(task="question-answering",
                       model='/code/SpanBERT/spanbert-finetuned-squadv2/', 
                       tokenizer='/code/SpanBERT/spanbert-finetuned-squadv2/')
# 模型下载地址 https://huggingface.co/mrm8488/spanbert-base-finetuned-squadv2/tree/main
result = qa_pipeline({'question': "What is Maching Learning?", 
                      'context': "Machine Learning is a subset of Artifical Intelligence. It is widely for creating a variety of applications such as email filtering and computer vision"})
print(result['answer'])

# 输出结果:
a subset of Artifical Intelligence

SpanBERT模型存储路径及目录如下:

\qquad 为了预测[MASK]所代表的标记,我们用掩码语言模型构建目标和区间边界目标 (span boundary objective, SBO)来训练SpanBERT模型。在区间边界目标中,为了预测任何一个掩码标记,只使用区间边界中的标记特征,而不使用相应的掩码标记的特征。区间边界包括区间开始之前的标记和区间结束之后的标记。除了区间边界标记特征,模型还使用了[MASK]的位置嵌入。位置嵌入表示掩码标记的相对位置。
\qquad 因此,SpanBERT使用两个目标:一个是掩码语言模型构建目标,另一个是区间边界目标。在掩码语言模型构建目标中,为了预测掩码标记,我们只使用相应标记的特征。在区间边界目标中,为了预测掩码标记,我们只使用区间边界标记特征和掩码标记的位置嵌入。

参考致谢:

1\]. ALBERT: A Lite BERT for Self-supervised Learning of Language Representations \[2\]. RoBERTa: A Robustly Optimized BERT Pretraining Approach \[3\]. ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators \[4\]. SpanBERT: Improving Pre-training by Representing and Predicting Spans \[5\]. BERT基础教程:Transformer大模型实战. 苏达哈拉桑 · 拉维昌迪兰 > 如有侵权,请联系侵删 > > 需要本实验源数据及代码的小伙伴请联系QQ:2225872659

相关推荐
陈广亮21 分钟前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬30 分钟前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia1 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能
爱可生开源社区1 小时前
DBA 的未来?八位行业先锋的年度圆桌讨论
人工智能·dba
叁两4 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
前端付豪4 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
strayCat232554 小时前
Clawdbot 源码解读 7: 扩展机制
人工智能·开源
程序员打怪兽4 小时前
详解Visual Transformer (ViT)网络模型
深度学习
王鑫星4 小时前
SWE-bench 首次突破 80%:Claude Opus 4.5 发布,Anthropic 的野心不止于写代码
人工智能