web设计在这:bilibili用户评论情感分析的web网页展示
训练前的准备工作:
可以在这里下载bert-base-chinese模型
可以在这里下载训练数据集(weibo_senti_100k)
https://github.com/SophonPlus/ChineseNlpCorpus/blob/master/datasets/weibo_senti_100k/intro.ipynb
路径参考:
data和data训练是我放数据集的,可忽略
models 和 saved_model 是我们要建的文件夹,里面内容运行代码后会生成
本代码生成的是saved_model.pth 忽略saved_model_7.pth这是我另一个情感分析的模型
完整代码:
如果之前运行总是出错 建议文件路径 和 代码中初始化模型和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哈哈哈哈哈没有参考价值)多次训练
爆红忽略 我不记得啥原因了 嘿嘿嘿