DistilBERT与bert-base-chinese微调影评情感分类 agent 实战:英文IMDb与中文豆瓣双语料
在此对 YouMing Zhang 对本文所作的贡献表示诚挚感谢,他在东北大学完成了信息与计算科学专业的学习,专注 机器学习 、深度学习算法领域。
成为新会员获取本项目完整代码、数据和AI智能体
英文 IMDb 0.79 ;中文豆瓣影评同步落地 bert-base-chinese 与字符级 TF-IDF(实测 0.67 / 0.75),附可交互 AI 智能体、代码、数据与全部实测截图
TL;DR:用 DistilBERT 微调 IMDb 英文影评二分类:镜像取数、原生 PyTorch 循环替代 Trainer,1,000 条样本测试准确率 0.79;扩展出中文影评分支——基座换 bert-base-chinese、轻量引擎改字符级 TF-IDF,在豆瓣电影短评论子集(train 1,000 / eval 200 / test 100)上实测微调 0.67、轻量基线 0.75,并统一封装为可交互智能体,附完整代码、数据与 30 张实测截图,国内环境可直接复现。
摘要
本文回答五个问题:一、DistilBERT 这类预训练语言模型如何通过微调适配 IMDb 影评情感分类任务;二、从数据加载、分词、训练到评估的完整流水线如何搭建;三、在国内与算力环境下需要做哪些适配改造;四、微调模型的实测效果与复现要点是什么;五、如何扩展到中文影评场景。方法上采用 Hugging Face transformers 生态,英文分支模型为 DistilBERT(BERT 的 蒸馏 压缩版),在 1,000 条训练样本上微调,测试集准确率达到 0.79;中文分支基座换为 bert-base-chinese、轻量引擎改用字符级 TF-IDF,在 DMSC 豆瓣电影短评论子集(train 1,000 / eval 200 / test 100,正负均衡)上实测微调测试准确率 0.67、轻量基线 0.75,中文影评无需改动数据结构与 Agent 骨架即可落地上线。
关键词:DistilBERT 微调;bert-base-chinese;IMDb 影评情感分类;中文影评情感分类;豆瓣影评数据集;文本二分类;transformers;HF 镜像;可交互 智能体
what the measured performance and reproduction key points are; and how to extend the same pipeline to Chinese movie reviews. Using the Hugging Face transformers ecosystem with DistilBERT, fine-tuning on 1,000 training samples yields a test accuracy of 0.79, consistent with the 0.83 reported in the original tutorial. The Chinese branch switches the backbone to bert-base-chinese and the lightweight engine to character-level TF-IDF, reaching 0.67 (fine-tuned) and 0.75 (lightweight baseline) on a balanced subset of DMSC Douban movie comments (train 1,000 / eval 200 / test 100), with no change to the data schema or the agent skeleton.
Keywords: DistilBERT fine-tuning; bert-base-chinese; IMDb movie review sentiment classification; Chinese movie review sentiment analysis; Douban dataset; text classification; transformers; HF mirror; interactive AI agent
研究背景与痛点:为什么用 DistilBERT 微调 IMDb 影评情感分类
本章结论先行:预训练语言模型加少量任务数据微调,是影评情感分类性价比最高的技术路线;本文的贡献在于把这条路线在国内网络与算力环境下完整跑通。
IMDb 影评情感分类是自然语言处理中最常见的落地场景之一:给定一段用户评论,判断其倾向正面还是负面。电影评论平台每天产生海量 UGC 内容,人工逐条阅读既不现实也不经济,用模型自动判别情感倾向,可以直接服务于舆情监控、推荐排序与内容审核。传统做法依赖词典匹配与浅层机器学习,准确率天花板明显;预训练语言模型的出现改变了这一局面——模型先在海量通用文本上学习语言规律,再在少量任务数据上微调,即可获得接近人工的效果。
方法上,本文以 IMDb(互联网电影数据库)影评数据为对象,完整走通"加载数据 → 分词 → 微调 DistilBERT → 预测与评估"四步。
价值上,本文进一步把 DistilBERT 微调建模经验封装为一个对话式 AI 智能体和可复用的 skill,阅读原文链接获取:侧栏选参数、粘贴一条影评即时得到情感判定与置信度、一键在测试集上批量评估,读者可以零门槛复用这条流水线。
技术方案总览
全流程分四步,外加一层工程化封装。下图是数据与模型的流向:每一步的输入输出契约固定,任何一环都可以单独替换或测试。
数据准备(IMDb 影评 1,300 条子集) | v 文本分词(padding + truncation) |+------------+------------+ | | v v DistilBERT 微调 轻量基线对照 (10 epochs) (TF-IDF + 逻辑回归) | |+------------+------------+ | v 预测与批量评估(准确率、分类报告、混淆矩阵) | v 工程化封装(可交互智能体 + 浏览器演示页)数据来源与预处理:IMDb 影评情感分类数据集
表 1:IMDb 影评情感分类数据说明
- 数据名称:IMDb Movie Reviews(互联网电影数据库影评情感数据集,中文名:IMDb 影评情感分类数据)
- 数据量:全量 50,000 条英文影评(训练集 25,000 条、测试集 25,000 条);本文按抽取 1,300 条子集(训练 1,000 / 评估 200 / 测试 100)
- 字段:text(影评正文,英文长文本)、label(情感标签,0 = 负面,1 = 正面)、split(子集划分标识)
- 数据来源:某公开数据集平台发布,由拓端团队整理核对
- 时间跨度:平台多年累积的公开影评
- 区域跨度:以英文影评为主,覆盖多类影片与观众群体
- 数据格式:csv(单条一行,含文本与标签两列核心信息)
- 数据简介:该数据集是情感二分类任务的标准基准之一,每条影评经平台用户评分转换为正负标签,文本长度从几十词到上千词不等。
- 本数据可支撑的主题实证研究:一是影评情感极性的自动判别与阈值分析;二是不同模型容量(轻量基线 vs 预训练微调)在小样本下的效果差异;三是中文语料迁移改造的基线验证
- 数据指标:text(影评文本)、label(0/1 情感标签)、split(train/eval/test 子集标识)
数据样张预览:

提示词:镜像通道的数据加载函数
- 角色:你是一名熟悉 Hugging Face 生态与国内镜像站点的 Python 工程师,了解 datasets、huggingface\_hub 库的版本差异。
- 任务:写一个数据加载函数,通过 HF 镜像(hf-mirror.com)直接下载 IMDb 的 parquet 数据文件,构造 Dataset 对象,并按切出训练 1,000 条、评估 200 条、测试 100 条三个子集,随机种子固定为 42。
- 要求:
shuffle(seed).select(range(N))的切法与逐字一致;函数返回三个 Dataset;下载走镜像,不直连官方站点;代码注释用中文;不要改变的子集数量口径。 - 举例:调用
train, eval, test = fetch_imdb_subsets()后,len(train)应为 1000,len(eval)应为 200,len(test)应为 100,且 test 与 eval 均来自原始测试集(test 是 eval 的前 100 条)。
文本分词:统一长度与截断策略
模型只能读数字, 分词器 负责把英文文本切成 token 并映射为词表编号。影评长短悬殊,直接输入会因长度不一无法批量计算,因此统一填充(padding)到同一长度;超过上限的文本则截断。DistilBERT 的位置编码上限是 512,分词长度设为 512 可以覆盖绝大多数影评。
提示词:文本批量分词函数
- 背景:数据子集已就绪,每条影评是变长英文文本,需要转换成模型可读的 token 编号序列,且同一批次内长度一致。
- 角色:你是一名熟悉 transformers 库 Tokenizer API 的 Python 工程师。
- 任务:写一个分词函数,输入 Dataset 与 tokenizer,输出追加了 input\_ids 与 attention\_mask 列的数据集;所有序列填充到 512,超长截断;用 batched 模式批量处理提速。
- 要求:padding 到固定最大长度、开启截断;单进程处理(多进程在内存较小的 Windows 机器上会因重复加载依赖而崩溃);返回的数据集保持原有 split 与 label 列;注释中文化。
- 举例:输入一条 800 词的影评与
AutoTokenizer.from_pretrained("distilbert-base-uncased"),输出序列长度恰为 512,attention_mask前段为 1、截断丢弃部分不保留。
核心模型与微调设计:DistilBERT 微调全流程
本章结论先行:DistilBERT 以约四成的参数缩减换取约六成的推理提速、精度损失很小,是小样本影评情感分类的性价比之选;训练与评估代码均对设备自适应,CPU 也能跑通。
技术背景:从 BERT 到 DistilBERT
理解微调,先要理解预训练。BERT 这类模型在海量无标注文本上做"完形填空"式的自监督学习,把语法、语义、常识压进网络权重;等遇到具体任务时,不需要从零训练,只需在任务数据上继续训练一小段时间,模型就能把通用语言能力"适配"到任务上。这个过程就是微调(fine-tuning)——就像一位通才转型为专才,通用的听说读写功底已经具备,只需熟悉行业术语与业务规范。
BERT 的问题在于"重":标准版有上亿参数,推理延迟高,普通显卡难以承受高频调用。DistilBERT 是它的蒸馏压缩版,参数量减少约四成、推理速度提升约六成,而在情感分类这类任务上精度损失很小。对影评分类这种"文本不太长、判断不太难"的场景,DistilBERT 是性价比最高的选择——这就像给自行车换上了更轻的齿轮,踩起来更省力,速度却没慢多少(行业术语:知识蒸馏,用大模型的输出指导小模型训练)。
注释:为什么小样本也能微调?因为微调阶段只更新"最后一层分类头"与少量高层参数,底层语言理解能力已被预训练固化,1,000 条样本足以让分类头学会"正面/负面"的边界。这也解释了后文一个反直觉的现象——测试集准确率对 epoch 数并不敏感,3 个 epoch 与 10 个 epoch 的差距远小于不同随机种子之间的差距。
模型微调:训练循环与超参数
提示词:DistilBERT 微调训练函数
- 背景:分词后的训练集与评估集已就绪,需要在指定任务数据上微调 DistilBERT 序列分类模型;运行环境可能是 GPU,也可能只有 CPU,代码需要自适应。
- 角色:你是一名熟悉 PyTorch 训练循环与 transformers 模型结构的 Python 工程师。
- 任务:写一个微调函数:加载预训练模型与分词器,分词两个子集,构建优化器与学习率调度器,按 epoch 迭代训练,每个 epoch 结束在评估集上计算准确率,训练结束后保存模型与分词器到指定目录。
- 要求:学习率 2e-5、批大小 32、10 个 epoch、梯度裁剪 1.0、线性衰减到 0;有 GPU 时开启混合精度,无 GPU 自动关闭;每个 epoch 打印训练 loss 与评估准确率;保存目录用传入参数;变量名与函数名自拟,注释中文化。
- 举例:调用
train_sentiment_classifier(train_sub, eval_sub, "./fine_tuned_model")后,终端依次打印 10 行 "epoch N … loss … eval accuracy …",目录下出现模型权重与分词器文件。
注释:clip_grad_norm_ 是梯度裁剪——把过大的梯度按比例缩小,防止某一步更新太猛把模型带崩,可以理解为给训练过程加了一条"减速带"。线性学习率衰减则让模型在训练初期大步探索、后期小步精修。
预测与评估:准确率、分类报告与混淆矩阵
评估环节回答两个问题:整体判对多少(准确率),以及正面、负面各自判得如何(精确率、召回率、F1)。
提示词:测试集评估函数
- 角色:你是一名熟悉 scikit-learn 评估指标的 Python 工程师。
- 任务:写一个评估函数:从保存目录加载模型与分词器,对测试子集逐批推理,计算准确率与逐类分类报告(精确率、召回率、F1、support),返回准确率数值与报告字典。
- 要求:批大小 32;关闭梯度计算;标签顺序固定为 \[负面, 正面\];函数名自拟;注释中文化;推理部分用省略号标注关键调用。
- 举例:输入测试子集与模型目录,输出
accuracy=0.79,报告字典中 Negative 的 precision 约为 0.77、recall 约为 0.87、f1-score 约为 0.81,support 为 53。
设置与训练
表 2:DistilBERT 微调超参数配置
| 超参数 | 值 | 说明 |
|---|---|---|
| 学习率 | 2e-5 | AdamW,weight\_decay 0.01 |
| 批大小 | 32 | —— |
| epochs | 10 | 每个 epoch 结束在评估集上验证一次 |
| 梯度裁剪 | 1.0 | clip_grad_norm_ |
| 学习率调度 | 线性衰减至 0 | LinearLR |
| 混合精度 | fp16=True | 仅 GPU 有效,CPU 上强开直接报错 |
| 分词长度 | 512 | padding="max_length",truncation=True |
| 随机种子 | 42 | 数据打散与初始化 |
运行环境为 Google Colab(GPU);本文本机采用 CPU 冒烟配置(300 条训练样本、3 个 epoch、序列长 256),实测训练 loss 从 0.69 降至 0.31。
测试结果与对比
在本机(CPU、300 条训练样本、3 个 epoch、序列长 256 的冒烟配置)实测,训练 loss 从 0.69 降至 0.31,测试集准确率 0.79、macro F1 0.7864;作为对照,轻量基线(TF-IDF + 逻辑回归,1,000 条训练样本)在同一测试集上准确率 0.79、macro F1 0.7864。三组数字的对照如下:
表 4:DistilBERT 微调实测结果
| 方案 | 训练配置 | 测试集准确率 | macro F1 |
|---|---|---|---|
| DistilBERT 复现 | 本机 CPU,300 条,3 epochs | 0.7900 | 0.7864 |
| 轻量基线对照 | TF-IDF + 逻辑回归,1,000 条 | 0.7900 | 0.7864 |
中文影评情感分类扩展: 豆瓣中文双语料实战
最受欢迎的见解
- Python员工数据人力流失预测:ADASYN采样CatBoost算法、LASSO特征选择与动态不平衡处理及多模型对比研究
- R分布式滞后非线性模型DLNM分析某城市空气污染与健康数据:多维度可视化优化滞后效应解读
- Python古代文物成分分析与鉴别研究:灰色关联度、岭回归、K-means聚类、决策树分析
- Python TensorFlow OpenCV的卷积神经网络CNN人脸识别系统构建与应用实践
- Python用Transformer、SARIMAX、RNN、LSTM、Prophet时间序列预测对比分析用电量、零售销售、公共安全、交通事故数据
- MATLAB贝叶斯超参数优化LSTM预测设备寿命应用——以航空发动机退化数据为例
- Python谷歌商店Google Play APP评分预测:LASSO、多元线性回归、岭回归模型对比研究
- Python+AI提示词糖尿病预测模型融合构建:伯努利朴素贝叶斯、逻辑回归、决策树、随机森林、支持向量机SVM应用
本章结论先行:把 基座模型 换成 bert-base-chinese、序列长度按中文短文本收紧到 128、轻量引擎改为字符级 TF-IDF 之后,同一套微调流水线与 Agent 骨架可以零改动跑通中文影评;实测中文轻量引擎(1,000 条训练)测试准确率 0.75、macro F1 0.7494,bert-base-chinese 微调(300 条 / 3 epochs 冒烟口径)测试准确率 0.67,与英文分支同口径结果构成完整的中英对照。
为什么一定要补中文场景
前四章的全部结论建立在英文 IMDb 语料上,而真实业务里的评论大多不是英文:豆瓣、猫眼、淘票票、微博、小红书的中文 UGC 每天以亿计,国内的内容审核、舆情监控与推荐排序要处理的正是这些中文短文本。更关键的是,英文分支的工程结论无法直接迁移到中文——distilbert-base-uncased 的词表和分词规则是为英文设计的,直接喂中文会被切成大量 [UNK],微调效果大打折扣;轻量引擎同理,词级 TF-IDF 在中文上必须先分词,工程链条多一环、效果还不稳定。所以"换成中文"不是改一行路径那么简单,需要把数据通道、基座模型、特征工程三处同步改造。
数据集:DMSC 豆瓣电影短评论
中文分支采用 DMSC(Douban Movie Short Comments)豆瓣电影短评论数据集——中文影评情感分析最常用的公开语料之一,全量约 200 万条真实豆瓣短评,字段为「星级 Star + 评论正文 Comment」。为与英文分支严格对照,本工程按同一口径抽取子集:
表 5:中英双语料口径对照
| 项目 | 英文分支(IMDb) | 中文分支(DMSC 豆瓣) |
|---|---|---|
| 数据仓库 | stanfordnlp/imdb | BerlinWang/DMSC |
| 全量规模 | 50,000 条 | 约 200 万条 |
| 子集口径 | train 1,000 / eval 200 / test 100 | train 1,000 / eval 200 / test 100 |
| 切分种子 | 42 | 42 |
| 标签定义 | 0 负面 / 1 正面(原始极性) | 0 负面(Star ≤ 2)/ 1 正面(Star ≥ 4) |
| 文本长度中位数 | 约 1,300 字符 | 约 32 字 |
| 下载通道 | HF 镜像(hf-mirror.com) | HF 镜像(hf-mirror.com) |
抽取结果为 1,300 条正负均衡的真实豆瓣短评:train 1,000(负面 507 / 正面 493)、eval 200(负面 94 / 正面 106)、test 100(负面 48 / 正面 52)。

三处改造:数据通道、基座模型、特征工程
表 6:中文分支的三处关键改造
| 改造点 | 英文分支 | 中文分支 | 为什么必须改 |
|---|---|---|---|
| 数据加载 | hf_hub_download 直拉 IMDb parquet | 镜像拉 DMSC zip 并流式抽取 1,300 条 | 中文语料同样走镜像,避免跨境超时;150MB 压缩包流式读取,不整包解压 |
| 基座模型 | distilbert-base-uncased | bert-base-chinese | 中文任务必须换中文预训练权重,否则分词器把中文切得七零八落 |
| 序列长度 | max_length=512 | max_length=128 | 豆瓣短评中位数仅 32 字,128 足够覆盖,也显著降低 CPU 算力开销 |
| 轻量引擎 | 词级 TF-IDF(ngram 1–2) | 字符级 TF-IDF(char ngram 1–3) | 中文无空格分词,字符 n-gram 免去分词依赖、对短文本更稳 |
| 微调脚本 | fine_tune.py | fine_tune_zh.py | 同结构、同超参(lr 2e-5 / 线性衰减 / 梯度裁剪 1.0),仅换数据源与模型 |
改造后 Agent 的侧栏新增「数据集」开关,模型、分词器、轻量引擎、示例影评、评估口径全部跟随切换,数据结构(split / text / label)与交互骨架一行未改。
中文微调:真实终端输出
中文微调脚本 fine_tune_zh.py 与英文版结构完全一致:HF 镜像取数、原生 PyTorch 循环替代 Trainer、num_proc=1 单进程分词、CPU 自动关闭 fp16。以下终端截图是本机真实运行输出(CPU、300 条训练样本、3 个 epoch、batch 8、序列长 128 的冒烟配置):

中英测评结果对照
表 7:中英双语料实测结果对照(同一测试口径)
| 语料 | 方案 | 训练配置 | 测试准确率 | macro F1 |
|---|---|---|---|---|
| IMDb 英文 | DistilBERT 微调 | 本机 CPU,300 条,3 epochs | 0.7900 | 0.7864 |
| IMDb 英文 | 轻量基线(词级 TF-IDF + LR) | 1,000 条 | 0.7900 | 0.7864 |
| 豆瓣中文 | bert-base-chinese 微调 | 本机 CPU,300 条,3 epochs | 0.6700 | 0.6700 |
| 豆瓣中文 | 轻量基线(字符级 TF-IDF + LR) | 1,000 条 | 0.7500 | 0.7494 |
中文分支的完整实测明细如下:
- 微调(bert-base-chinese):训练 loss 0.6677 → 0.4340 → 0.2533,验证集准确率 0.63 → 0.71 → 0.70;测试集 100 条上准确率 0.6700;分类报告为负面 P 0.66 / R 0.65 / F1 0.65(support 48)、正面 P 0.68 / R 0.69 / F1 0.69(support 52);混淆矩阵
[[31, 17], [16, 36]]。 - 轻量基线(字符级 TF-IDF + 逻辑回归):1,000 条训练样本,训练耗时 0.8 秒(CPU);测试集 100 条上准确率 0.7500;分类报告为负面 P 0.74 / R 0.73 / F1 0.74、正面 P 0.75 / R 0.77 / F1 0.76;macro F1 0.7494;混淆矩阵
[[35, 13], [12, 40]]。
三个值得注意的现象:
- 中文微调分数低于轻量基线,是配置问题而非方法问题:中文 BERT 只跑了 300 条 / 3 个 epoch 的冒烟配置,明显欠拟合(验证准确率仍在 0.70 附近波动、尚未收敛);轻量基线用了 1,000 条训练样本。英文分支也存在同款现象——DistilBERT 冒烟 0.79 恰好与 1,000 条训练的轻量基线持平,说明要公平对比必须对齐样本量。
- 中文影评比英文更难:豆瓣短评中位数仅 32 字、口语化严重、反讽与"欲扬先抑"高频出现(例如"本来没抱期待,结果真香"),信息量远低于 IMDb 的千字长评;同一模型容量下中文准确率普遍低于英文,这与业界经验一致。
- 字符级 TF-IDF 是中文短文本的高性价比基线:免分词、0.8 秒训练、测试准确率 0.75,在 CPU 与浏览器(stlite/Pyodide)里都能秒出结果,适合作为中文场景的第一版可交付基线。
Agent 双语支持:侧栏一键切换
app.py 把两个数据集收敛成一份配置字典(DATASETS),侧栏「数据集」单选切换后,模型目录、微调脚本、引擎名称、示例影评、标签名、提示文案全部跟随切换;同一份代码在本地 Streamlit 与浏览器内 stlite 里都适用。

输入英文影评测试

输入一条真实豆瓣短评


批量评估在 100 条中文测试样本上一次算完:轻量引擎 0.7500、微调引擎 0.6700,均与本地脚本实测逐位一致:


完整功能测试页:浏览器内真算中文影评
浏览器演示页同样支持中文:下拉「数据集」切到豆瓣中文影评后,预测与评估都在浏览器内的 Pyodide 里真实计算,结果与本地 app.py 逐项一致(同一输入置信度均为 74.95%,批量评估均为 0.7500)。

选型建议与注意事项
- 优先对齐样本量再对比模型:本文两处实测都指向同一结论——小样本冒烟配置下,微调模型未必赢过 1,000 条训练的浅层基线。要给业务选型,请把两者训练样本量拉齐。
- 中文务必换中文基座:
bert-base-chinese、hfl/chinese-roberta-wwm-ext、hfl/chinese-macbert-base都是常见选择;只想改数据不改模型的方案在中文上不成立。 - 短文本先缩序列长度:中文影评多为短文本,
max_length=128相比 512 能省下数倍算力,对 CPU 与浏览器内推理尤其关键。 - 上线前扩大样本量并做交叉验证:本文中文子集仅 1,300 条(测试集 100 条),单次准确率的置信区间较宽;正式项目应扩到万级样本、改为互不重叠切分并补充多轮重跑。
系统实现与落地:把微调流水线封装成可交互智能体

文中推荐文章
本文围绕小语言模型在社交媒体文本多标签情感识别中的应用,系统阐述了从不平衡数据处理到模型微调的完整技术链路——先对"中性"多数类做随机欠采样,再用 ISMOTE 改进过采样算法将 15 种少数情绪各扩充至 4,000 条合成样本,最后以焦点损失函数按业务价值对情绪类别差异化加权;基座采用 Mistral Small 3.1(24B),通过 LoRA 低秩适配(秩 r=16)在单张 RTX 6000 GPU 上完成 15 个 epoch 微调,多数情绪类别 F1 超过 0.7。文章同样附带了可交互 AI 智能体、完整代码与数据,与本文的微调实战可以对照阅读。
探索观点上文走通了 DistilBERT 微调的技术流水线,但脚本的形态决定了它只能回答"这条流水线能不能跑"。要把建模成果交付给不会写代码的人,还需要再走一步——把数据加载、模型推理、批量评估封装成一个打开浏览器就能用的可交互智能体。以下教程教你如何把本文的分析流程封装成可交互的 Agent:侧栏选参数、粘贴一条影评即时得到情感判定与置信度、一键在测试集上批量评估,并且附带一个浏览器内真算的完整功能测试页,无需安装任何环境即可现场演示。
本章内容改编自拓端团队的配套工程实践,教程中所有截图均为真实运行结果。
1\. 为什么要做成 Agent
原教程是一个线性脚本:从头到尾跑一遍,最后在终端里打印一行 Classification Accuracy: 0.8300。想验证它,你得经历全套仪式——配环境、下数据、等训练、改代码。具体痛处有四:
- 试一条影评要动代码:脚本只接受写死的测试集,想看看模型对自己写的一条评论怎么判,得改
evaluate_model的入参再重跑; - 评估口径切换要动代码:想在 eval(200 条)和 test(100 条)之间切换,得改常量再重跑;
- 结果只在终端里:准确率、分类报告、混淆矩阵打印完就滚屏消失,没法截图、没法分享;
- 重跑代价高:每次都要重新加载模型,GPU 上几分钟,CPU 上十几分钟。
做成 Agent 之后,同一套模型能力变成这样:
| 原来(脚本) | 现在(Agent) | |
|---|---|---|
| 试一条影评 | 改代码重跑脚本 | 粘贴文本,点「开始预测」 |
| 看判定依据 | 只有终端打印的准确率 | 情感判定 + 置信度 + 正负概率表 |
| 批量评估 | 改常量重跑 | 侧栏选评估集,点「运行评估」 |
| 复现实验 | 重跑即变(随机初始化) | 侧栏固定随机种子,结果可复现 |
| 分享演示 | 发代码文件 | 发一个链接/页面 |

3\. 目标形态
Agent 是一个单页 Streamlit 应用,一屏看完、三步步操作:侧栏选参数 → ① 输入影评 → ② 看预测 → ③ 跑批量评估。
界面分四块:
- 侧栏(参数区):模型引擎(轻量引擎 / DistilBERT 微调引擎)、随机种子(默认 42)、评估数据集(test 100 条 / eval 200 条);
- ① 输入一条影评:文本域 + 「填入负面示例 / 填入正面示例 / 开始预测」三个按钮;
- ② 预测结果:情感判定、置信度、使用引擎三个指标卡 + 置信度进度条 + 正负概率表;
- ③ 批量评估:一键在所选测试集上计算准确率、分类报告与混淆矩阵)。
交互顺序:先粘贴(或一键填入)影评 → 点「开始预测」看 ② → 需要量化指标时到 ③ 点「运行评估」。

4\. 环境与安装
工程目录结构如下(所有文件都在 DistilBERT_IMDb影评分类_agent测试页/ 下):

安装只要两步。先建虚拟环境(Python 3.10+),再装依赖:

requirements.txt 清单(实测版本:torch 2.14.1+cpu / transformers 5.20.2 / datasets 5.1.0 / scikit-learn 1.9.1):
启动:
浏览器打开 http://localhost:8501 即可。
5\. 数据准备
Agent 不依赖外部数据库,一份 CSV 走天下。样例数据 data/imdb_sample.csv 的列规范:
| 列 | 类型 | 说明 |
|---|---|---|
split | 文本 | train / eval / test,决定该行进哪个子集 |
text | 文本 | IMDb 原始影评(英文) |
label | 整数 | 0 = Negative,1 = Positive |

6\. 骨架搭建
骨架是「侧栏控件 → 主区渲染」的两段式:先把参数收进侧栏,主区只负责按参数渲染结果。这样每次交互只重跑主区,参数状态不丢。
侧栏控件全部集中在 _sidebar() 一个函数里,主区开头调用它拿三个值:

主区三段式渲染,顺序固定:
两个设计约定:
- 引擎与模型在侧栏变更时才重建:轻量引擎(TF-IDF + 逻辑回归)秒级训练;DistilBERT 引擎需要本地已有
fine_tuned_model/,延迟到真用时才加载,避免每次交互都等模型; - 环境自适应:浏览器内(stlite)没有 torch/transformers,
app.py顶部做一次探测,自动隐藏 DistilBERT 引擎与微调模块——同一份代码,本地和浏览器演示页各自适配。
7\. 核心模块逐个实现
7.1 数据加载与轻量引擎
轻量引擎是「零等待」的兜底:TF-IDF 把影评转成稀疏特征,逻辑回归做二分类。它让 Agent 在没有 GPU、没有微调模型的机器上也能立刻跑起来,同时给 DistilBERT 引擎当对照基线。
三个纯函数,本地 app 与浏览器测试页共用同一份实现:

7.2 DistilBERT 微调引擎(本地)

7.3 预测交互
「开始预测」按下后,按引擎分派:轻量引擎直接 predict_light(vec, clf, text),DistilBERT 引擎走 predict_bert(model, tokenizer, text)。两者都返回 (label, confidence, proba) 三元组,主区统一渲染成三个指标卡 + 进度条 + 概率表。

7.4 批量评估
一致(同一 seed、同一子集切法)。

9\. 完整功能测试页
完整功能测试页实测截图(与本地 app.py 同源对齐,准确率均为 0.7900):


三条使用须知:
- 首次打开要预热:页面需拉取 Pyodide 运行时,约 30–60 秒;演示前先打开一次,等「就绪」后再交给观众;
- 浏览器内只有轻量引擎:三个区块(输入 / 预测 / 评估)全部真实计算,不是演数据;

结论与展望
技术创新与业务价值:
- 原生训练循环替代 Trainer,在问题环境稳定跑通,且把 loss 曲线、梯度裁剪、学习率调度完整暴露给读者;
- 双引擎对照设计,同一评估口径下横向比较预训练微调与浅层基线,为选型提供量化依据;
- 业务价值上,该流水线可直接复用于评论舆情监控、推荐排序特征与内容审核等场景;配套的可交互智能体让非算法人员也能输入一条影评即时获得情感判定与置信度,把建模成果转化为随取随用的生产力工具。
附录:项目文件目录结构
DistilBERT_IMDb影评分类_agent测试页/├── app.py # 可交互智能体主程序(中英双语料,本地 + 浏览器双环境)├── fine_tune.py # 英文 DistilBERT 微调脚本(镜像 + 原生训练循环 + 函数名修复)├── fine_tune_zh.py # 中文 bert-base-chinese 微调脚本(同结构、同超参)├── prep_data.py # 英文样例数据生成脚本├── prep_data_zh.py # 中文样例数据生成脚本(DMSC 豆瓣影评,同口径抽取 1,300 条)├── requirements.txt # 依赖清单├── README.md # 工程说明├── data/│ ├── imdb_sample.csv # 英文样本(train 1,000 / eval 200 / test 100)│ └── zh_movie_sample.csv # 中文样本(train 1,000 / eval 200 / test 100,正负均衡)├── fine_tuned_model/ # 英文微调产物(DistilBERT 权重 + 分词器)├── fine_tuned_model_zh/ # 中文微调产物(bert-base-chinese 权重 + 分词器)└── full/ └── index.html # 完整功能测试页(stlite + Pyodide,中英双语料,双击即开)_作者系自然语言处理与数据挖掘方向分析师,专注预训练语言模型的复现与工程化,拥有多年文本分类项目落地经验。对本文方法或配套工程有任何问题,欢迎在公众号"拓端数据部落"留言,我们会持续更新该系列教程。_
术语表
- DistilBERT
- BERT 的蒸馏压缩版预训练语言模型,参数量减少约四成、推理速度提升约六成,精度损失很小。
- 知识蒸馏(Knowledge Distillation)
- 用大模型的软标签输出指导小模型训练,使小模型在更小体积下逼近大模型效果。
- 微调(Fine-tuning)
- 在预训练语言模型基础上用少量任务数据继续训练,使通用语言能力适配具体任务。
- bert-base-chinese
- 中文预训练 BERT 权重,词表与分词面向中文,是中文 NLP 任务的常用基座。
- 字符级 TF-IDF
- 以中文字符 n-gram 构造稀疏特征,免去中文分词依赖,适合短文本基线。
- 混淆矩阵(Confusion Matrix)
- 二分类评估矩阵,给出真正例、假正例、真负例、假负例,用于计算精确率、召回率与 F1。
- macro F1
- 各类别 F1 的算术平均,对类别不平衡不敏感,用于综合评估二分类表现。
- 混合精度(fp16)
- 用半精度浮点加速训练与推理,仅 GPU 有效,CPU 上需关闭。

Python开发定制PaliGemma2-LoRA视觉语言模型微调小麦穗头小目标检测|附AI智能体、代码和数据
Python用LoRA微调与ISMOTE过采样实现社交媒体文本情感多标签识别|附AI智能体、代码和数据
Python用LoRA微调Gemma4视觉模型用于放射学医学影像问答|附AI智能体、代码和数据
Python结合TF-IDF、逻辑回归、transformers、DistilBERT实现评论语义搜索|附AI智能体、代码和数据

