【情感预测】利用bert-base-chinese实现情感预测(weibo_senti_100k 正负情感)

web设计在这:bilibili用户评论情感分析的web网页展示

训练前的准备工作:

可以在这里下载bert-base-chinese模型

google-bert/bert-base-chinese at main

可以在这里下载训练数据集(weibo_senti_100k)

https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_senti_100k/intro.ipynb

路径参考:

data和data训练是我放数据集的,可忽略

modelssaved_model 是我们要建的文件夹,里面内容运行代码后会生成

本代码生成的是saved_model.pth 忽略saved_model_7.pth这是我另一个情感分析的模型

db28acd03b3a4d8c929382cd184338b2.png

完整代码:

如果之前运行总是出错 建议文件路径 和 代码中初始化模型和tokenizer这一部分一点都不要改动再试试 我之前总是报"找不到"还是什么错误(忘性太大 还没记录下来)最终这样尝试后才成功

import os
import pandas as pd
import torch
from torch.nn import CrossEntropyLoss
from torch.utils.data import Dataset, DataLoader
from transformers import BertTokenizer, BertForSequenceClassification, get_linear_schedule_with_warmup

max_length = 100
# 从CSV文件中加载数据
data_path = "data训练/正负训练/weibo_senti_100k.csv"
df = pd.read_csv(data_path)

# 随机选择x个样本(为了快速出现训练结果 本代码中只取了n=5个样本)
df = df.sample(n=5, random_state=42)

# 将texts和labels分别从DataFrame中提取出来
texts = df['review'].tolist()
labels = df['label'].tolist()


# 修改数据集类的初始化函数
class SentimentDataset(Dataset):
    def __init__(self, texts, labels, tokenizer, max_length):
        self.texts = texts
        self.labels = labels
        self.tokenizer = tokenizer
        self.max_length = max_length

    def __len__(self):
        return len(self.texts)

    def __getitem__(self, idx):
        text = self.texts[idx]
        label = self.labels[idx]

        encoding = self.tokenizer.encode_plus(
            text,
            add_special_tokens=True,
            max_length=self.max_length,
            return_token_type_ids=False,
            padding='max_length',
            truncation=True,
            return_attention_mask=True,
            return_tensors='pt'
        )

        return {
            'text': text,
            'input_ids': encoding['input_ids'].flatten(),
            'attention_mask': encoding['attention_mask'].flatten(),
            'labels': torch.tensor(label, dtype=torch.long)
        }


# 初始化模型和tokenizer
model_name = "bert-base-chinese"
model = BertForSequenceClassification.from_pretrained(model_name)

model_folder = 'models/'
state_dict_path = os.path.join(model_folder, 'saved_model.pth')
if os.path.isfile(state_dict_path):
    model.load_state_dict(torch.load(state_dict_path))

tokenizer = BertTokenizer.from_pretrained(model_name)

# 数据预处理
dataset = SentimentDataset(texts, labels, tokenizer, max_length)
dataloader = DataLoader(dataset, batch_size=2)

# 损失函数和优化器(博主用cpu训练的)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
loss_fn = CrossEntropyLoss()
optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0,
                                            num_training_steps=len(dataloader) * 2)  # 2 epochs

# 训练模型
EPOCHS = 2
for epoch in range(EPOCHS):
    for batch in dataloader:
        input_ids = batch['input_ids'].to(device)
        attention_mask = batch['attention_mask'].to(device)
        labels = batch['labels'].to(device)

        # 前向传播
        outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
        loss = outputs.loss

        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        scheduler.step()

    torch.save(model.state_dict(), state_dict_path)
    print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

# 预测
test_sentence = '没做事的动力真的太难受了,尤其是我有明确想做的事的时候,就是提不起精神来去做,太痛苦了'
test_encoding = tokenizer.encode_plus(test_sentence, add_special_tokens=True, max_length=max_length,
                                      return_tensors='pt')
test_input_ids = test_encoding['input_ids'].to(device)
test_attention_mask = test_encoding['attention_mask'].to(device)

with torch.no_grad():
    test_output = model(test_input_ids, attention_mask=test_attention_mask)
    prediction = torch.argmax(test_output.logits, dim=1).item()
    # print(f'预测 "{test_sentence}" 结果: {prediction}')
    # 如果预测结果为0,则转换为-1
    # (用于训练的csv文件中0表示负样本,1表示正样本,但老师建议-1表示负样本,所以这里做了转换)
    prediction = -1 if prediction == 0 else prediction
    print(f'预测 "{test_sentence}" 结果: {prediction}')
model.save_pretrained('saved_model')
print("ok")

AI对该代码的解释:

这段代码是使用transformers库中的BERT模型进行情感分析的完整示例。下面是对代码的详细解释:
1. 导入必要的库

  • os: 文件系统操作。
  • pandas as pd: 数据处理。
  • torch: PyTorch深度学习框架。
  • CrossEntropyLoss: 分类问题的损失函数。
  • Dataset, DataLoader: PyTorch的数据处理工具。
  • BertTokenizer, BertForSequenceClassification, get_linear_schedule_with_warmup: transformers库提供的BERT相关组件。

2. 数据加载与预处理

  • 加载CSV文件中的数据,随机选取5个样本进行训练。
  • 从DataFrame中提取文本和标签列表。

3. 自定义数据集类

  • 定义SentimentDataset类继承自Dataset,用于封装文本和标签,并在__getitem__方法中对文本进行编码。
  • 使用tokenizer.encode_plus方法对文本进行编码,添加特殊标记,填充或截断到max_length长度,并返回input_ids和attention_mask。

4. 模型初始化

  • 加载预训练的BERT模型BertForSequenceClassification。
  • 检查是否存在保存的模型状态字典并加载。
  • 初始化BertTokenizer。

5. 数据加载器

  • 创建DataLoader以批量加载数据。

6. 设置设备和训练参数

  • 根据GPU可用性选择设备。
  • 设置损失函数CrossEntropyLoss,优化器AdamW,以及学习率调度器get_linear_schedule_with_warmup。

7. 模型训练

  • 进行两个epoch的训练循环。
  • 对每个批次的数据进行前向传播,计算损失,反向传播,更新权重,调整学习率。
  • 每个epoch结束时保存模型状态字典。

8. 预测

  • 对单个句子进行编码和预测。
  • 调整预测结果以匹配训练数据中正负样本的标签编码。

9. 保存模型

  • 最后,保存整个模型到指定目录。

这段代码展示了如何使用BERT进行情感分类的基本流程,包括数据预处理、模型加载、训练和预测。注意,这里的训练仅使用了5个样本,这通常不足以得到好的模型性能,实际应用中应使用更多数据。

运行结果:

这是我多次训练后的结果

代码中 每次训练都会把模型保存下来 所以如果和我一样只能用cpu训练的话 可以把n值调小一点(本文为5哈哈哈哈哈没有参考价值)多次训练

爆红忽略 我不记得啥原因了 嘿嘿嘿

64a2f3ed87e549ab9b51d8d4c0abbbe5.png

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青鱼鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值