BertModel和BertForMaskedLM使用介绍

BertModel和BertForMaskedLM使用介绍

在transformers中有BertModel和BertForMaskedLM这个类,直接调用。在实体抽取,文本分类等任务中常用使用的是BertModel获取句子的embedding 向量,BertForMaskedLM可以得到mask处的文字,最近在做一个任务遇到了BertForMaskedLM的使用,记录一下。

BertModel

torch 代码如下

import torch
from transformers import BertModel
from transformers import BertTokenizer
from transformers import BertForMaskedLM 

pretrain_model_bert = "D:/Spyder/pretrain_model/transformers_torch_tf/bert-base-chinese/"
# 获取tokenizer
bert_tokenzier = BertTokenizer.from_pretrained(pretrain_model_bert)
# 加载bert 预训练模型
bert = BertModel.from_pretrained(pretrain_model_bert)

input_text = "但是我不能去参加,因为我有一点事情阿!"
input_tokens = bert_tokenzier(input_text, add_special_tokens=True,
padding=True, return_tensors='pt')
bert_outputs = bert(**input_tokens, return_dict=True
                    )
bert_logits = bert_outputs[0]

bert logits 是bert 预训练模型得到的last_hidden_state的输出,是最后一层的输出, shape为(batch_size, seq_len, 768)

BertForMaskedLM

torch 代码如下:

import torch
from transformers import BertModel
from transformers import BertTokenizer
from transformers import BertForMaskedLM 

pretrain_model_bert = "D:/Spyder/pretrain_model/transformers_torch_tf/bert-base-chinese/"
# 获取tokenizer
bert_tokenzier = BertTokenizer.from_pretrained(pretrain_model_bert)
# 加载bert mask 预训练模型
maskbert = BertForMaskedLM.from_pretrained(pretrain_model_bert)
input_text = "但是我不能去参加,因为我有一点事情阿!"
output_text = "但是我不能去参加,因为我有一点事情啊!"
#
output_labels = bert_tokenzier(output_text, add_special_tokens=True, padding=True, return_tensors='pt')['input_ids']
input_tokens = bert_tokenzier(input_text, add_special_tokens=True, padding=True, return_tensors='pt')
#
maskbert_outputs = maskbert(**input_tokens, labels=output_labels, return_dict=True,
                            output_hidden_states=True)
maskbert_logits = maskbert_outputs.logits
print("maskbert logits shape: ", maskbert_logits.size())
maskbert_loss = maskbert_outputs.loss
maskbert_hidden = maskbert_outputs.hidden_states[-1]

labels 是为了计算masked language modeling 的loss,maskbert_logits是得到序列中每一个词的概率,shape为(batch_size, seq_len, vocab_size),maskbert_hidden 是模型最最后一层的hidden state
这里验证一下maskbert_hidden和bert logits是否一样

print(maskbert_hidden.equal(bert_logits))
True

这里给一个BertForMaskedLM可以得到mask处的文字的例子,没有finetuing,直接加载预训练模型得到mask处字的结果

import torch
from transformers import BertTokenizer
from transformers import BertForMaskedLM

pretrain_model_bert = "D:/Spyder/pretrain_model/transformers_torch_tf/bert-base-chinese/"
# 获取tokenizer
bert_tokenzier = BertTokenizer.from_pretrained(pretrain_model_bert)
# 加载bert mask 预训练模型
maskbert = BertForMaskedLM.from_pretrained(pretrain_model_bert)
text = "[MASK]的首都是北京"
text_tokens = bert_tokenzier(text, add_special_tokens=True,
                             padding=True, return_tensors='pt')
print(text_tokens["input_ids"])
maskbert_outputs = maskbert(**text_tokens, return_dict=True,
                            output_hidden_states=True)
logits = maskbert_outputs.logits
pred = torch.argmax(logits, dim=-1)
pred = pred.data.cpu().numpy().tolist()[0]
pred_tokens = bert_tokenzier.decode(pred)
print(pred_tokens)

如有表述和理解不当,欢迎指出。

你可能感兴趣的:(NLP,自然语言处理,深度学习,transformer)