BERT-IMDB电影评论情感分类实战(完整代码、数据集、实验过程)

基于BERT模型的IMDB电影评论情感分类,是NLP经典的Hello World任务之一。

这篇文章我将带大家使用SwanLab、transformers、datasets三个开源工具,完成从数据集准备、代码编写、可视化训练的全过程。

观察了一下,中文互联网上似乎很少有能直接跑起来的BERT训练代码和教程,所以也希望这篇文章可以帮到大家。
在这里插入图片描述

1.环境安装

我们需要安装以下这4个Python库:

transformers>=4.41.0
datasets>=2.19.1
swanlab>=0.3.3

一键安装命令:

pip install transformers datasets swanlab

他们的作用分别是:

  1. transformers:HuggingFace出品的深度学习框架,已经成为了NLP(自然语言处理)领域最流行的训练与推理框架。代码中用transformers主要用于加载模型、训练以及推理。
  2. datasets:同样是HuggingFace出品的数据集工具,可以下载来自huggingface社区上的数据集。代码中用datasets主要用于下载、加载数据集。
  3. swanlab:在线训练可视化和超参数记录工具,官网,可以记录整个实验的超参数、指标、训练环境、Python版本等,并可是化成图表,帮助你分析训练的表现。代码中用swanlab主要用于记录指标和可视化。

本文的代码测试于transformers4.41.0、datasets2.19.1、swanlab==0.3.3,更多库版本可查看SwanLab记录的Python环境

2.加载BERT模型

BERT模型我们直接下载来自HuggingFace上由Google发布的bert-case-uncased预训练模型。

执行下面的代码,会自动下载模型权重并加载模型:

from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments

# 加载预训练的BERT tokenizer
model = AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)

如果国内下载比较慢的话,可以在这个百度云(提取码: u9gi)下载后,把bert-base-uncased文件夹放到根目录,然后改写上面的代码为:

model = AutoModelForSequenceClassification.from_pretrained('./bert-base-uncased', num_labels=2)

3.加载IMDB数据集

IMDB数据集(Internet Movie Database Dataset)是自然语言处理(NLP)领域中一个非常著名和广泛使用的数据集,主要应用于文本情感分析任务。

IMDB数据集源自全球最大的电影数据库网站Internet Movie Database(IMDb),该网站包含了大量的电影、电视节目、纪录片等影视作品信息,以及用户对这些作品的评论和评分。
数据集包括50,000条英文电影评论,这些评论被标记为正面或负面情感,用以进行二分类任务。其中,25,000条评论被分配为训练集,另外25,000条则作为测试集。训练集和测试集都保持了平衡的正负样本比例,即各含50%的正面评论和50%的负面评论.

在这里插入图片描述
我们同样直接下载HuggingFace上的imdb数据集,执行下面的代码,会自动下载数据集并加载:

from datasets import load_dataset

# 加载IMDB数据集
dataset = load_dataset('imdb')

如果国内下载比较慢的话,可以在这个百度云(提取码: u9gi)下载后,把imdb文件夹放到根目录,然后改写上面的代码为:

dataset = load_dataset('./imdb')

4.集成SwanLab

因为swanlab已经和transformers框架做了集成,所以将SwanLabCallback类传入到trainercallbacks参数中即可实现实验跟踪和可视化:

from swanlab.integration.huggingface import SwanLabCallback

# 设置swanlab回调函数
swanlab_callback = SwanLabCallback()

...

# 定义Transformers Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets['train'],
    eval_dataset=tokenized_datasets['test'],
    # 传入swanlab回调函数
    callbacks=[swanlab_callback],
)

想了解更多关于SwanLab的知识,请看SwanLab官方文档

5.开始训练!

训练过程看这里:BERT-SwanLab

在首次使用SwanLab时,需要去官网注册一下账号,然后在用户设置复制一下你的API Key。

在这里插入图片描述
然后在终端输入swanlab login:

swanlab login

把API Key粘贴进去即可完成登录,之后就不需要再次登录了。

完整的训练代码:

"""
用预训练的Bert模型微调IMDB数据集,并使用SwanLabCallback回调函数将结果上传到SwanLab。
IMDB数据集的1是positive,0是negative。
"""

import torch
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from swanlab.integration.huggingface import SwanLabCallback
import swanlab

def predict(text, model, tokenizer, CLASS_NAME):
    inputs = tokenizer(text, return_tensors="pt")

    with torch.no_grad():
        outputs = model(**inputs)
        logits = outputs.logits
        predicted_class = torch.argmax(logits).item()

    print(f"Input Text: {text}")
    print(f"Predicted class: {int(predicted_class)} {CLASS_NAME[int(predicted_class)]}")
    return int(predicted_class)

# 加载IMDB数据集
dataset = load_dataset('imdb')

# 加载预训练的BERT tokenizer
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')

# 定义tokenize函数
def tokenize(batch):
    return tokenizer(batch['text'], padding=True, truncation=True)

# 对数据集进行tokenization
tokenized_datasets = dataset.map(tokenize, batched=True)

# 设置模型输入格式
tokenized_datasets = tokenized_datasets.rename_column("label", "labels")
tokenized_datasets.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])

# 加载预训练的BERT模型
model = AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)

# 设置训练参数
training_args = TrainingArguments(
    output_dir='./results',
    eval_strategy='epoch',
    save_strategy='epoch',
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    logging_first_step=100,
    # 总的训练轮数
    num_train_epochs=3,
    weight_decay=0.01,
    report_to="none",
    # 单卡训练
)

CLASS_NAME = {0: "negative", 1: "positive"}

# 设置swanlab回调函数
swanlab_callback = SwanLabCallback(project='BERT',
                                   experiment_name='BERT-IMDB',
                                   config={'dataset': 'IMDB', "CLASS_NAME": CLASS_NAME})

# 定义Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets['train'],
    eval_dataset=tokenized_datasets['test'],
    callbacks=[swanlab_callback],
)

# 训练模型
trainer.train()

# 保存模型
model.save_pretrained('./sentiment_model')
tokenizer.save_pretrained('./sentiment_model')

# 测试模型
test_reviews = [
    "I absolutely loved this movie! The storyline was captivating and the acting was top-notch. A must-watch for everyone.",
    "This movie was a complete waste of time. The plot was predictable and the characters were poorly developed.",
    "An excellent film with a heartwarming story. The performances were outstanding, especially the lead actor.",
    "I found the movie to be quite boring. It dragged on and didn't really go anywhere. Not recommended.",
    "A masterpiece! The director did an amazing job bringing this story to life. The visuals were stunning.",
    "Terrible movie. The script was awful and the acting was even worse. I can't believe I sat through the whole thing.",
    "A delightful film with a perfect mix of humor and drama. The cast was great and the dialogue was witty.",
    "I was very disappointed with this movie. It had so much potential, but it just fell flat. The ending was particularly bad.",
    "One of the best movies I've seen this year. The story was original and the performances were incredibly moving.",
    "I didn't enjoy this movie at all. It was confusing and the pacing was off. Definitely not worth watching."
]

model.to('cpu')
text_list = []
for review in test_reviews:
    label = predict(review, model, tokenizer, CLASS_NAME)
    text_list.append(swanlab.Text(review, caption=f"{label}-{CLASS_NAME[label]}"))

if text_list:
    swanlab.log({"predict": text_list})

swanlab.finish()

训练可视化过程:
在这里插入图片描述

训练大概需要6G左右的显存,我在一块3090上跑了,1个epoch大概要12~13分钟时间。

训练的推理结果:

在这里插入图片描述
这里我生成了10个比较简单的测试文本,微调后的BERT模型基本都能答对。

至此,我们顺利完成了用BERT预训练模型微调IMDB数据的训练过程~

相关链接

  • 49
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: BERT-CRF是一种基于深度学习的序列标注模型,可以实现对自然语言文本进行序列标注。在实现BERT-CRF模型时,需要准备一个数据集,用于训练和评估模型的性能。 数据集BERT-CRF模型中非常重要的一部分,它决定了模型的性能和泛化能力。数据集应当包含一组有标注的样本,每个样本都应该是一个输入序列和其对应的标注序列。 对于自然语言处理任务,常用的数据集包括CoNLL-2003、OntoNotes、ACE2005等。这些数据集包含了大量的有标注文本数据,并被广泛应用于序列标注任务中。在准备数据集时,需要根据具体的任务和数据集格式对数据集进行处理。 对于CoNLL-2003数据集,其格式为每个词占据一行,每行包含9个字段,分别为:单词、词性、分块标签和4个NER标记。在处理数据集时,需要将每个样本中的文本与其对应的NER标签分离,并进行适当的编码和分割。 在BERT-CRF实现过程中,还需要考虑如何将输入向量化,并将其转换为能够被BERT模型接受的格式。一种常用的方法是使用bert-serving来将原始文本转换为BERT向量,然后将向量输入到CRF模型中进行标注。 总之,BERT-CRF实现需要准备一个有效的训练数据集数据集应当包含有标注的样本,并符合模型的输入格式。同时,还需要针对具体的任务和数据集格式对数据集进行适当的预处理和编码。 ### 回答2: BERT-CRF是一种基于BERT模型和条件随机场(CRF)的序列标注模型。在实现bert-crf之前,我们需要一个数据集来进行训练和测试。数据集就是文本序列上每个词的标注结果,例如分句、分词、命名实体标注、词性标注等。下面我们来介绍一下如何准备一个数据集。 首先,选择一个合适的任务,例如中文命名实体识别(NER)。NER任务是指识别文本数据中具有特定意义的实体,如人名、组织机构名、地名等。选择该任务的原因是其具有广泛的应用场景,适合用来演示bert-crf模型的实现流程。 接下来是数据收集和预处理。我们需要收集一些包括实体标注信息的文本语料库,并进行预处理,例如分词、去除停用词、标注实体、划分训练集和测试集等。在这一步可以使用一些工具来简化操作,例如jieba分词、StanfordNLP、pyltp等。最终得到的文本序列和标注序列是该数据集的核心部分。 然后是特征工程,即将文本序列和标注序列转化为模型可接受的特征格式。具体来说,需要将文本序列中每个词转化为对应的BERT向量表达形式,同时将标注序列转化为one-hot编码形式。这些特征都可以通过使用相应的Python工具来进行处理。 最后是模型训练和测试。BERT-CRF模型的训练可以使用已经训练好的BERT权重作为初始值,并在预训练期的基础上进行finetuning。模型测试时可以使用在预处理阶段划分的测试集进行验证,最终将预测的标注序列与真实标注序列进行比较,并计算评价指标,如精度、召回率、F1值等。 总之,准备一个数据集BERT-CRF模型实现的重要一步。数据集的质量将直接影响模型的表现效果和应用效果。因此,数据集的准确性和完备性都需要得到重视。 ### 回答3: BERT-CRF是一种自然语言处理技术,其基本思想是结合 BERT(Bidirectional Encoder Representations from Transformers)预训练模型和条件随机场(CRF)来完成对于自然语言序列标注的任务。 在这种技术中,BERT被用来对输入文本进行特征提取,并且将提取的特征序列作为CRF模型的输入,CRF负责对序列进行标注。 对于BERT-CRF,数据集的构建非常重要。数据集必须包含大量的标记数据,即标有正确标注的文本的数据,以确保CRF模型的准确性和效果。构建数据集的主要步骤如下: 1. 定义标记标准 在构建数据集之前,需要定义标记标准。在自然语言处理任务中,标记通常包含实体标记、词义标记、词性标记等。标志标准将大大影响数据集的构建和模型的学习效果,因此必须尽可能严格定义。 2. 选择文本样本 选择文本样本时,需要选择具有代表性的样本来训练模型,应尽可能覆盖各种文本类型和语言风格。这些文本样本应来自于各种来源,例如新闻报道、论坛、社交媒体等。 3. 标记数据 将选定的文本样本转换为适合模型学习的标记数据。还可以利用现成的标记工具进行标记化,例如Stanford NER、spaCy等。 4. 数据预处理 对标注好的数据进行清洗、切分、建立词典等预处理操作,使其适合于BERT-CRF模型进行学习和训练。这些任务可以使用Python等语言的自然语言处理库来完成。 5. 划分数据集数据集划分为训练集、开发集和测试集,通过不断调整模型参数和超参数,并在开发集上测试结果来优化模型,最终在测试集上进行评估。 总而言之,BERT-CRF技术在自然语言处理领域的应用,需要基于一组标记良好且具有代表性的数据集。通过上述步骤,我们可以建立一个完善的数据集来支持BERT-CRF模型的学习和训练。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值