本文探讨了BERT模型在自然语言处理领域的应用与实践。详细介绍了Transformers库(曾用名pytorch-transformers和pytorch-pretrained-bert)的使用方法,涵盖了从模型加载到微调的各个环节。此外,还分析了BERT在文本分类、情感分析和命名实体识别等任务中的性能表现,并讨论了其在实际项目中的优势和局限性。
1. transformer资料
transformers(以前称为pytorch-transformers和pytorch-pretrained-bert)
提供用于自然语言理解(NLU)和自然语言生成(NLG)的BERT家族通用结构(BERT,GPT-2,RoBERTa,XLM,DistilBert,XLNet等),包含超过32种、涵盖100多种语言的预训练模型
2.使用
import numpy as np
import torch
下载transformers包
!pip install transformers
下载分词器和模型
from transformers import BertTokenizer,BertModel
下载bert-base-chinese的config.josn,vocab.txt,pytorch_model.bin三个文件后,放在bert-base- chinese文件夹下,此例中该文件夹放在F:/Transformer-Bert/
下#导入分词器
model_name = 'bert-base-chinese'
MODEL_PATH = 'F:/Transformer-Bert/bert-base-chinese/'
导入分词器
tokenizer = BertTokenizer.from_pretrained(model_name)
导入配置文件
model_config = BertConfig.from_pretrained(model_name)
修改配置
model_config.output_hidden_states = True
model_config.output_attentions = True
通过配置和路径导入模型
bert_model = BertModel.from_pretrained(MODEL_PATH, config = model_config)
输入文本
input_text = "我爱伟大的祖国"
# 通过tokenizer把文本变成 token_id
encode仅返回input_ids
encode_plus返回所有编码信息
input_ids:是单词在词典中的编码
token_type_ids:区分两个句子的编码(上句全为0,下句全为1)
attention_mask:指定 对哪些词 进行self-Attention操作
input_ids = tokenizer.encode(input_text)
sen_code = tokenizer.encode_plus('这个故事没有终点', "正如星空没有彼岸")
#print(sen_code)
# {'input_ids': [101, 6821, 702, 3125, 752, 3766, 3300, 5303, 4157, 102, 3633, 1963, 3215, 4958, 3766, 3300, 2516, 2279, 102],
# 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
# 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
将input_id转化回token
tokenizer.convert_ids_to_tokens(sen_code['input_ids'])
转化为tensor
tokens_tensor = torch.tensor([sen_code['input_ids']]) # 添加batch维度并,转换为tensor,torch.Size([1, 19])
segments_tensors = torch.tensor(sen_code['token_type_ids']) # torch.Size([19])
bert_model.eval()
# 进行编码
with torch.no_grad():outputs = bert_model(tokens_tensor, token_type_ids = segments_tensors)encoded_layers = outputs # outputs类型为tupleprint(encoded_layers[0].shape, encoded_layers[1].shape, encoded_layers[2][0].shape, encoded_layers[3][0].shape)# torch.Size([1, 19, 768]) torch.Size([1, 768])# torch.Size([1, 19, 768]) torch.Size([1, 12, 19, 19])
Bert最终输出的结果维度为:sequence_output, pooled_output, (hidden_states), (attentions)
以输入序列为19为例:
sequence_output:torch.Size([1, 19, 768])
输出序列
pooled_output:torch.Size([1, 768])
对输出序列进行pool操作的结果
(hidden_states):tuple, 13 * torch.Size([1, 19, 768])
隐藏层状态(包括Embedding层),取决于 model_config 中的 output_hidden_states
(attentions):tuple, 12 * torch.Size([1, 12, 19, 19])
注意力层,取决于 model_config 中的 output_attentions
2. 遮蔽语言模型 Masked Language Model
BERT以训练遮蔽语言模型(Masked Language Model)作为预训练目标。
具体来说就是把 输入的语句中的字词 随机用 [MASK] 标签覆盖,然后 训练模型 结合被覆盖的词的 左侧 和 右侧上下文进行预测。
可以看出,BERT 的做法 与 从左向右语言模型只通过左侧语句预测下一个词的做法相比,遮蔽语言模型 能够生成同时融合了左、右上下文的语言表示。
这种做法能够使 BERT 学到字词更完整的语义表示。