第 8 节 / 共 10 节
第8章 预训练模型微调实战(day11-12)
NLP 基础(day11-12)
NLP基础
【了解】今日内容介绍
- fasttext工具介绍
- fasttext文本分类
- fasttext词向量迁移
- 迁移学习
- Transformers库的使用
【掌握】fasttext工具介绍
简介
fasttext是自然语言处理(NLP)任务的开源工具包,由Facebook AI Research(FAIR)开发。
它被广泛用于各种任务,包括情感分析、文本分类、命名实体识别、机器翻译等
主要作用
- 文本分类
- 训练词向量
优势
正如其名,在保持较高精度的情况下,快速的进行训练和预测是fasttext的最大优势。
原因:
-
fasttext工具包中内含的fasttext模型,模型结构简单
-
使用fasttext模型训练词向量时,使用层次softmax结构, 来提升超多类别下的模型性能
-
采用负采样(negative sampling),每次训练仅仅更新一小部分的权重, 降低梯度下降过程中的计算量
-
fasttext模型过于简单无法捕捉词序特征, 可采用n-gram特征提取文本特征以弥补模型缺陷提升精度
安装
# pip安装
pip install fasttext-wheel -i https://mirrors.aliyun.com/pypi/simple/
# 如果安装失败,则执行如下命令,文件见day01资料文件夹
pip install fasttext_wheel-0.9.2-cp38-cp38-win_amd64.whl
注意事项:
一定要明确Python环境,避免导致安装后失效的情况。
模型架构
FastText 模型架构和 Word2Vec 中的 CBOW 模型很类似。不同之处在于FastText是预测标签,而 CBOW 模型预测中间词。
fasttext是由3层组成:
-
输入层:是对文档embedding之后的向量, 包含N-gram特征
-
隐藏层:是对输入数据的求和平均
-
输出层:是文档对应的label
如下图所示:

层次softmax
计算超多类别分类时,为了提高效率,不再使用传统的softmax来进行多分类的计算,可使用哈夫曼树,使用层次化的softmax来进行概率的计算。
普通softmax:求每个单词的概率分布。如下图:

层次softmax:求每个单词的概率分布转化为求单词路径的概率乘积。如下图:

霍夫曼树作用:用来构建带权最小二叉树。霍夫曼树,也称哈夫曼树、最优二叉树,因为:huffman
霍夫曼树目的:完成哈夫曼编码,哈夫曼编码是一种变长、极少多余编码方案。
说明如下:
带权路径长度WPL(weighted path length):
左图的叶子节点为: 3,5,7,9
左图的wpl计算:3*3 + 5*3 + 7*2 + 9*1 = 47
WPL最小的二叉树就是赫夫曼树
如下图:

哈夫曼树如何构建?
- 第一步:假设有四个Label分别为:A~D。统计其在语料库出现的频数。

- 第二步:第一次合并建树

- 第三步:第二次合并建树

- 第四步:第三次合并建树

负采样
为什么需要负采样?
-
神经网络经过一个训练样本的训练,它的权重就会进行一次调整。
-
比如利用Skip-Gram进行词向量训练:如果词汇量的数量为上万个,利用softmax计算概率时,需要计算上万个概率值,且每个值都需要进行反向传播更新模型参数,这是非常消耗计算资源的,并且实际中训练起来会非常慢。
-
负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降的计算量。
负采样的优势?
-
提高训练速度,选择了部分数据计算损失,损失计算更加简单。
-
改进效果,增加部分负样本,能够模拟真实场景下的噪声情况,能够让模型的稳健性更强。
扩展阅读:
# 概念名词解释
下采样/降采样:一堆样本100个,采10个。
上采样/升采样:一堆样本100个,采200个。
负采样:通过随机选择负样本,来减少softmax的计算量。
# 作用
下/降采样:数据预处理技术,用于减少数据量。
上/升采样:数据预处理技术,用于增加数据量。
负采样:模型优化技术。用于提升训练效率。
【掌握】fasttext文本分类
概述
文本分类的是将文档(例如电子邮件,帖子,文本消息,产品评论等)分配给一个或多个类别。
训练文本分类模型需要是有监督学习,需要标签。
分类
-
二分类:文本被分类两个类别,往往这两个类别是对立面。比如: 判断一句评论是好评还是差评。
-
单标签多分类:文本可被分成多个类别中的一个类别(即被打上某一个标签)。比如:输入一个人名, 判断它是来自哪个国家的人名。
-
多标签多分类:文本可被分成多个类别中的一多类别(即被打上多个个标签)。比如: 输入一段讨论,话题可以美食、体育新闻、游戏。
步骤
第一步: 获取数据
第二步: 训练集与验证集的划分
第三步: 训练模型
第四步: 使用模型进行预测并评估
第五步: 模型调优
第六步: 模型保存与重加载
获取数据
案例:本案例烹饪相关的数据集, 它是由facebook AI实验室提供的演示数据集。
数据:
__label__sauce __label__cheese How much does potato starch affect a cheese sauce recipe?
__label__food-safety __label__acidity Dangerous pathogens capable of growing in acidic environments
__label__cast-iron __label__stove How do I cover up the white spots on my cast iron stove?
__label__restaurant Michelin Three Star Restaurant; but if the chef is not there
__label__knife-skills __label__dicing Without knife skills, how can I quickly and accurately dice vegetables?
__label__storage-method __label__equipment __label__bread What's the purpose of a bread box?
__label__baking __label__food-safety __label__substitutions __label__peanuts how to seperate peanut oil from roasted peanuts at home?
__label__chocolate American equivalent for British chocolate terms
__label__baking __label__oven __label__convection Fan bake vs bake
__label__sauce __label__storage-lifetime __label__acidity __label__mayonnaise Regulation and balancing of readymade packed mayonnaise and other sauces
数据说明:
fasttext工具数据格式:__label__AAA__label__BBB text1text1text1
多标签多分类问题
训练集与验证集划分
# 12404条数据作为训练数据
head -n 12404 cooking.stackexchange.txt > cooking_train.txt
# 3000条数据作为验证数据
tail -n 3000 cooking.stackexchange.txt > cooking_valid.txt
训练模型
# 导入fasttext
import fasttext
# 使用fasttext的train_supervised方法进行文本分类模型的训练
model = fasttext.train_supervised("../data/cooking_train.txt")
预测和评估
# 使用模型预测一段输入文本, 通过我们常识, 可知预测是正确的, 但是对应预测概率并不大
model.predict("Which baking dish is best to bake a banana bread ?")
# 元组中的第一项代表标签, 第二项代表对应的概率
(('__label__baking',), array([0.06550845]))
# 为了评估模型到底表现如何, 我们在3000条的验证集上进行测试
model.test("data/cooking/cooking_valid.txt")
# 元组中的每项分别代表, 验证集样本数量, 精度以及召回率
(3000, 0.124, 0.0541)
模型调优
- 数据方面:重新处理数据
# 使标点符号与单词分离并统一使用小写字母
cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
# 划分数据集
head -n 12404 cooking.preprocessed.txt > cooking.pre.train
tail -n 3000 cooking.preprocessed.txt > cooking.pre.valid
重新进行模型训练:
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train")
model.test("data/cooking/cooking.pre.valid")
# 我们看到精度和召回率都有所提升
(3000, 0.161, 0.06962663975782038)
- 增加训练轮数
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train", epoch=25)
model.test("data/cooking/cooking.pre.valid")
- 调整学习率
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train", epoch=25, lr=1.0)
model.test("data/cooking/cooking.pre.valid")
- 增加n-gram特征
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train", epoch=25, lr=1.0, wordNgrams=2)
model.test("data/cooking/cooking.pre.valid")
- 修改损失计算方式
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train", epoch=25, lr=1.0, wordNgrams=2, loss='hs')
model.test("data/cooking/cooking.pre.valid")
- 自动超参数调优
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train", autotuneValidationFile='data/cooking/cooking.pre.valid', autotuneDuration=600)
model.test("data/cooking/cooking.pre.valid")
- 实际生产中多标签多分类问题的损失计算方式
model = fasttext.train_supervised(input="data/cooking/cooking.pre.train", epoch=25, lr=1.0, wordNgrams=2, loss='ova')
# 参数k代表指定模型输出多少个标签, 默认为1, 这里设置为-1, 意味着尽可能多的输出.
# 参数threshold代表显示的标签概率阈值, 设置为0.5, 意味着显示概率大于0.5的标签
model.predict("Which baking dish is best to bake a banana bread ?", k=-1, threshold=0.5)
模型保存和加载
# 使用model的save_model方法保存模型到指定目录
model.save_model("data/model/model_cooking.bin")
# 使用fasttext的load_model进行模型的重加载
model = fasttext.load_model("data/model/model_cooking.bin")
# 重加载后的模型使用方法和之前完全相同
model.predict("Which baking dish is best to bake a banana bread ?", k=-1, threshold=0.5)
((u'__label__baking', u'__label__bananas', u'__label__bread'), array([1.00000, 0.939923, 0.592677]))
【掌握】fasttext词向量迁移
概述
使用在大型语料库上已经进行训练完成的词向量模型。
也就是说,已经存在的、已经训练好的词向量,拿过来直接用。
fasttext提供的可迁移的词向量
#1.
fasttext提供了157种语言的在CommonCrawl和Wikipedia语料上进行训练的可迁移词向量模型, 它们采用CBOW模式进行训练, 词向量维度为300维. 可通过该地址查看具体语言词向量模型: https://fasttext.cc/docs/en/crawl-vectors.html
#2.
fasttext提供了294种语言的在Wikipedia语料上进行训练的可迁移词向量模型, 它们采用skipgram模式进行训练, 词向量维度同样是300维. 可通过该地址查看具体语言词向量模型: https://fasttext.cc/docs/en/pretrained-vectors.html
案例
#1.下载词向量模型文件
#2.解压文件
#3.加载bin文件获取词向量
#4.利用邻近词进行效果检验
实现
#1.下载词向量模型压缩的bin.gz文件
wget https://dl.fbaipublicfiles.com/fasttext/vectors-crawl/cc.zh.300.bin.gz
#2.解压bin.gz文件到bin文件
gunzip cc.zh.300.bin.gz
# 3.加载模型
model = fasttext.load_model("cc.zh.300.bin")
# 4.获取词向量
model.get_word_vector("音乐")
# 获取邻近词
model.get_nearest_neighbors("音乐")
【了解】迁移学习
概念
把预训练模型中已经学习知识迁移到另外一个地方,形象比喻成迁移学习。
迁移方式
方式一:直接使用预训练模型,也就是开箱即用。比如fasttext工具包。
方式二:微调预训练模型。
名词介绍
预训练模型
- 一般情况下预训练模型都是大型模型。
特点:网络复杂,参数多,需要大量的数据进行训练
- 在NLP领域,预训练模型往往是语言模型。
因语言模型的训练是无监督的,可以获得大规模语料。比如:输入一句话,生成下一个单词、或者句子,这就是语言模型。比如:打字软件是一个AI程序,是一个语言模型。
- 语言模型又是许多典型NLP任务的基础,如机器翻译,文本生成,阅读理解等。
常见预训练模型BERT, GPT, roBERTa, transformer-XL
微调
- 微调的对象
-
预训练模型
-
微调的方式:
- 1.微调预训练模型的参数
-
2.增加1层或2层输出结构再用小批量标准数据进行重新训练
-
微调的目标
- 让模型更加适应特性任务
说白了,就是下载一个预训练模型比如bert,再用自己的小数据重新训练一下,这个动作就是微调。
【掌握】NLP常见预训练模型
常见预训练模型可以分为三类:
- 自编码语言模型(Auto Encoder Language Model,简称AE)
主要用来进行文本理解;比如: 阅读理解,完型填空,提取句子特征做分类。
代表模型:BERT。
- 自回归语言模型(Auto Regressive Language Model ,简称AR)
主要用来进行文本生成,比如:文本摘要、翻译、文本写作。
代表模型:GPT。
- Seq2Seq混合模型(Sequence-to-Sequence,就是AR+AR)
主要用来做综合任务,比如:摘要、翻译、看图说话。
代表模型:T5。
【实现】Transformers库的使用
了解Transformers库
Transformers是HuggingFace公司开源的、基于 transformer 模型结构的,提供预训练语言库。
HuggingFace的开源社区,尤其是在github上开源的预训练模型库Transformers已成为工业风向标。
HuggingFace网址:https://huggingface.co/
魔搭网址:https://www.modelscope.cn/
如果环境中没有transformers库,则需要安装:
# transformers库的安装命令
pip install transformers -i https://pypi.tuna.tsinghua.edu.cn/simple
或者
pip install transformers-4.46.3-py3-none-any.whl
# 额外安装一个datasets库
pip install datasets -i https://pypi.tuna.tsinghua.edu.cn/simple
说明:
transformers-4.46.3-py3-none-any.whl文件在今日资料目录下。
Transformers库三层应用结构
- 管道(Pipline)方式:高度集成的极简使用方式,只需要几行代码即可实现一个NLP任务。
- 自动模型(AutoMode)方式:可载入并使用BERTology系列模型。
- 具体模型(SpecificModel)方式:在使用时,需要明确指定具体的模型,并按照每个BERTology系列模型中的特定参数进行调用,该方式相对复杂,但具有较高的灵活度。
管道方式
文本分类任务
文本分类是指模型可以根据文本中的内容来进行分类。
import numpy as np
from transformers import pipeline
# 1.文本分类任务
def text_classification():
# 定义模型
model = pipeline(task="text-classification", model="../model/chinese_sentiment")
# 直接预测
output = model(inputs="我爱北京天安门,天安门上太阳升。")
# 数出结果
print('output-->', output)
if __name__ == '__main__':
text_classification()
特征提取任务
特征抽取任务只返回文本处理后的特征,属于预训练模型的范畴。特征抽取任务的输出结果需要和其他模型一起工作。
# 2.特征提取任务
def feature_extraction():
# 定义模型
model = pipeline(task="feature-extraction", model="../model/bert-base-chinese")
# 直接预测
output = model(inputs="人生该如何起头")
# 数出结果
print('output-->', np.array(output).shape)
if __name__ == '__main__':
# text_classification()
feature_extraction()
完形填空任务
完型填空任务又被叫做“遮蔽语言建模任务”,它属于BERT模型训练过程中的子任务。
# 3.完形填空任务
def fill_mask():
# 定义模型
model = pipeline(task="fill-mask", model="../model/chinese-bert-wwm")
# 直接预测
output = model("我想明天去[MASK]家吃饭.")
print('output-->', output)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
fill_mask()
阅读理解任务
阅读理解任务又称为“抽取式问答任务”,即输入一段文本和一个问题,让模型输出结果。
# 4.阅读理解任务
def question_answer():
context = '我叫张三,我是一个程序员,我的喜好是打篮球。'
questions = ['我是谁?', '我是做什么的?', '我的爱好是什么?']
model = pipeline(task="question-answering", model="../model/chinese_pretrain_mrc_roberta_wwm_ext_large")
output = model(context=context, question=questions)
print('output-->', output)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
# fill_mask()
question_answer()
文本摘要任务
文本摘要,就是输入一段文本,输出是一段概况、简单的文字。说白了,就是对一段话进行总结。
# 5.文本摘要任务
def summarization():
text = "BERT is a transformers model pretrained on a large corpus of English data " \
"in a self-supervised fashion. This means it was pretrained on the raw texts " \
"only, with no humans labelling them in any way (which is why it can use lots " \
"of publicly available data) with an automatic process to generate inputs and " \
"labels from those texts. More precisely, it was pretrained with two objectives:Masked " \
"language modeling (MLM): taking a sentence, the model randomly masks 15% of the " \
"words in the input then run the entire masked sentence through the model and has " \
"to predict the masked words. This is different from traditional recurrent neural " \
"networks (RNNs) that usually see the words one after the other, or from autoregressive " \
"models like GPT which internally mask the future tokens. It allows the model to learn " \
"a bidirectional representation of the sentence.Next sentence prediction (NSP): the models" \
" concatenates two masked sentences as inputs during pretraining. Sometimes they correspond to " \
"sentences that were next to each other in the original text, sometimes not. The model then " \
"has to predict if the two sentences were following each other or not."
model = pipeline(task="summarization", model="../model/distilbart-cnn-12-6")
output = model(text)
print("output-->", output)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
# fill_mask()
# question_answer()
summarization()
NER任务
命名实体识别(NER)任务是NLP中的基础任务。它用于识别文本中的人名(PER)、地名(LOC)、组织(ORG)以及其他实体(MISC)等。例如:(王 B-PER) (小 I-PER) (明 I-PER) (在 O) (办 B-LOC) (公 I-LOC) (室 I-LOC)。其中O表示一个非实体,B表示一个实体的开始,I表示一个实体块的内部。
命名实体识别本质上是一个分类任务(又叫序列标注任务),命名实体识别是句法分析的基础,而句法分析又是NLP任务的核心。
# 6.NER任务
def ner():
model = pipeline(task="token-classification", model="../model/roberta-base-finetuned-cluener2020-chinese")
output = model("我爱北京天安门,天安门上太阳升")
print("output-->", output)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
# fill_mask()
# question_answer()
# summarization()
ner()
自动模型方式
文本分类任务
文本分类是指模型可以根据文本中的内容来进行分类。
# 1.文本分类任务
def text_classification():
# 1.加载tokenizer
my_tokenizer = AutoTokenizer.from_pretrained("../model/chinese_sentiment")
print('my_tokenizer-->', my_tokenizer)
# 2.加载模型
model = AutoModelForSequenceClassification.from_pretrained("../model/chinese_sentiment")
print("model-->", model)
# 3.准备句子
message = "人生该如何起头"
# 4.对句子进行编码
# padding:True/longest,则表示以最长的句子打padding,max_length,表示以max_length的长度打padding
msg_encode = my_tokenizer.encode(text=message, padding='longest', truncation=True, max_length=20, return_tensors='pt')
print("msg_encode-->", msg_encode, msg_encode.shape)
# 5.传入模型进行预测
model.eval()
output = model(msg_encode)
print("output-->", output)
if __name__ == '__main__':
text_classification()
特征提取任务
特征抽取任务只返回文本处理后的特征,属于预训练模型的范畴。特征抽取任务的输出结果需要和其他模型一起工作。
# 2.特征提取任务
def feature_extraction():
# 1.加载tokenizer
my_tokenizer = AutoTokenizer.from_pretrained("../model/bert-base-chinese")
print("my_tokenizer-->", my_tokenizer)
# 2.加载模型
model = AutoModel.from_pretrained("../model/bert-base-chinese")
print("model-->", model)
# 3.准备句子
message = ["人生该如何起头","你是谁"]
# 4.对句子进行编码
# encode_plus:更加强大的编码方式
output1 = my_tokenizer.encode_plus(text=message, padding="max_length", truncation=True, return_tensors='pt', max_length=30)
# input_ids:根据词表,用于将词表转为id,起始为101,分隔符为102
# token_type_ids:标识不同的句子,用0标识第一个句子,用1表示第二个句子
# attention_mask:把padding的位置标识为0,非padding的位置标识为1
print('output1-->', output1)
# 5.传入模型进行预测
model.eval()
output = model(**output1)
# token级别的词向量
print("output-->", output.last_hidden_state.shape) # [1, 30, 768]
# 从[1,30,768]中拿出 CLS[1,768],经过linear层(768,768),不改变维度,得到[1,768],这个数据就代表整个句子,也称为句向量。
print("output-->", output.pooler_output.shape) # [1, 768]
if __name__ == '__main__':
# text_classification()
feature_extraction()
完形填空任务
完型填空任务又被叫做“遮蔽语言建模任务”,它属于BERT模型训练过程中的子任务。
# 3.完形填空任务
def fill_mask():
#1.加载分词器
tokenizer = AutoTokenizer.from_pretrained("../model/chinese-bert-wwm")
print("tokenizer-->", tokenizer)
#2.加载模型
model = AutoModelForMaskedLM.from_pretrained("../model/chinese-bert-wwm")
print("model-->", model)
#3.准备语句
message = "我今天中午准备去[MASK]家吃饭"
#4.对句子进行编码
input = tokenizer.encode_plus(message, return_tensors='pt')
print('output1-->', input)
#5.送入模型
model.eval()
output = model(**input)
print('output-->', output.logits.shape) # [1, 14, 21128]
# 一定要item(),把数据取出来,logits就是预测结果。
index = torch.argmax(output.logits[0][9]).item()
print("mask_pred_idx-->", index)
res = tokenizer.convert_ids_to_tokens(index)
print("res-->", res)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
fill_mask()
阅读理解任务
阅读理解任务又称为“抽取式问答任务”,即输入一段文本和一个问题,让模型输出结果。
# 4.阅读理解任务
def reading():
#1.加载分词器
tokenizer = AutoTokenizer.from_pretrained("../model/chinese_pretrain_mrc_roberta_wwm_ext_large")
#2.加载模型
model = AutoModelForQuestionAnswering.from_pretrained("../model/chinese_pretrain_mrc_roberta_wwm_ext_large")
#3.准备语句,并且编码
context = '我叫张三,我是一个程序员,我的喜好是打篮球'
questions = ['我是谁', '我是做什么的', '我的爱好是什么']
#4.模型预测
model.eval()
for question in questions:
input = tokenizer.encode_plus(question, context, return_tensors='pt')
print("input-->", input)
output = model(**input)
print("output-->", output)
# 获取开始和结束的logits
start = torch.argmax(output.start_logits, dim=-1)
end = torch.argmax(output.end_logits, dim=-1)
print("start-->", start)
print("end-->", end)
# 把logits转换为汉字
answer = tokenizer.convert_ids_to_tokens(input["input_ids"][0][start: end + 1])
print("question-->", question)
print("answer-->", answer)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
# fill_mask()
reading()
文本摘要任务
文本摘要,就是输入一段文本,输出是一段概况、简单的文字。说白了,就是对一段话进行总结。
# 5.文本摘要任务
def summarization():
#1.加载分词器
tokenizer = AutoTokenizer.from_pretrained("../model/distilbart-cnn-12-6")
#2.加载模型
model = AutoModelForSeq2SeqLM.from_pretrained("../model/distilbart-cnn-12-6")
#3.准备语句,编码
text = "BERT is a transformers model pretrained on a large corpus of English data " \
"in a self-supervised fashion. This means it was pretrained on the raw texts " \
"only, with no humans labelling them in any way (which is why it can use lots " \
"of publicly available data) with an automatic process to generate inputs and " \
"labels from those texts. More precisely, it was pretrained with two objectives:Masked " \
"language modeling (MLM): taking a sentence, the model randomly masks 15% of the " \
"words in the input then run the entire masked sentence through the model and has " \
"to predict the masked words. This is different from traditional recurrent neural " \
"networks (RNNs) that usually see the words one after the other, or from autoregressive " \
"models like GPT which internally mask the future tokens. It allows the model to learn " \
"a bidirectional representation of the sentence.Next sentence prediction (NSP): the models" \
" concatenates two masked sentences as inputs during pretraining. Sometimes they correspond to " \
"sentences that were next to each other in the original text, sometimes not. The model then " \
"has to predict if the two sentences were following each other or not."
inputs = tokenizer.encode_plus(text, return_tensors="pt")
#4.送入模型,进行摘要生成
model.eval()
output = model.generate(inputs["input_ids"])
# [1, 84]:表示生成了一段话,这段话有84个token
print('output-->', output, output.shape)
#5.解码
res = tokenizer.decode(output[0], skip_special_tokens=True, clean_up_tokenization_spaces=False)
print("res-->", res)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
# fill_mask()
# reading()
summarization()
NER任务
命名实体识别(NER)任务是NLP中的基础任务。它用于识别文本中的人名(PER)、地名(LOC)、组织(ORG)以及其他实体(MISC)等。例如:(王 B-PER) (小 I-PER) (明 I-PER) (在 O) (办 B-LOC) (公 I-LOC) (室 I-LOC)。其中O表示一个非实体,B表示一个实体的开始,I表示一个实体块的内部。
命名实体识别本质上是一个分类任务(又叫序列标注任务),命名实体识别是句法分析的基础,而句法分析又是NLP任务的核心。
# 6.NER任务
def ner():
#1.加载分词器
tokenizer = AutoTokenizer.from_pretrained("../model/roberta-base-finetuned-cluener2020-chinese")
#2.加载模型
model = AutoModelForTokenClassification.from_pretrained("../model/roberta-base-finetuned-cluener2020-chinese")
configs = AutoConfig.from_pretrained("../model/roberta-base-finetuned-cluener2020-chinese")
#3.准备语料,编码
message = '我爱北京天安门,天安门上太阳升'
inputs = tokenizer.encode_plus(message, return_tensors='pt')
print("inputs-->", inputs)
#4.送入模型,进行预测
model.eval()
output = model(**inputs)
# [1, 17, 32],默认对每一个token做了一个32的分类
print("output-->", output.logits, output.logits.shape) # [1, 17, 32]
#5.获得添加特殊字符的句子
tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0])
print("tokens-->", tokens)
#6.判断token是否是特殊符号,特殊符号一定不是实体。
output_list = []
for token, logit in zip(tokens, output.logits[0]):
if token in tokenizer.all_special_tokens:
continue
# 得到预测结果的index
index = torch.argmax(logit, dim=-1).item()
# 把index转换为label
label = configs.id2label[index]
output_list.append((token, label))
print("output_list-->", output_list)
if __name__ == '__main__':
# text_classification()
# feature_extraction()
# fill_mask()
# reading()
# summarization()
ner()
具体模型方式
完型填空任务又被叫做“遮蔽语言建模任务”,它属于BERT模型训练过程中的子任务。
下面使用具体模型来实现。
import torch
from transformers import BertForMaskedLM, BertTokenizer
def fill_mask():
#1.加载分词器
tokenizer = BertTokenizer.from_pretrained("../model/chinese-bert-wwm")
#2.加载模型
model = BertForMaskedLM.from_pretrained("../model/chinese-bert-wwm")
#3.准备语料,编码
message = "我明天准备去[MASK]家吃饭"
inputs = tokenizer.encode_plus(message, return_tensors='pt')
print("inputs-->", inputs)
#4.送入模型,进行预测
output = model(**inputs).logits
print("output-->", output, output.shape)
#5.获取结果
index = torch.argmax(output[0][7]).item()
print("index-->", index)
res = tokenizer.convert_ids_to_tokens(index)
print("res-->", res)
if __name__ == '__main__':
fill_mask()
微调实战代码
3 个文件- 📄 demo.py 1.1KB 下载
- 📄 demo01_pipeline.py 4.9KB 下载
- 📄 demo02_automodel.py 10.2KB 下载