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

相关推荐
幻风_huanfeng12 分钟前
线性代数中的核心数学知识
人工智能·机器学习
volcanical20 分钟前
LangGPT结构化提示词编写实践
人工智能
weyson1 小时前
CSharp OpenAI
人工智能·语言模型·chatgpt·openai
RestCloud1 小时前
ETLCloud异常问题分析ai功能
人工智能·ai·数据分析·etl·数据集成工具·数据异常
IT古董1 小时前
【机器学习】决定系数(R²:Coefficient of Determination)
人工智能·python·机器学习
鲜枣课堂1 小时前
5G-A如何与AI融合发展?华为MBBF2024给出解答
人工智能·5g·华为
武子康2 小时前
大数据-213 数据挖掘 机器学习理论 - KMeans Python 实现 距离计算函数 质心函数 聚类函数
大数据·人工智能·python·机器学习·数据挖掘·scikit-learn·kmeans
武子康2 小时前
大数据-214 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn n_clusters labels
大数据·人工智能·python·深度学习·算法·机器学习·数据挖掘
weixin_518285053 小时前
深度学习笔记11-神经网络
笔记·深度学习·神经网络
封步宇AIGC3 小时前
量化交易系统开发-实时行情自动化交易-Okex K线数据
人工智能·python·机器学习·数据挖掘