Bert实现意图分类
来自保姆级教程,用PyTorch和BERT进行文本分类
一、bert
bert模型的下载:去抱抱脸网站bert-base-cased at main下载预训练模型,下载对应的这三个文件,这里下载的是pytorch版本
下载后放入对应文件夹,是这样的:
验证bert能不能调用成功:
from transformers import BertModel,BertTokenizer
BERT_PATH = './bert-base-cased'
tokenizer = BertTokenizer.from_pretrained(BERT_PATH)
print(tokenizer.tokenize('I have a good time, thank you.'))
bert = BertModel.from_pretrained(BERT_PATH)
print('load bert model over')['I', 'have', 'a', 'good', 'time',
',', 'thank', 'you', '.']
load bert model over
BertTokenizer解析:BertTokenizer将数据处理成bert需要的格式
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
example_text = 'I will watch Memento tonight'
bert_input = tokenizer(example_text,padding='max_length', max_length = 10, truncation=True,return_tensors="pt")
# ------- bert_input ------
print(bert_input['input_ids'])
print(bert_input['token_type_ids'])
print(bert_input['attention_mask'])tensor([[ 101, 146, 1209, 2824, 2508,26173, 3568, 102, 0, 0]])
tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
tensor([[1, 1, 1, 1, 1, 1, 1, 1, 0, 0]])
BertTokenizer参数:
padding
:将每个sequence填充到指定的最大长度。max_length
: 每个sequence的最大长度。本示例中我们使用 10,但对于本文实际数据集,我们将使用 512,这是 BERT 允许的sequence 的最大长度。truncation
:如果为True,则每个序列中超过最大长度的标记将被截断。return_tensors
:将返回的张量类型。由于我们使用的是 Pytorch,所以我们使用pt
;如果你使用 Tensorflow,那么你需要使用tf
BertTokenizer输出:bert_input
input_ids
,它是每个 token 的 id 表示,101代表[CLS],102代表[SEP],0代表[PAD]token_type_ids
,它是一个 binary mask,用于标识 token 属于哪个 sequence。如果我们只有一个 sequence,那么所有的 token 类型 id 都将为 0。对于文本分类任务,token_type_ids
是 BERT 模型的可选输入参数。attention_mask
,它是一个 binary mask,用于标识 token 是真实 word 还是只是由填充得到。如果 token 包含 [CLS]、[SEP] 或任何真实单词,则 mask 将为 1。如果 token 只是 [PAD] 填充,则 mask 将为 0
二、定义模型
bert的输出送入一层全连接层,再通过一层relu层
from torch import nn
from transformers import BertModel
import torchclass BertClassifier(nn.Module):def __init__(self, dropout=0.5):super(BertClassifier, self).__init__()#self.bert = BertModel.from_pretrained('bert-base-cased')self.bert = BertModel.from_pretrained('/home/jiqiboyi03/chenpp/bert-classification/bert-base-cased')self.dropout = nn.Dropout(dropout)self.linear = nn.Linear(768, 7)self.relu = nn.ReLU()def forward(self, input_id, mask):_, pooled_output = self.bert(input_ids= input_id, attention_mask=mask,return_dict=False)# print(pooled_output.size())#[batch_size,768] CLS的向量dropout_output = self.dropout(pooled_output)linear_output = self.linear(dropout_output)final_layer = self.relu(linear_output)return final_layer
输入input_ids和mask的格式应该是:以batch_size=2为例,input_ids应该是二维的,mask二维三维都可以
input_id=torch.tensor([[ 101, 178, 112, 173, 1176, 170, 189, 3624, 3043, 1121,17496, 1396, 11305, 1106, 1207, 26063, 4661, 1664, 26645, 102],[ 101, 1110, 1175, 170, 20811, 3043, 1121, 10552, 4121, 1106,21718, 1179, 175, 4047, 21349, 2528, 102, 0, 0, 0]])
mask=torch.tensor([[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]]])
三、数据预处理
import torch
import numpy as np
from transformers import BertTokenizer
import torch.utils.data as databert_path='/home/jiqiboyi03/chenpp/bert-classification/bert-base-cased'
tokenizer = BertTokenizer.from_pretrained(bert_path)
labels={'AddToPlaylist':0,'BookRestaurant':1,'GetWeather':2,'PlayMusic':3,'RateBook':4,'SearchCreativeWork':5,'SearchScreeningEvent':6}class Dataset(data.Dataset):def __init__(self, df):self.labels = [labels[label] for label in df['category']]self.texts = [tokenizer(text,padding='max_length',max_length = 20,truncation=True,return_tensors="pt")for text in df['text']]def classes(self):return self.labelsdef __len__(self):return len(self.labels)def get_batch_labels(self, idx):# Fetch a batch of labelsreturn np.array(self.labels[idx])def get_batch_texts(self, idx):# Fetch a batch of inputsreturn self.texts[idx]def __getitem__(self, idx):batch_texts = self.get_batch_texts(idx)batch_y = self.get_batch_labels(idx)return batch_texts, batch_y
其中df的格式应该是:
{'category': ['PlayMusic', .....],
'text': ['open groove shark and play native us',..... }
四、训练
from torch.optim import Adam
from tqdm import tqdm
from snips_process import Dataset
import torch
import torch.utils.data as data
import torch.nn as nn
import matplotlib.pyplot as pltdef train(model, train_data, val_data, learning_rate, epochs):# 通过Dataset类获取训练和验证集train, val = Dataset(train_data), Dataset(val_data)# DataLoader根据batch_size获取数据,训练时选择打乱样本train_dataloader = torch.utils.data.DataLoader(train, batch_size=32, shuffle=True)val_dataloader = torch.utils.data.DataLoader(val, batch_size=32)# 判断是否使用GPUuse_cuda = torch.cuda.is_available()device = torch.device("cuda" if use_cuda else "cpu")# 定义损失函数和优化器criterion = nn.CrossEntropyLoss()optimizer = Adam(model.parameters(), lr=learning_rate)train_loss=[]train_acc=[]val_loss=[]val_acc=[]EPOCH=[]if use_cuda:model = model.cuda()criterion = criterion.cuda()# 开始进入训练循环for epoch_num in range(epochs):# 定义两个变量,用于存储训练集的准确率和损失total_acc_train = 0total_loss_train = 0# 进度条函数tqdmfor train_input, train_label in tqdm(train_dataloader):train_label = train_label.to(device)#1维mask = train_input['attention_mask'].to(device)input_id = train_input['input_ids'].squeeze(1).to(device)# print("input_id size:",input_id.size())#[32,20]# print("mask size:",mask.size())# 通过模型得到输出output = model(input_id, mask)#[32,21]# 计算损失batch_loss = criterion(output, train_label)total_loss_train += batch_loss.item()# 计算精度acc = (output.argmax(dim=1) == train_label).sum().item()total_acc_train += acc# 模型更新model.zero_grad()batch_loss.backward()optimizer.step()# ------ 验证模型 -----------# 定义两个变量,用于存储验证集的准确率和损失total_acc_val = 0total_loss_val = 0# 不需要计算梯度with torch.no_grad():# 循环获取数据集,并用训练好的模型进行验证for val_input, val_label in val_dataloader:# 如果有GPU,则使用GPU,接下来的操作同训练val_label = val_label.to(device)mask = val_input['attention_mask'].to(device)input_id = val_input['input_ids'].squeeze(1).to(device)output = model(input_id, mask)batch_loss = criterion(output, val_label)total_loss_val += batch_loss.item()acc = (output.argmax(dim=1) == val_label).sum().item()total_acc_val += acctrain_loss.append(total_loss_train / len(train_data['text']))train_acc.append(total_acc_train / len(train_data['text']))val_loss.append(total_loss_val / len(val_data['text']))val_acc.append(total_acc_val / len(val_data['text']))EPOCH.append(epoch_num+1)print(f'''Epochs: {epoch_num + 1} | Train Loss: {total_loss_train / len(train_data['text']): .3f} | Train Accuracy: {total_acc_train / len(train_data['text']): .3f} | Val Loss: {total_loss_val / len(val_data['text']): .3f} | Val Accuracy: {total_acc_val / len(val_data['text']): .3f}''')print("saving bert model......")torch.save(model.state_dict(),'../bert-base-cased/bert_trained_snips_full.pt')#画图plt.plot(EPOCH,train_loss,'b',label='train_loss')plt.plot(EPOCH, train_acc,'g',label='train_acc')plt.plot(EPOCH, val_loss, 'r', label='val_loss')plt.plot(EPOCH, val_acc, 'c', label='val_acc')plt.show()
注:train_data即数据预处理中的df,经过DataLoader会加一维batch_size,变成3维,但是bert的输入得是2维,因此经过了squeeze(1)操作
五、验证
from snips_process import Dataset,df_test
import torch
from model import BertClassifier
import torch.utils.data as datadef evaluate(model, test_data):test = Dataset(test_data)length=len(test_data['text'])test_dataloader = torch.utils.data.DataLoader(test, batch_size=2)use_cuda = torch.cuda.is_available()device = torch.device("cuda" if use_cuda else "cpu")if use_cuda:model = model.cuda()total_acc_test = 0with torch.no_grad():for test_input, test_label in test_dataloader:test_label = test_label.to(device)mask = test_input['attention_mask'].to(device)input_id = test_input['input_ids'].squeeze(1).to(device)output = model(input_id, mask)acc = (output.argmax(dim=1) == test_label).sum().item()total_acc_test += accprint(f'Test Accuracy: {total_acc_test / length: .3f}')
Bert实现意图分类相关推荐
- 搜索引擎——用户搜索意图的理解及其难点解析,本质是利用机器学习用户的意图分类...
用户搜索意图的理解及其难点解析 搜索引擎涉及的技术非常的繁复,既有工程架构方面的,又有算法策略方面的.综合来讲,一个搜索引擎的技术构建主要包含三大部分: 对 query 的理解 对内容(文档)的理解 ...
- 【NLP】Kaggle从零到实践:Bert中文文本分类
Bert是非常强化的NLP模型,在文本分类的精度非常高.本文将介绍Bert中文文本分类的基础步骤,文末有代码获取方法. 步骤1:读取数据 本文选取了头条新闻分类数据集来完成分类任务,此数据集是根据头条 ...
- 【PaddleNLP实战】对话意图分类方案
基于预训练模型ERNIE 3.0 和CrossWOZ数据的意图识别分类任务 AI Studio平台默认安装了Paddle和PaddleNLP,并定期更新版本. 如需手动更新Paddle,可参考飞桨安装 ...
- Bert实战--文本分类(一)
使用Bert预训练模型进行文本分类 bert做文本分类,简单来说就是将每句话的第一个位置加入了特殊分类嵌入[CLS].而该[CLS]包含了整个句子的信息,它的最终隐藏状态(即,Transformer的 ...
- Rasa实体抽取和意图分类之DIETClassifier
Rasa实体抽取和意图分类之DIETClassifier rasa\nlu\classifiers\diet_classifier.py DIETClassifier训练模型是diet_classif ...
- 基于维基百科的用户意图分类
关于"用户查询意图分类(识别)",在很久以前就开始关注了,最近开始阅读一些文章.前期得文章中,多半在特征抽取中,提到的都是用其他得资源比如查询日志比较多.今天偶然读了一篇文章,以一 ...
- Pytorch Bert+BiLstm文本分类
文章目录 前言 一.运行环境 二.数据 三.模型结构 四.训练 五.测试及预测 前言 昨天按照该文章(自然语言处理(NLP)Bert与Lstm结合)跑bert+bilstm分类的时候,没成功跑起来,于 ...
- 深度学习 一 :使用BERT做 NLP分类任务
文章目录 前言 什么是BERT? 它与其他机器学习算法的不同之处 代码示例 开始设置 准备数据 训练模型 做一个预测 鸣谢!!!! 前言 ****Bert的原理资料已经很多这里不多陈述,仅仅用一个实际 ...
- 二分类问题:基于BERT的文本分类实践!附完整代码
Datawhale 作者:高宝丽,Datawhale优秀学习者 寄语:Bert天生适合做分类任务.文本分类有fasttext.textcnn等多种方法,但在Bert面前,就是小巫见大巫了. 推荐评论展 ...
最新文章
- ORA-32004错误的解决方法
- 利用FreeNas创建AFP共享
- c语言指针写鞍点,c语言——鞍点
- Debian下搭建Samba CTDB集群。
- transforms.Compose()函数
- java实现邮件发送, 抄送及多附件发送
- python模块heapq之简单学习使用
- 僵尸进程与孤儿进程(精简易懂,直接要害)
- html背景半透明 字不变,css实现背景半透明文字不透明的效果示例
- 【项目管理】开发方法和生命周期绩效域管理
- Zynga和Unity:独家奖励广告
- hadoop+Spark实战基于大数据技术之电视收视率企业项目实战
- 上海证券交易所-债券品种介绍
- 高仿微信抢红包动画特效
- do_syscall_64 函数
- Web设计网站软件推荐
- 【力扣】6. Z 字形变换
- HTTP访问控制(CORS) 跨域访问
- Filter过滤器的生命周期和工作原理
- 修改 jq weui cityPicker.js原来的值