赞
踩
1.首先什么是bert情感分类
在这个ppt中,我们将使用预先训练好的深度学习模型来处理一些文本。然后,我们将使用该模型的输出对文本进行分类。绿色方框内是电影评论中的句子列表。我们会将每个句子分为“积极地”谈论主题或“消极地”谈论主题。
我们的目标是创建一个模型,该模型采用一个句子(就像我们数据集中的句子一样)并产生1(表示句子带有积极情绪)或0(表示句子带有消极情绪)。我们可以把它想象成这样:
事实上,黄色的分类器里面是由两种模型组成:
DistilBERT处理句子,并将从中提取的一些信息传递给下一个模型。DistilBERT是由HuggingFace的团队开发并开源的BERT的缩小版。这是一个更轻更快的BERT版本,其性能大致相当。
下一个模型是scikit learn的基本逻辑回归模型,它将接受DistilBERT的处理结果,并将句子分类为肯定或否定(分别为1或0)。
我们用的是sst情感分析数据集,其组成来自电影的评论。
以前在处理不同的NLP任务通常需要不同语言模型,BERT的作用是可以嵌套在各种NLP任务中,以此为基础fine tune多个下游任务。
在LeeMeng - 進擊的 BERT:NLP 界的巨人之力與遷移學習 文章中有提到以下这几个步骤我觉得很重要:
1.准备原始文本数据
2.将原始文本转化为BERT相容的输入模型
3.利用BERT基于微调的方式建立下游人物模型
4.训练下游任务模型
5.对新样本做推论
下面我用的是hfl/chinese-bert-wwm-ext · Hugging Face 团队提供的BERT模型,十分方便。同时也有缺点,就是同意报错连接错误,出现此问题的原因是运行程序的服务器没有网络,却使用了未下载的bert-base-cased
模型。若该服务器没有网络,则可将bert-base-cased
模型,从huggingface.co官网下载下来。将其放在相应的文件夹即可。方法在这里:Hugging Face 预训练模型的下载及使用_cxxx17的博客-CSDN博客
import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.model_selection import GridSearchCV from sklearn.model_selection import cross_val_score import torch from torch import optim import torch.nn as nn import transformers as tfs import warnings from transformers import logging logging.set_verbosity_error() warnings.filterwarnings('ignore') train_df = pd.read_csv('https://github.com/clairett/pytorch-sentiment-classification/raw/master/data/SST2/train.tsv', delimiter='\t', header=None) train_set = train_df[:3000] #取其中的3000条数据作为我们的数据集 print("Train set shape:", train_set.shape) train_set[1].value_counts() #查看数据集中标签的分布 sentences = train_set[0].values targets = train_set[1].values train_inputs, test_inputs, train_targets, test_targets = train_test_split(sentences, targets) batch_size = 64 batch_count = int(len(train_inputs) / batch_size) batch_train_inputs, batch_train_targets = [], [] for i in range(batch_count): batch_train_inputs.append(train_inputs[i*batch_size : (i+1)*batch_size]) batch_train_targets.append(train_targets[i*batch_size : (i+1)*batch_size]) class BertClassificationModel(nn.Module): def __init__(self): super(BertClassificationModel, self).__init__() model_class, tokenizer_class= (tfs.BertModel, tfs.BertTokenizer) self.tokenizer = tokenizer_class.from_pretrained(r"模型地址") self.bert = model_class.from_pretrained(r"模型地址") self.dense = nn.Linear(768, 2) # bert默认的隐藏单元数是768, 输出单元是2,表示二分类 def forward(self, batch_sentences): batch_tokenized = self.tokenizer.batch_encode_plus(batch_sentences, add_special_tokens=True, max_len=66, pad_to_max_length=True) # tokenize、add special token、pad input_ids = torch.tensor(batch_tokenized['input_ids']) attention_mask = torch.tensor(batch_tokenized['attention_mask']) bert_output = self.bert(input_ids, attention_mask=attention_mask) bert_cls_hidden_state = bert_output[0][:, 0, :] # 提取[CLS]对应的隐藏状态 linear_output = self.dense(bert_cls_hidden_state) return linear_output # train the model epochs = 3 lr = 0.01 print_every_batch = 5 bert_classifier_model = BertClassificationModel() optimizer = optim.SGD(bert_classifier_model.parameters(), lr=lr, momentum=0.9) criterion = nn.CrossEntropyLoss() for epoch in range(epochs): print_avg_loss = 0 for i in range(batch_count): inputs = batch_train_inputs[i] labels = torch.tensor(batch_train_targets[i]) optimizer.zero_grad() outputs = bert_classifier_model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() print_avg_loss += loss.item() if i % print_every_batch == (print_every_batch - 1): print("Batch: %d, Loss: %.4f" % ((i + 1), print_avg_loss / print_every_batch)) print_avg_loss = 0 # eval the trained model total = len(test_inputs) hit = 0 with torch.no_grad(): for i in range(total): outputs = bert_classifier_model([test_inputs[i]]) _, predicted = torch.max(outputs, 1) if predicted == test_targets[i]: hit += 1 print("Accuracy: %.2f%%" % (hit / total * 100))
最后训练结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。