本文针对于huggingface使用.不是教程,只是我需要的东西.
调用bert类
参考博客:
1Huggingface简介及BERT代码浅析 - 知乎 (zhihu.com).
import torch
from transformers import BertModel, BertTokenizer
model_name = ‘bert-base-uncased’
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)
input_text = “Here is some text to encode”
input_ids = tokenizer.encode(input_text, add_special_tokens=True)
input_ids = torch.tensor([input_ids])
with torch.no_grad():
last_hidden_states = model(input_ids)[0] # Models outputs are now tuples
“”"
shape: (1, 9, 768)
“”"
上图就是如何使用bert嵌入文本.注意tokenization就是调用字典而已.经过model产生嵌入向量.
以bert为例子,看bertmodel类,它就是bert的主类.它的output是添加了objective任务的.而里边的bertembedding没有添加任务,只是嵌入而已.
作者说,BertEncoder主要将embedding的输出.是不是说bertencoder=bertembedding.
Bertpooler 其实就是将BERT的[CLS]的hidden_state 取出,经过一层DNN和Tanh计算后输出
class BertModel(BertPreTrainedModel):
def init(self, config):
super().init(config)
self.config = config
self.embeddings = BertEmbeddings(config)
self.encoder = BertEncoder(config)
self.pooler = BertPooler(config)
self.init_weights()
下面这段话很重要
在这个文件中还有上述基础的BertModel的进一步的变化,比如BertForMaskedLM,BertForNextSentencePrediction这些是Bert加了预训练头的模型,还有BertForSequenceClassification, BertForQuestionAnswering 这些加上了特定任务头的模型。
这句话的意思是 头就是objective任务,上述第二行就是下游任务.
我们还是不了解上面话的含义,我们查阅huggingface的文档:BERT (huggingface.co).
hidden_size=768,就是bert嵌入的输出维度.
BertModel: 主类.
BertForPreTraing: 两个头,看来两个头就是两个任务.
BertForMaskedLM#
看了东于的博客:[BERT相关——(8)BERT-based Model代码分析 | 冬于的博客 (ifwind.github.io)](https://ifwind.github.io/2021/08/24/BERT相关——(8)BERT-based Model代码分析/#引言).
HuggingFace的transformers库中基于 BERT 的模型都是基于BertPreTrainedModel这一抽象基类的,而后者则基于一个更大的基类PreTrainedModel。这里我们关注BertPreTrainedModel的功能:BertPreTrainedModel用于初始化模型权重,同时维护继承自PreTrainedModel的一些标记身份或者加载模型时的类变量。
HuggingFace的transformers库提供了对两个目标都进行预训练、以及只对其中一个任务进行预训练的Bert预训练模型:
BertForPreTraining:进行MLM和NSP两个任务的预训练;
BertForMaskedLM:只进行 MLM 任务的预训练;
BertLMHeadModel:这个和上一个的区别在于,这一模型是作为 decoder 运行的版本;#这是什么意思?懂了,就是只能利用上文,不能利用下文. BertForNextSentencePrediction:只进行 NSP 任务的预训练。
注意,bert的两个任务都是分类任务.
BertForMaskedLM只完成MLM任务,事实上后续的RoBERTa、ALBERT、spanBERT等模型都移去了NSP任务(消除NSP损失在下游任务的性能上能够与原始BERT持平或略有提高)。
与上面的BertForMaskedLM模型不同,BertLMHeadModel模型是decoder版本,也就是只能利用上文而不能利用下文,任务修改为next token prediction。完成LM任务:注意这里做的是下一个token预测的任务
接下来介绍HuggingFace-Transformers库中实现的四种 Fine-tune 模型,基本都是分类任务,与上一篇博客相对应,不包括seq2seq模型。
one class-BertForSequenceClassification#句子分类
one class-BertForMultipleChoice
class for each token-BertForTokenClassification#token分类
copy from input-BertForQuestionAnswering#输入为问题 +(对于 BERT 只能是一个)回答组成的句子对,输出为起始位置s和结束位置e用于标出回答中的具体文本。
什么是回归任务和分类任务?
简单来讲,分类任务 和 回归任务 的区别在于 需要预测的值的类型:
回归任务,是对 连续值 进行预测(比如 多少);#使用MSE
分类任务,是对 离散值 进行预测(比如 是不是,属不属于,或者 属于哪一类)。#使用交叉熵
比如,
预测 明天的气温是多少度,这是一个回归任务;
预测 明天会不会下雨,就是一个分类任务。
调用gpt类
参考:huggingface transformers预训练模型如何下载至本地,并使用? - 知乎 (zhihu.com).
特别注意三个类:使用的时候,非常简单。huggingface的transformers框架主要有三个类model类、configuration类、tokenizer类,这三个类,所有相关的类都衍生自这三个类,他们都有from_pretained()方法和save_pretrained()方法。
注意,from_pretained就可以微调了,save_pretrained就是存储自己的微调.
import torch
from transformers import GPT2Tokenizer, GPT2LMHeadModel
tokenizer = GPT2Tokenizer.from_pretrained(‘/dfsdata2/yucc1_data/models/huggingface/gpt2’)
text = ‘Who was Jim Henson ? Jim Henson was a’
indexed_tokens = tokenizer.encode(text)
tokens_tensor = torch.tensor([indexed_tokens])
model = GPT2LMHeadModel.from_pretrained(‘/dfsdata2/yucc1_data/models/huggingface/gpt2’)
model.eval()
with torch.no_grad():
# 将输入tensor输入,就得到了模型的输出,非常简单
# outputs是一个元组,所有huggingface/transformers模型的输出都是元组
# 本初的元组有两个,第一个是预测得分(没经过softmax之前的,也叫作logits),
# 第二个是past,里面的attention计算的key value值
# 此时我们需要的是第一个值
outputs = model(tokens_tensor)
# predictions shape为 torch.Size([1, 11, 50257]),
# 也就是11个词每个词的预测得分(没经过softmax之前的)
# 也叫做logits
predictions = outputs[0]
predicted_index = torch.argmax(predictions[0, -1, :]).item()
predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])
print(predicted_text)
欢迎留言讨论