1. 引言

在自然语言处理(NLP)任务中,情感分析是最经典的应用之一。近年来,预训练语言模型(如BERT)的出现大幅提升了文本分类的效果。然而,很多开发者对“如何微调BERT”仍然感到无从下手——数据怎么处理?训练代码怎么写?训练好的模型怎么用?

我前段时间想弄一个对微博评论进行情感分析的系统,查了很多资料,也看了很多博客,结果找到的文章,大部分都是解释,什么是bert,它的机制是什么,它可以用来做什么,但是,我就是找不到,应该怎么使用它。

如果你是一个大学生,或者对这方面了解不多的开发者,你会发现,你花了很长的时间来学习和了解它,最后好像知道它是什么了,可以用来干什么了,却还是一头雾水,不知道该从哪里开始。

在我看来,这是一种本末倒置的现象,bert本质上其实只是一个工具,我们最应该学习的,就是应该怎么使用它,就像你使用ai,你不需要知道它是怎么训练的,也不需要知道它的底层逻辑和机制是什么,你只需要知道,我怎么向他发提示词,让他能够完成我想完成的工作,就够了。

基于这种想法,我写下了这篇文章,本文不会告诉你bert是什么,机制是什么,谁发明的,我会从以下几点告诉你,你该怎么使用他,并且完全可以复现。

本文将带你从零开始,使用 Hugging Face 的 transformers 库和 bert-base-chinese 预训练模型,完成一个微博评论情感二分类任务。你将获得:

  • 一份可直接运行的训练脚本(含SwanLab可视化)

  • 一份批量预测 CSV 的推理脚本

  • 数据清洗、模型保存与加载的最佳实践

最终效果:输入一段中文评论,模型能判断它是积极(positive)还是消极(negative)


2. 环境准备与依赖安装

我使用的是python版本是3.12,PyCharm版本是2024的版本,别的版本应该也可以,别太老导致运行库不兼容即可。

如果你没有python环境或pycharm,可以到官网进行下载,也可以下载我的安装包进行安装,下面的是安装包链接:

通过网盘分享的文件:pycharm-professional-2024.1.exe等2个文件
链接: https://pan.baidu.com/s/1CTD_ozq9cibUkiN7Wmeekw 提取码: myj8 

下载后双击安装即可

安装后,安装必要的运行库,主要是下面的库,语法如下:

pip install torch transformers datasets pandas scikit-learn swanlab

  • torch:深度学习框架,GPU加速推理

  • transformers:Hugging Face 模型库,提供BERT及分词器

  • datasets:高效处理数据集

  • pandas:读写 CSV、数据清洗

  • swanlab:国内可用的实验跟踪可视化工具(可选,若不使用可移除相关代码)


3. 数据集准备

安装完环境后,你需要找到一个数据集进行训练,在这里进行一个简单的解释,我使用的模型名称是bert-base-chinese,它是一个预训练的模型,什么意思呢,你可以把它看成是一个中文词典,有了它,电脑就可以认出我们的中文,也就是说它现在只能认识中文,并不能进行情感分析,所以我们此时要告诉他,什么话是积极的,什么话是消极的,这就是对模型进行训练,也可以称为微调,而要训练它,我们会需要一个数据集,数据集的格式如下图:

它分为了两列,左边的一列是label,里面是数字0和1,分别代表消极和积极,右边则是文本,这个数据集内的文本都是微博中的评论,1和0是人工提前进行标注的,通过把这样的数据集喂给模型,让他知道,什么样的评论应该标上1,什么样的评论应该标上0,就实现了对文本进行情感分析。

我使用的数据是一个拥有10万条微博评论的数据集,这是我在网上找到的,并非我自行标注,但是准确率也挺高了,以下是数据集的链接可以直接进行下载:


链接: https://pan.baidu.com/s/1xkCTCi0-Aj_pl-4ab3GIdA 提取码: i5zm 
 

使用10万条微博情感数据,包含两列:

  • review:评论文本

  • label:0(消极)或 1(积极)

你需要确保数据格式与本例一致,路径默认为脚本同级目录。若无此数据集,也可以用其他带情感标签的中文文本 CSV 替代,只需确保列名为 review 和 label


4. 模型训练脚本详解

数据集和模型可以说是一一对应的,之前有说,我们使用的模型是bert-base-chinese,数据集也是中文的,如果你下载了别的版本,就可能会报错,因为可能别的模型不认识中文,而是一本“英文词典”,你告诉它“好!”这样的句子应该打上标签1,但是它只认识“good”,所以,选择正确的模型和数据集,可以让你事半功倍。

下面是我使用的模型的下载链接:
链接: https://pan.baidu.com/s/1HNWd4dK5eb1cp57dBTWCtg 提取码: 491y 
 

准备好了数据集和模型,就要使用脚本开始训练模型。

训练模型的脚本文件是“训练.py”,你不需要知道它的原理,知道它是用来干嘛的,以及怎么使用即可,我会发出完整的脚本代码,你只需要修改如模型存放位置,训练步数等参数即可。

链接如下:
链接: https://pan.baidu.com/s/1zkUrQDkhQFO1HSJdJQYPog 提取码: shnk 

训练.py 负责加载数据、微调BERT、保存最佳模型。核心步骤如下。

4.1 导入库与预测函数

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

def predict(text, model, tokenizer, CLASS_NAME):
    inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
    device = next(model.parameters()).device
    inputs = {k: v.to(device) for k, v in inputs.items()}
    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)

这段函数用于快速验证模型效果,它会自动跟随模型所在的设备(CPU/GPU),无需手动指定,需要注意的是,训练模型最好使用GPU,如果没有GPU的话,训练速度会很慢,我训练的时候出现了有GPU但是模型仍然在CPU上跑的情况,出现这种情况的原因是:默认安装的 torch 只是 CPU 版,或者 CUDA 版本与你的显卡驱动不匹配。

出现这种情况,我们需要卸载掉默认安装的torch库,代码如下

pip uninstall torch torchvision torchaudio

然后再用下面的代码,安装适配的torch版本:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

如果你发现模型训练的速度特别慢,很大概率是这个原因。

4.2 主函数:数据加载与预处理

df = pd.read_csv('weibo_senti_100k_cleaned.csv')
df = df.dropna()
dataset = Dataset.from_pandas(df)
dataset = dataset.train_test_split(test_size=0.1)   # 9:1 划分训练集和验证集

tokenizer = AutoTokenizer.from_pretrained('bert-base-chinese')
def tokenize(batch):
    return tokenizer(batch['review'], padding='max_length', truncation=True, max_length=128)

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'])

这里的代码,首先通过pd.read_csv读取了数据集,如果你细心的话,可以看到,我发出来的数据集是“weibo_senti_100k.csv”,但是我读取的数据集是“weibo_senti_100k_cleaned.csv”,这里就要提到数据集的清洗工作,有的数据集是不能直接使用的,比如前一个数据集,它的文本中还有一些url链接,表情符号,@某人等信息,这些无意义的内容统称为“噪声”,在使用之前,我们要将其进行清理,而且这个数据集还有一个很大的问题,就是它的前5万条数据,标签都是1,后5万条数据,标签都是0,这会让模型在学习的时候,前期一直都标1,正确率就很高,后期一直标0,正确率也很高,这两点都会导致训练出来的模型分析效果变差,所以还需要对数据集进行清洗,清洗的工作就是,第一,清除噪声,第二,将他们的次序打乱,随机排序,可以把这个要求发给ai,让它生成一段清洗数据的代码,随后在python中清洗数据。

我进行清洗的代码被覆盖了,在这里附上清洗后的数据集的链接:

通过网盘分享的文件:weibo_senti_100k_cleaned.csv
链接: https://pan.baidu.com/s/1W7HiqwJL-uBs9tLkHALMRg 提取码: a36f 
 

读取了数据集后,下方有一个注释是“9:1划分训练集和验证集”,这里要提到训练模型的逻辑,是需要给他一个训练集和一个验证集,他可以看到训练集的标签,看不到验证集的标签,他会通过学习训练集的标签,然后去给验证集打上标签,再验证是否正确,通过这样的过程,学会进行情感分析,而我们只给了一个数据集,所以就通过这样的方式,将数据集中的90%作为训练集,剩下10%作为验证集。

随后,再通过tokenizer = AutoTokenizer.from_pretrained('bert-base-chinese')导入你的模型,后方的双引号中,是模型的地址,自行修改为自己存放的位置。

4.3 模型定义与训练参数

model = AutoModelForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=2)
CLASS_NAME = {0: "negative", 1: "positive"}

training_args = TrainingArguments(
    output_dir='./results',
    eval_strategy='epoch',
    save_strategy='epoch',
    logging_steps=100,
    learning_rate=2e-5,
    per_device_train_batch_size=32,
    per_device_eval_batch_size=32,
    num_train_epochs=5,
    weight_decay=0.01,
    report_to="none",
    dataloader_num_workers=0,
    dataloader_pin_memory=True,
    load_best_model_at_end=True,
    metric_for_best_model='eval_loss',
    greater_is_better=False,
)

导入数据集和模型后,设置相关参数,随后就可以进行训练了,有兴趣的可以复制上面的参数发给ai,询问每个参数的意义是什么,就我个人而言,只需要知道,读取模型进行了二分类训练“0和1”,然后epoch=5,代表的是将同一个数据集喂给模型5次,可以让模型的学习效果更好,当然不是越多越好,学习次数过多也会出现过拟合的情况,一般3-5次就好。

关键配置解释:

  • eval_strategy='epoch':每个epoch结束时在验证集上评估。

  • load_best_model_at_end=True:训练结束后自动加载验证损失最低的模型,避免过拟合。

  • metric_for_best_model='eval_loss' 且 greater_is_better=False:以更小的验证损失为最佳模型指标。

  • batch_size 设为32,普通GPU(如RTX 3060 12G)可流畅运行。

在我的代码中,每一个epoch都会对模型进行一次保存,记录下当前的loss率,最终会保存效果最好的版本,保存到“sentiment_model_fixed_best”文件夹内。

4.4 集成SwanLab与启动训练

swanlab_callback = SwanLabCallback(
    project='BERT-Chinese-Weibo',
    experiment_name='Weibo-Sentiment-v1',
    config={'dataset': 'Weibo-100k', "CLASS_NAME": CLASS_NAME}
)

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

trainer.train()

SwanLab 是一个开源的机器学习实验跟踪和可视化工具,类似于 TensorBoard 或 Weights & Biases。它可以帮助你记录训练过程中的超参数、指标(如 loss, accuracy)以及硬件状态,并生成可视化的仪表盘。

简单的来说,可以截图看效果,用于自己把握训练效果和展示给其他人看,都很不错。

效果如下图所示:

使用的方法:

第一步:SwanLab - AGI时代先进模型训练研发工具进入这个网址,注册账号

第二步:在设置中找到如图所示的api进行复制

第三步:在bash中输入如下代码

swanlab login

随后粘贴上刚才复制的api,提示登录成功即可。

4.5 保存模型与快速测试

python

trainer.save_model('./sentiment_model_fixed_best')
tokenizer.save_pretrained('./sentiment_model_fixed_best')

test_reviews = [
    "这部电影太好看了,剧情非常精彩,强烈推荐!",
    "简直是浪费时间,剧情老套,演员演技也很尴尬。",
    # ... 更多测试评论
]
for review in test_reviews:
    predict(review, model, tokenizer, CLASS_NAME)
swanlab.finish()

保存模型后,直接用训练脚本末尾的测试语句验证效果。输出如下:

Input Text: 这部电影太好看了,剧情非常精彩,强烈推荐!
Predicted class: 1 positive
Input Text: 简直是浪费时间,剧情老套,演员演技也很尴尬。
Predicted class: 0 negative

5. 模型推理(批量预测CSV)

训练完成后,我们有了一个 sentiment_model_fixed_best 文件夹,里面包含 config.jsonpytorch_model.bin、分词器等文件。下面的 测试.py 脚本可以批量读取CSV文件中的评论,输出情感标签和置信度

完整代码:

通过网盘分享的文件:训练.py
链接: https://pan.baidu.com/s/1UpqcZW-oeZFpBX9M-QQfSA 提取码: ra2f 

5.1 数据清洗

首先,要对微博评论进行情感分析的话,就要先爬取微博的评论,相关内容请看这篇文章

Python爬虫实战:基于Selenium替代方案的微博热搜与评论全量采集-CSDN博客

从微博爬取的原始评论可能包含大量噪声,我们设计 clean_weibo_text 函数:

  • 移除URL、话题标签#...#、@用户

  • 仅保留中英文、数字和常用标点

  • 合并多余空格

同时,对整表进行过滤:

  • 删除内容为“未获取到评论数据”的无效行

  • 删除清洗后为空的评论

5.2 加载模型与推理函数

model_path = "./情感分析模型/sentiment_model_fixed_best"  # 修改为你的路径
tokenizer = AutoTokenizer.from_pretrained(model_path)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = AutoModelForSequenceClassification.from_pretrained(model_path).to(device)
CLASS_MAPPING = {0: "LABEL_0", 1: "LABEL_1"}   # 对应消极和积极

def predict_sentiment(text):
    if not text.strip():
        return "LABEL_1", 0.0
    inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512).to(device)
    with torch.no_grad():
        outputs = model(**inputs)
        predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
    predicted_class_id = torch.argmax(predictions, dim=-1).item()
    score = predictions[0][predicted_class_id].item()
    label = CLASS_MAPPING.get(predicted_class_id, "LABEL_1")
    return label, score

这里标签名称保留为 LABEL_0 / LABEL_1,你可以在实际使用时修改为“消极/积极”。

5.3 批量处理文件夹内所有CSV

def batch_analyze_csv(folder_path):
    for filename in os.listdir(folder_path):
        if filename.endswith('.csv'):
            df = pd.read_csv(file_path)
            df = clean_dataframe(df)   # 返回带“纯净评论”列的数据
            # 判断是否已有情感标签列,支持增量分析
            if '情感标签' in df.columns:
                mask = df['情感标签'].isna() | df['置信度'].isna()
                for idx in df[mask].index:
                    label, conf = predict_sentiment(df.loc[idx, '纯净评论'])
                    df.loc[idx, '情感标签'] = label
                    df.loc[idx, '置信度'] = conf
            else:
                results = df['纯净评论'].apply(lambda x: pd.Series(predict_sentiment(x), index=['情感标签', '置信度']))
                df['情感标签'] = results['情感标签']
                df['置信度'] = results['置信度']
            df.to_csv(file_path, index=False, encoding='utf-8-sig')

该段代码的亮点是增量分析:如果 CSV 中已有“情感标签”列,但部分行为空,脚本只会对空缺部分进行推理,避免重复计算浪费资源。

5.4 运行示例

将待分析的 CSV 放在 ./comments_csv 文件夹下,执行脚本:

最终CSV会多出三列:

  • 纯净评论:清洗后的文本

  • 情感标签:LABEL_0 或 LABEL_1

  • 置信度:模型预测的softmax概率

效果如图所示:


6. 结果验证与调优建议

训练5个epoch后,验证集准确率通常能达到94%以上,足以应对一般场景。

进一步优化方向

  • 数据增强:回译、同义词替换等方法增加样本多样性。

  • 超参数调整:尝试不同的学习率(1e-5 ~ 5e-5)、批次大小。

  • 长文本处理:若评论较长,可将 max_length 增加到256或512,并调整batch size。

  • 早停机制:加入 EarlyStoppingCallback,当验证损失不再下降时提前停止训练。

如果想换用其他中文BERT变体(如 bert-wwm-extRoBERTa-wwm-ext),只需修改 AutoTokenizer 和 AutoModel 中的模型名称即可,代码全兼容。


7. 总结

本文提供了完整的代码框架,实现了:

  1. 用 bert-base-chinese 微调微博情感分类模型

  2. 集成 SwanLab 进行训练监控

  3. 训练后模型的保存与加载

  4. 批量处理 CSV 文件并输出带有情感标签和置信度的结果

整套流程清晰、可复用,你只需准备好带“评论内容”列的CSV,即可一键产出分析结果。希望这篇文章能帮助你快速上手BERT微调与实战部署,只要你愿意花时间跟着步骤去做,都可以运行成功。希望这个教学可以帮到一些正在学习的小白同学,至少可以让你学会“怎么用”,而不是像一只无头苍蝇到处找。

以上的所有内容都是我个人学习得到的成果,可能已经不那么新,有很多地方加入了我的个人理解,不够专业的地方还请多多包涵,如有不对的地方敬请指正,如果有更好的方案,欢迎探讨,谢谢每一个看到这里的人,如果你是小白,恭喜你学到了新的技能,加油。

完整代码:你可以分别下载文中的 训练.py 和 测试.py,按需修改路径后直接运行。如果遇到任何问题,欢迎在评论区交流。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐