huggingface使用bert

本文针对于huggingface使用.不是教程,只是我需要的东西.

调用bert类

参考博客:

1Huggingface简介及BERT代码浅析 - 知乎 (zhihu.com).

import torch
from transformers import BertModel, BertTokenizer

这里我们调用bert-base模型,同时模型的词典经过小写处理

model_name = ‘bert-base-uncased’

读取模型对应的tokenizer

tokenizer = BertTokenizer.from_pretrained(model_name)

载入模型

model = BertModel.from_pretrained(model_name)

输入文本

input_text = “Here is some text to encode”

通过tokenizer把文本变成 token_id

input_ids = tokenizer.encode(input_text, add_special_tokens=True)

input_ids: [101, 2182, 2003, 2070, 3793, 2000, 4372, 16044, 102]

input_ids = torch.tensor([input_ids])

获得BERT模型最后一个隐层结果

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

这里你需要改为自己的实际文件夹路径

tokenizer = GPT2Tokenizer.from_pretrained(‘/dfsdata2/yucc1_data/models/huggingface/gpt2’)
text = ‘Who was Jim Henson ? Jim Henson was a’

编码一段文本

编码后为[8241, 373, 5395, 367, 19069, 5633, 5395, 367, 19069, 373, 257]

indexed_tokens = tokenizer.encode(text)

转换为pytorch tensor

tensor([[ 8241, 373, 5395, 367, 19069, 5633, 5395, 367, 19069, 373, 257]])

shape为 torch.Size([1, 11])

tokens_tensor = torch.tensor([indexed_tokens])

从下载好的文件夹中加载预训练模型

model = GPT2LMHeadModel.from_pretrained(‘/dfsdata2/yucc1_data/models/huggingface/gpt2’)

设置为evaluation模式,去取消激活dropout等模块。

在huggingface/transformers框架中,默认就是eval模式

model.eval()

预测所有token

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]

我们需要预测下一个单词,所以是使用predictions第一个batch,最后一个词的logits去计算

predicted_index = 582,通过计算最大得分的索引得到的

predicted_index = torch.argmax(predictions[0, -1, :]).item()

反向解码为我们需要的文本

predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])

解码后的文本:‘Who was Jim Henson? Jim Henson was a man’

成功预测出单词 ‘man’

print(predicted_text)

欢迎留言讨论

你可能感兴趣的:(bert,深度学习,人工智能)