bert实战:使用distilbert进行文本情感分类(代码片段)

梆子井欢喜坨 梆子井欢喜坨     2022-12-04     762

关键词:

这次根据一篇教程Jay Alammar: A Visual Guide to Using BERT for the First Time学习下如何在Pytorch框架下使用BERT。

主要参考了中文翻译版本

教程提供了可用的代码,可以在colab或者github获取。

1. huggingface/transformers

Transformers提供了数千个预训练的模型来执行文本任务,如100多种语言的分类、信息提取、问答、摘要、翻译、文本生成等。

文档:https://huggingface.co/transformers/
模型:https://huggingface.co/models

huggingface团队用pytorch复现许多模型,本次要使用它们提出的DistilBERT模型。

2. 数据集

本次使用的数据集是 SST2,是一个电影评论的数据集。用标签 0/1 代表情感正负。
在这里插入图片描述

3. 模型

在这里插入图片描述
句子的情感分类模型由两部分组成:

  • DistilBERT处理输入的句子,并将它从句子中提取的一些信息传递给下一个模型。 DistilBERT 是一个更小版本的 BERT 模型,是由 HuggingFace 团队开源的。它保留了 BERT 能力的同时,比 BERT 更小更快。
  • 一个基本的 Logistic Regression 模型,它将处理 DistilBERT 的输出结果并且将句子进行分类,输出0或1。

在这两个模型之间传递的数据是一个 768 维的向量。
假设句子长度为n,那及一个句子经过BERT应该得到n个768 维的向量。
在这里插入图片描述
实际上只使用[CLS]位置的向量看作是我们用来分类的句子的embedding向量。
在这里插入图片描述

4. 训练与预测

4.1 训练

虽然我们使用了两个模型,但是只需要训练回归模型(Logistic Regression)即可。
对于 DistilBERT 模型,使用该模型预训练的参数即可,这个模型没有被用来做句子分类任务的训练和微调。
使用 Scikit Learn 工具包进行操作。将整个BERT输出的数据分成 train/test 数据集。
在这里插入图片描述
将75%的数据划为训练集,将25%的数据划分为测试集。
sklearn的train/test split在进行分割之前会对示例进行shuffles。
接下来就用机器学习的方法训练回归模型就行了。

4.2 预测

如何使用模型进行预测呢?
比如,我们要对句子 “a visually stunning rumination on love” 进行分类
第一步,用 BERT 的分词器(tokenizer)将句子分成 tokens;
第二步,添加特殊的 tokens 用于句子分类任务(在句子开头加上 [CLS],在句子结尾加上 [SEP]);
第三步,分词器(tokenizer)会将每个 token 替换成 embedding 表中的ID,embedding 表是我们预训练模型自带的;
在这里插入图片描述
下面这一行代码就完成了上述3步。

tokenizer.encode("a visually stunning rumination on love", add_special_tokens=True)

每个token的输出都是一个一个768维的向量。
在这里插入图片描述
由于这是一个句子分类任务,我们只取第一个向量(与 [CLS] token有关的向量)而忽略其他的 token 向量。
将该向量作为 逻辑回归的输入。

5. 代码(加入图片注释)

环境的配置就不细说了,可以在transformers的github页面查阅

5.1 导入所需的工具包

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
import transformers as ppb
import warnings
warnings.filterwarnings('ignore')

5.2 导入数据集

数据集的链接,这里我已经提前下载到本地了。

df = pd.read_csv('./train.tsv', delimiter='\\t', header=None)
# 为做示例只取前2000条数据
batch_1 = df[:2000]
# 查看正负例的数量
batch_1[1].value_counts()

5.3 导入预训练模型

下载大概花费了40s

# For DistilBERT:
model_class, tokenizer_class, pretrained_weights = (ppb.DistilBertModel, ppb.DistilBertTokenizer, 'distilbert-base-uncased')

## Want BERT instead of distilBERT? Uncomment the following line:
#model_class, tokenizer_class, pretrained_weights = (ppb.BertModel, ppb.BertTokenizer, 'bert-base-uncased')

# Load pretrained model/tokenizer
tokenizer = tokenizer_class.from_pretrained(pretrained_weights)
model = model_class.from_pretrained(pretrained_weights)

5.4 数据预处理

包括token化和padding
token化的过程与4.2中图片相同

tokenized = batch_1[0].apply((lambda x:tokenizer.encode(x, add_special_tokens = True)))

在这里插入图片描述
需要把所有的向量用 id 0 来填充较短的句子到一个相同的长度。

max_len = 0
for i in tokenized.values:
    if len(i) > max_len:
        max_len = len(i)
padded = np.array([i + [0] * (max_len - len(i)) for i in tokenized.values])
np.array(padded).shape
# Masking
# attention_mask(也就是input_mask)的0值只作用在padding部分
# np.where(condition, x, y) 满足条件(condition),输出x,不满足输出y
attention_mask = np.where(padded != 0, 1, 0)
attention_mask.shape

padding的过程如下图所示,值得注意的是
如果我们直接把padded发给BERT,那会让它有点混乱。
我们需要创建另一个变量,告诉它在处理输入时忽略(屏蔽)我们添加的填充。这就是attention_mask:
在这里插入图片描述

5.5 使用BERT

# 基本可以看作又进行了一次embedding
input_ids = torch.LongTensor(padded)
attention_mask = torch.tensor(attention_mask)

with torch.no_grad():
    last_hidden_states = model(input_ids, attention_mask=attention_mask)

# BERT模型输出的张量尺寸为[2000, 59, 768]
# 取出[CLS]token对应的向量
features = last_hidden_states[0][:,0,:].numpy()
labels = batch_1[1] # 取出标签

在这里插入图片描述
在这里插入图片描述

5.5 训练一个Logistic回归模型

# 划分训练集和测试集
train_features, test_features, train_labels, test_labels = train_test_split(features, labels)
# 搜索正则化强度的C参数的最佳值。
parameters = 'C': np.linspace(0.0001, 100, 20)
grid_search = GridSearchCV(LogisticRegression(), parameters)
grid_search.fit(train_features, train_labels)

print('best parameters: ', grid_search.best_params_)
print('best scrores: ', grid_search.best_score_)

lr_clf = LogisticRegression(C = 10.526405263157894)
lr_clf.fit(train_features, train_labels)
lr_clf.score(test_features, test_labels)

在这里插入图片描述
在使用完整数据集的时候,准确率约为0.847。

6.结果评估

from sklearn.dummy import DummyClassifier
clf = DummyClassifier()

scores = cross_val_score(clf, train_features, train_labels)
print("Dummy classifier score: %0.3f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))

可以发现训练出的分类器的结果明显好于随即预测的结果。
但这个例子恐怕完全没有体现出BERT的性能,缺少了fine-tuning阶段。

该数据集上最高的准确率是 96.8. (根据19年的教程)
通过fine-tuning 更新 BERT 的参数权重, 可以提升DistilBERT 模型在句子分类任务(称为下游任务)上得到的分数。
通过对 DistilBERT 进行 fine-tuned 之后达到了 90.7 的准确率。
全尺寸的 BERT 模型能达到 94.9 的分数。

使用训练的 BERT 模型预测原始文本的情感,拥抱脸

】使用训练的BERT模型预测原始文本的情感,拥抱脸【英文标题】:PredictingSentimentofRawTextusingTrainedBERTModel,HuggingFace【发布时间】:2021-12-1713:33:50【问题描述】:我正在预测具有正面、负面和中性类别的推文的情绪分析。我已经使... 查看详情

nlp进阶,bert+bilstm情感分析实战(代码片段)

Bert+BiLSTM做情感分析情感分析情感分析一类的任务比如商品评价正负面分析,敏感内容分析,用户感兴趣内容分析、甚至安全领域的异常访问日志分析等等实际上都可以用文本分类的方式去做,情感分析的问题本质... 查看详情

论文泛读187使用bert基于阿拉伯语方面的情感分析

贴一下汇总贴:论文阅读记录论文链接:《ArabicaspectbasedsentimentanalysisusingBERT》一、摘要基于方面的情感分析(ABSA)是一种文本分析方法,它定义了与特定目标相关的某些方面的观点的极性。关于ABSA的大部分研究是用英... 查看详情

论文泛读187使用bert基于阿拉伯语方面的情感分析

贴一下汇总贴:论文阅读记录论文链接:《ArabicaspectbasedsentimentanalysisusingBERT》一、摘要基于方面的情感分析(ABSA)是一种文本分析方法,它定义了与特定目标相关的某些方面的观点的极性。关于ABSA的大部分研究是用英... 查看详情

bert实战:使用bert实现文本分类。(代码片段)

1、简介最近使用Bert实现了文本分类,模型使用的是bert的base版本。本文记录一下实现过程。数据集:cnews,包含三个文件,分别是cnews.train.txt、cnews.test.txt、cnews.val.txt。类别包含10类,分别是:体育、娱乐... 查看详情

bert-多标签文本分类实战之一——实战项目总览

[1]总览  【BERT-多标签文本分类实战】系列共七篇文章:  【BERT-多标签文本分类实战】之一——实战项目总览  【BERT-多标签文本分类实战】之二——BERT的地位与名词术语解释  【BERT-多标签文本分类实战】之三—... 查看详情

使用领域文本预训练 BERT/RoBERTa 语言模型,估计需要多长时间?哪个更快?

】使用领域文本预训练BERT/RoBERTa语言模型,估计需要多长时间?哪个更快?【英文标题】:Pre-trainingBERT/RoBERTalanguagemodelusingdomaintext,howlongitgonnatakeestimately?whichisfaster?【发布时间】:2020-05-2423:45:34【问题描述】:我想使用领域语料... 查看详情

删除 Bert 中的 SEP 令牌以进行文本分类

】删除Bert中的SEP令牌以进行文本分类【英文标题】:RemovingSEPtokeninBertfortextclassification【发布时间】:2020-04-3007:49:15【问题描述】:给定一个情感分类数据集,我想微调Bert。如您所知,BERT创建的目的是在给定当前句子的情况下... 查看详情

keras深度学习实战(30)——使用文本生成模型进行文学创作(代码片段)

Keras深度学习实战(30)——使用文本生成模型进行文学创作0.前言1.文本生成模型与数据集分析1.1数据集分析1.2模型分析2.构建文本生成模型2.1数据预处理2.2模型构建与训练小结系列链接0.前言在情感分类任务中,神经... 查看详情

[论文笔记]distilbert,adistilledversionofbert:smaller,faster,cheaperandlighter

引言本文是DistilBERT1的阅读笔记。核心思想DistilBERT是一个更小更快的BERT模型,类似ALBERT,也是用来给BERT瘦身的。DistilBERT应用了基于三重损失(TripletLoss)的知识蒸馏(knowledgedistillation)方法。相比BERT模型,DistilBERT的参数... 查看详情

使用 huggingface 的 distilbert 模型生成文本

】使用huggingface的distilbert模型生成文本【英文标题】:Textgenerationusinghuggingface\'sdistilbertmodels【发布时间】:2020-04-0201:43:35【问题描述】:我一直在为huggingface的DistilBERT模型苦苦挣扎,因为文档似乎很不清楚,而且他们的示例(... 查看详情

论文泛读198通过输入空间转换利用bert进行多模态目标情感分类

贴一下汇总贴:论文阅读记录论文链接:《ExploitingBERTForMultimodalTargetSentimentClassificationThroughInputSpaceTranslation》一、摘要多模态目标/方面情感分类结合了多模态情感分析和方面/目标情感分类。该任务的目标是结合视觉和语... 查看详情

论文泛读198通过输入空间转换利用bert进行多模态目标情感分类

贴一下汇总贴:论文阅读记录论文链接:《ExploitingBERTForMultimodalTargetSentimentClassificationThroughInputSpaceTranslation》一、摘要多模态目标/方面情感分类结合了多模态情感分析和方面/目标情感分类。该任务的目标是结合视觉和语... 查看详情

论文泛读198通过输入空间转换利用bert进行多模态目标情感分类

贴一下汇总贴:论文阅读记录论文链接:《ExploitingBERTForMultimodalTargetSentimentClassificationThroughInputSpaceTranslation》一、摘要多模态目标/方面情感分类结合了多模态情感分析和方面/目标情感分类。该任务的目标是结合视觉和语... 查看详情

使用 pytorch 进行 BERT 文本分类

】使用pytorch进行BERT文本分类【英文标题】:BERTtextclasisificationusingpytorch【发布时间】:2021-11-1321:08:19【问题描述】:我正在尝试借助此代码[https://towardsdatascience.com/bert-text-classification-using-pytorch-723dfb8b6b5b]构建用于文本分类的BERT... 查看详情

中文情感分类任务如何对bert语言模型微调,微调后的模型如何使用

中文情感分类任务如何对bert语言模型微调,微调后的模型如何使用  查看详情

使用 BERT 和 Keras 的神经网络进行文本分类

】使用BERT和Keras的神经网络进行文本分类【英文标题】:UsingBERTandKeras\'sneuralnetworkfortextclassification【发布时间】:2021-05-0802:18:27【问题描述】:我正在尝试使用BERT运行二进制监督文本分类任务,但我不知道该怎么做。我尝试使... 查看详情

keras深度学习实战——使用长短时记忆网络构建情感分析模型(代码片段)

Keras深度学习实战——使用长短时记忆网络构建情感分析模型0.前言1.构建LSTM模型进行情感分类1.1数据集分析1.2模型构建2.构建多层LSTM进行情感分类相关链接0.前言我们已经学习了如何使用循环神经网络(Recurrentneuralnetworks,RNN)构建... 查看详情