HuggingFace-transformers系列的介绍以及在下游任务中的使
⽤
这篇博客主要⾯向对Bert系列在Pytorch上应⽤感兴趣的同学,将涵盖的主要内容是:Bert系列有关的论⽂,的实现,以及如何在不同下游
任务中使⽤预训练模型。
看过这篇博客,你将了解:
Transformers实现的介绍,不同的Tokenizer和Model如何使⽤。
如何利⽤HuggingFace的实现⾃定义你的模型,如果你想利⽤这个库实现⾃⼰的下游任务,⽽不想过多关注其实现细节的话,那么这
篇⽂章将会成为很好的参考。
所需的知识
(需要预先安装pytorch)
在阅读这篇⽂章之前,如果你能将以下资料读⼀遍,或者看⼀遍的话,在后续的阅读过程中将极⼤地减少你陷⼊疑惑的概率。
视频类内容:根据排序观看更佳
或者,你更愿意去看论⽂的话:
相关论⽂:根据排序阅读更佳
,BERT:Pre-trainingofDeepBidirectionalTransformersforLanguageUnderstanding,Authors:JacobDevlin,Ming-
WeiChang,KentonLee,KristinaToutanova
,Transformer-XL:AttentiveLanguageModelsBeyondaFixed-LengthContext,Authors:ZihangDai,ZhilinYang,
YimingYang,,JaimeCarbonell,uslanSalakhutdinov.
XLNet论⽂
ALBERT论⽂
HuggingFace模型加载+下游任务使⽤
项⽬组件
⼀个完整的transformer模型主要包含三部分:
,控制模型的名称、最终输出的样式、隐藏层宽度和深度、激活函数的类别等。将Config类导出时⽂件格式为json格式,就
像下⾯这样:
{
"attention_probs_dropout_prob":0.1,
"hidden_act":"gelu",
"hidden_dropout_prob":0.1,
"hidden_size":768,
"initializer_range":0.02,
"intermediate_size":3072,
"max_position_embeddings":512,
"num_attention_heads":12,
"num_hidden_layers":12,
"type_vocab_size":2,
"vocab_size":30522
}
当然,也可以通过来实例化Config类,这是⼀个互逆的过程。
zer,这是⼀个将纯⽂本转换为编码的过程。注意,Tokenizer并不涉及将词转化为词向量的过程,仅仅是将纯⽂本分词,添加
[MASK]标记、[SEP]、[CLS]标记,并转换为字典索引。Tokenizer类导出时将分为三个⽂件,也就是:
词典⽂件,每⼀⾏为⼀个词或词的⼀部分
l_tokens_特殊标记的定义⽅式
{"unk_token":"[UNK]","p_token":"[SEP]","pad_token":"[PAD]",
"cls_token":"[CLS]","mask_token":"[MASK]"}
zer_配置⽂件,主要存储特殊的配置。
,也就是各种各样的模型。除了初始的Bert、GPT等基本模型,针对下游任务,还定义了诸如BertForQuestionAnswering等下
游任务模型。模型导出时将⽣成和pytorch_参数⽂件。前者就是1中的配置⽂件,这和我们的直觉相同,即
config和model应该是紧密联系在⼀起的两个类。后者其实和()存储得到的⽂件是相同的,这是因为Model都直接或者间
接继承了Pytorch的Module类。从这⾥可以看出,HuggingFace在实现时很好地尊重了Pytorch的原⽣API。
导⼊Bert系列基本模型的⽅法
通过官⽹⾃动导⼊
官⽅⽂档中提供的⽅法为:
#Loadpre-trainedmodel(weights)
#model=_pretrained('bert-ba-uncad')
这个⽅法需要从官⽅的s3数据库下载模型配置、参数等信息(代码中已配置好位置)。这个⽅法虽然简单,但是在国内并不可⽤。当然你可
以先尝试⼀下,不过会有很⼤的概率⽆法下载模型。
⼿动下载模型信息并导⼊
1.在HuggingFace上找到需要下载的模型,点击模型链接,这个例⼦使⽤的是bert-ba-uncad模型
2.点击,将其中的⽂件⼀⼀下载到同⼀⽬录中。例如,对于XLNet:
#Listofmodelfiles
782.0B
pytorch_445.4MB
special_tokens_202.0B
779.3KB
tokenizer_2.0B
但是这种⽅法有时也会不可⽤。如果您可以将Transformers预训练模型上传到迅雷等⽹盘的话,请在评论区告知,我会添加在此博
客中,并为您添加博客友链。
3.通过下载好的路径导⼊模型:
importtransformers
MODEL_PATH=r"D:transformr_filesbert-ba-uncad/"
#a.通过词典导⼊分词器
tokenizer=_pretrained(r"D:transformr_")
#b.导⼊配置⽂件
model_config=_pretrained(MODEL_PATH)
#修改配置
model__hidden_states=True
model__attentions=True
#通过配置和路径导⼊模型
model=_pretrained(MODEL_PATH,config=model_config)
利⽤分词器分词
利⽤分词器进⾏编码
对于单句:
#encode仅返回input_ids
("ilikeyou")
Out:[101,1045,2066,2017,102]
对于多句:
#encode_plus返回所有编码信息
_plus("ilikeyou","butnothim")
Out:
{'input_ids':[101,1045,2066,2017,102,2021,2025,2032,102],
'token_type_ids':[0,0,0,0,0,1,1,1,1],
'attention_mask':[1,1,1,1,1,1,1,1,1]}
模型的所有分词器都是在PreTrainedTokenizer中实现的,分词的结果主要有以下内容:
{
input_ids:list[int],
token_type_ids:list[int]ifreturn_token_type_idsisTrue(default)
attention_mask:list[int]ifreturn_attention_maskisTrue(default)
overflowing_tokens:list[int]ifamax_lengthisspecifiedandreturn_overflowing_tokensisTrue
num_truncated_tokens:intifamax_lengthisspecifiedandreturn_overflowing_tokensisTrue
special_tokens_mask:list[int]ifadd_special_tokensifttoTrueandreturn_special_tokens_maskisTrue
}
编码解释:
'input_ids':顾名思义,是单词在词典中的编码
'token_type_ids',区分两个句⼦的编码
'attention_mask',指定对哪些词进⾏lf-Attention操作
'overflowing_tokens',当指定最⼤长度时,溢出的单词
'num_truncated_tokens',溢出的token数量
'return_special_tokens_mask',如果添加特殊标记,则这是[0,1]的列表,其中0指定特殊添加的标记,⽽1指定序列标记
将分词结果输⼊模型,得到编码
#添加batch维度并转化为tensor
input_ids=([input_ids])
token_type_ids=([token_type_ids])
#将模型转化为eval模式
()
#将模型和数据转移到cuda,若⽆cuda,可更换为cpu
device='cuda'
tokens_tensor=input_(device)
gments_tensors=token_type_(device)
(device)
#进⾏编码
_grad():
#Seethemodelsdocstringsforthedetailoftheinputs
outputs=model(tokens_tensor,token_type_ids=gments_tensors)
#Transformersmodelsalwaysoutputtuples.
#Seethemodelsdocstringsforthedetailofalltheoutputs
#Inourca,thefirstelementisthehiddenstateofthelastlayeroftheBertmodel
encoded_layers=outputs
#得到最终的编码结果encoded_layers
Bert最终输出的结果为:
quence_output,pooled_output,(hidden_states),(attentions)
以输⼊序列长度为14为例
index名称维度描述
0quence_([1,14,768])输出序列
1pooled_([1,768])对输出序列进⾏pool操作的结果
2(hidden_states)tuple,13*([1,14,768])隐藏层状态(包括Embedding层),取决于modelconfig中output_hidden_states
3(attentions)tuple,12*([1,12,14,14])注意⼒层,取决于参数中output_attentions
Bert总结
这⼀节我们以Bert为例对模型整体的流程进⾏了了解。之后的很多模型都基于Bert,并基于Bert进⾏了少量的调整。其中的输出和输出参数
也有很多重复的地⽅。
利⽤预训练模型在下游任务上微调
如开头所说,这篇⽂章重点在于"如何进⾏模型的调整以及输⼊输出的设定",以及"Transformer的实现进⾏简要的提及",所以,我们不会去
介绍、涉及如何写train循环等话题,⽽仅仅专注于模型。也就是说,我们将⽌步于跑通⼀个模型,⽽不计批量数据预处理、训练、验证等过
程。
同时,这⾥更看重如何基于Bert等初始模型在实际任务上进⾏微调,所以我们不会仅仅地导⼊已经在下游任务上训练好的模型参数,因为在
这些模型上使⽤的⽅法和上⼀章的⼏乎完全相同。
这⾥的输⼊和输⼊以模型的预测过程为例。
问答任务viaBert
模型的构建:
fromtransformersimportBertTokenizer,BertForQuestionAnswering
importtorch
MODEL_PATH=r"D:transformr_filesbert-ba-uncad/"
#实例化tokenizer
tokenizer=_pretrained(r"D:transformr_")
#导⼊bert的model_config
model_config=_pretrained(MODEL_PATH)
#⾸先新建bert_model
bert_model=_pretrained(MODEL_PATH,config=model_config)
#最终有两个输出,初始位置和结束位置(下⾯有解释)
model__labels=2
#同样根据bert的model_config新建BertForQuestionAnswering
model=BertForQuestionAnswering(model_config)
=bert_model
⼀般情况下,⼀个基本模型对应⼀个Tokenizer,所以并不存在对应于具体下游任务的Tokenizer。这⾥通过bert_model初始化
BertForQuestionAnswering。
任务输⼊:问题句,答案所在的⽂章"WhowasJimHenson?","JimHensonwasanicepuppet"
任务输出:答案"anicepuppet"
#设定模式
()
question,text="WhowasJimHenson?","JimHensonwasanicepuppet"
#获取input_ids编码
input_ids=(question,text)
#⼿动进⾏token_type_ids编码,可⽤encode_plus代替
token_type_ids=[0ifi<=input_(102)el1foriinrange(len(input_ids))]
#得到评分,
start_scores,end_scores=model(([input_ids]),token_type_ids=([token_type_ids]))
#进⾏逆编码,得到原始的token
all_tokens=t_ids_to_tokens(input_ids)
#['[CLS]','who','was','jim','henson','?','[SEP]','jim','henson','was','a','nice','puppet','[SEP]']
模型输⼊:inputids,token_type_ids
模型输出:start_scores,end_scores形状都为([1,14]),其中14为序列长度,代表每个位置是开始/结束位置的概率。
将模型输出转化为任务输出:
#对输出的答案进⾏解码的过程
answer=''.join(all_tokens[(start_scores):(end_scores)+1])
#asrtanswer=="anicepuppet"
#这⾥因为没有经过微调,所以效果不是很好,输出结果不佳。
print(answer)
#'wasjimhenson?[SEP]jimhensonwasanicepuppet[SEP]'
⽂本分类任务(情感分析等)viaXLNet
模型的构建:
fromtransformersimportXLNetConfig,XLNetModel,XLNetTokenizer,XLNetForSequenceClassification
importtorch
#定义路径,初始化tokenizer
XLN_PATH=r"D:transformr_filesXLNetLMHeadModel"
tokenizer=_pretrained(XLN_PATH)
#加载配置
model_config=_pretrained(XLN_PATH)
#设定类别数为3
model__labels=3
#直接从xlnet的config新建XLNetForSequenceClassification(和上⼀节⽅法等效)
cls_model=_pretrained(XLN_PATH,config=model_config)
任务输⼊:句⼦"ilikeyou,whataboutyou"
任务输出:句⼦所属的类别class1
#设定模式
()
token_codes=_plus("ilikeyou,whataboutyou")
模型输⼊:inputids,token_type_ids
模型输出:logits,hiddenstates,其中logits形状为([1,3]),其中的3对应的是类别的数量。当训练时,第⼀项为loss。
其他的任务,将继续更新
其他的模型和之前的两个⼤致是相同的,你可以⾃⼰发挥。我会继续在相关的库上进⾏实验,如果发现⽤法不⼀样的情况,将会添加在这
⾥。
参考
本⽂章主要对HuggingFace库进⾏了简要介绍。具体安装等过程请参见官⽅。
本文发布于:2022-11-14 17:33:57,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/88/18928.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |