赞
踩
Hugging Face
一直致力于自然语言处理NLP技术的平民化(democratize),希望每个人都能用上最先进(SOTA, state-of-the-art)的NLP技术,而非困窘于训练资源的匮乏"

其中,transformer库提供了NLP领域大量预训练语言模型和调用框架,方便根据自己的需求快速进行语言模型搭建,这里为自己学习做下简单总结(参考官方教程)。
目录
Transformer常用model架构(带head)接口输出
正文
Transformer整体介绍
语言模型与自然语言处理
语言模型:简易理解就是求概率P(tm|t1、t2、…、tn)
自然语言处理常见任务
其他非文本任务:
图像:
图像分类:对图像进行分类。
图像分割:对图像中的每个像素进行分类。
物体检测:检测图像中的物体。
音频:
音频分类:为给定的音频片段分配标签。
自动语音识别 (ASR):将音频数据转录为文本。
经典模型处理能力(句子序列长度)
transformer库piepeline接口介绍
Transformers library 中最基本对象是pipeline,它将数据预处理、预训练语言模型和目标结果处理步骤串联起来,使我们能够直接输入文本并获得自己需要的答案。
Pipeline结构示意图:

pipeline的简单使用:
import torch from transformers import pipeline # 哈工大中文预训练模型bert-roberta-wwm (已下载到本地) model_path = r"D:\appData\bert-wwm-ext\chinese-roberta-wwm-ext" # 测试中文填词任务 fill_mask_model = pipeline(task='fill-mask', # 填写要做的任务类型,确定POST-processing model=model_path, # 处理任务要使用的预训练语言模型 tokenizer=model_path # 输入数据预处理,需要的分词编码器(与要使用的语言模型相关) ) fill_mask_model(['我[MASK]你']) # 返回 ''' [{'score': 0.8178807497024536, 'token': 4263, 'token_str': '爱', 'sequence': '我 爱 你'}, {'score': 0.05486121028661728, 'token': 2682, 'token_str': '想', 'sequence': '我 想 你'}, {'score': 0.02797825261950493, 'token': 3221, 'token_str': '是', 'sequence': '我 是 你'}, {'score': 0.019031845033168793, 'token': 1469, 'token_str': '和', 'sequence': '我 和 你'}, {'score': 0.01068081520497799, 'token': 3612, 'token_str': '欠', 'sequence': '我 欠 你'}] '''
默认情况下,给定特定任务,pipeline会自动选择一个特定的预训练模型。
将文本输入pipeline,pipeline的处理涉及3个步骤,对应上面的pipeline结构图
tokenizer: 文本预处理为对应model可以理解的格式
model: 预处理模型输入对应model
post-processing: 将model的输入经过全连接/激活,处理成任务需要输出的形式
至此,只需要修改参数 task名+匹配的预训练语言模型,就能简单实现自然语言处理任务(同样也可以使用pipeline实现其他如图像、音频分类等任务)。
tokenizer和model介绍
通过pipeline接口,我们能实现特征的任务,但越简单的接口,往往伴随着缺乏灵活性的问题。一般情况下,不直接使用pipeline,使用其中tokenizer和model,配合模型后续处理生成适合自己任务的模型。
tokenizer介绍
from transformers import BertModel,BertTokenizer,BertConfig # 主要加载预训练模型词汇表,分词规则等 tokenizer = BertTokenizer.from_pretrained(model_path) #分词器序列编码,解码 data_encode = tokenizer( text = ['我 爱 你','我恨你','天空'], # 输入多条分本 text_pair = None, add_special_tokens = True, # padding = 'max_length', # 填充长度不够的序列 truncation = True, # 过长序列截断 max_length = 5, # 指定序列长度 stride = 0, is_split_into_words = False, # text或text_pair参数输入字符串列表时,起作用,指定序列是否分批 pad_to_multiple_of = None, # 指定数据处理后的返回 return_tensors = 'pt',# 指定返回数据类型,pt:pytorch np:数组 'tf':tensorflow 不指定返回list return_token_type_ids = True, # 指定上下句子关系,上句为0,下句为1 return_attention_mask = True, # 返回句子序列实际长度,1代表真实token,0代表填充 return_overflowing_tokens = False, return_special_tokens_mask = True,# 指定特殊字符位置,1代表起始符[CLS],分隔符[sep],填充符[PAD]等,0代表正常token return_offsets_mapping = False, return_length = True,# 返回序列长度 verbose = True ) data_encode ''' {'input_ids': tensor([[ 101, 2769, 4263, 872, 102], [ 101, 2769, 2616, 872, 102], [ 101, 1921, 4958, 102, 0]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]), 'special_tokens_mask': tensor([[1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 1, 1]]), 'length': tensor([5, 5, 4]), 'attention_mask': tensor([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 0]])} ''' tokenizer.decode(token_ids=data_encode['input_ids'][0]) # 字符解码 >> [CLS] 我 爱 你 [SEP] [PAD]
model介绍
# 加载预训练bert中文语言模型(主要是预训练参数) model = BertModel.from_pretrained(pretrained_model_name_or_path=model_path) bert_out = model.forward( input_ids = data_encode.input_ids, # 对应tokener输出字符序列编码 attention_mask = data_encode.attention_mask, token_type_ids = data_encode.token_type_ids, position_ids = None, head_mask = None, inputs_embeds = None, encoder_hidden_states = None, encoder_attention_mask = None, past_key_values = None, use_cache = None, output_attentions = None, output_hidden_states = True, # 是否返回 return_dict = None ) # bert_out.hidden_states # 返回每个block的隐藏层输出 bert_out.last_hidden_state.shape # 返回bert模型最后一个block隐藏层输出 bert_out.pooler_output.shape # 返回[CLS]标记处对应的向量后面接个全连接再接tanh激活后的输出 ''' torch.Size([3, 5, 768]) (batch,sequence_len,word_embedding_szie) torch.Size([3, 768]) (batch,word_embedding_szie) '''
transformers 中有tokenizer和model类还有很多其他的函数功能,这里只是bert预训练中文语言模型的使用,可以在model(经过tokenizer处理后分词数据输入)的带有语义的隐藏层输出后面,灵活添加后续处理层,实现自己特定的任务。
Transformer常用model架构(带head)接口输出
transformer库有很多带有不同预设输出的model架构,针对预训练模型输出结果后续处理的层,称之为head层。head将transformer network(多头注意力机制)最终隐藏层输出的高维特征向量作为输入,并将他们投影到不同的维度上,head通常由一个或几个线性层组成。

AutoModel架构的输出(通用类,不带head部分)
In many cases, the architecture you want to use can be guessed from the name or the path of the pretrained model you are supplying to the from_pretrained() method. AutoClasses are here to do this job for you so that you automatically retrieve the relevant model given the name/path to the pretrained weights/config/vocabulary. – 官方原文
– 大概意思 AutoModel是个通用类,能从输入的预训练模型名称中或预训练模型存储路径中,自动生成相应模型的architecture(架构)并自动加载checkpoint(可以理解为对应层的权重参数)
– BertModel 专用于加载BERT架构模型的基础类。
from transformers import ( AutoTokenizer, AutoModel, AutoConfig, AutoModelForMaskedLM, AutoModelForSequenceClassification, AutoModelForTokenClassification) # 记载预训练模型 auto_model = AutoModel.from_pretrained(model_path) bert_model = BertModel.from_pretrained(model_path) tokenizer = AutoTokenizer.from_pretrained(model_path) # 验证AutoModel和BertModel加载同一个模型输出结果 data = tokenizer(text=['我爱你'],return_tensors='pt') auto_model(data.input_ids).last_hidden_state bert_model(data.input_ids).last_hidden_state ''' tensor([[[ 0.0963, 0.0306, -0.0745, ..., -0.6741, 0.0229, -0.3951], [ 0.8193, -0.4155, 0.4848, ..., -0.7079, 0.5251, -0.2706], [ 0.2164, 0.2476, -0.2831, ..., -0.1583, 0.1191, -1.0851], [ 0.8606, -0.5950, 0.8120, ..., -0.4619, 0.1180, -0.4674], [ 0.0963, 0.0306, -0.0745, ..., -0.6741, 0.0229, -0.3951]]], grad_fn=<NativeLayerNormBackward>) tensor([[[ 0.0963, 0.0306, -0.0745, ..., -0.6741, 0.0229, -0.3951], [ 0.8193, -0.4155, 0.4848, ..., -0.7079, 0.5251, -0.2706], [ 0.2164, 0.2476, -0.2831, ..., -0.1583, 0.1191, -1.0851], [ 0.8606, -0.5950, 0.8120, ..., -0.4619, 0.1180, -0.4674], [ 0.0963, 0.0306, -0.0745, ..., -0.6741, 0.0229, -0.3951]]], grad_fn=<NativeLayerNormBackward>) '''
AutoModel类输出:
data = tokenizer(text=['我爱你'],return_tensors='pt')
model = AutoModel.from_pretrained(model_path)
outputs = model(**data)
outputs.keys()
outputs.last_hidden_state.shape # 最后一层隐藏层输出
outputs.pooler_output.shape # pooler output是取[CLS]标记处对应的向量后面接个全连接再接tanh激活后的输出
'''
odict_keys(['last_hidden_state', 'pooler_output'])
torch.Size([1, 5, 768]) (batch,sequence_len,word_embedding_szie)
torch.Size([1, 768]) (batch,word_embedding_szie)
'''
AutoModelForMaskedLM 架构的输出(with a masked language modeling head,可用于文本填空任务)
AutoModelForMaskedLM输出:
model = AutoModelForMaskedLM.from_pretrained(model_path)
outputs = model(**data)
outputs.keys()
outputs.logits.shape
'''
odict_keys(['logits'])
torch.Size([1, 5, 21128])
'''
AutoModelForSequenceClassification架构的输出(with a sequence classification head,文本分类型任务)
data = tokenizer(text=['我爱你'],return_tensors='pt')
model = AutoModelForSequenceClassification.from_pretrained(model_path)
outputs = model(**data)
outputs.keys()
outputs.logits.shape
'''
odict_keys(['logits'])
torch.Size([1, 2])
'''
AutoModelForTokenClassification架构的输出(with a token classification head,命名实体识别任务)
AutoModelForTokenClassification输出:
model = AutoModelForTokenClassification.from_pretrained(model_path)
outputs = model(**data)
outputs.keys()
outputs.logits.shape
'''
odict_keys(['logits'])
torch.Size([1, 5, 2])
'''
模型输出logits概率处理
logits,即模型最后一层输出的原始的、非标准化的分数。要转换为概率,它们需要经过softmax(所有
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。