正在加载中...

展开本页目录
算法教程BERT_Finetune-BERT 微调

BERT_Finetune-BERT 微调

No.062 · 在线教程

BERTFinetune-BERT 微调 模块的真实实现位于 core/bertfinetunecalculator.py。它并不是传统机器学习的文本向量化分类器,而是调用 HuggingFace transformers 中的 AutoTokenizer 与 AutoMode…

BERT_Finetune-BERT 微调

1. 方法概述

BERT_Finetune-BERT 微调 模块的真实实现位于 core/bert_finetune_calculator.py。它并不是传统机器学习的文本向量化分类器,而是调用 HuggingFace transformers 中的 AutoTokenizerAutoModelForSequenceClassification,对预训练语言模型做文本分类或文本回归微调

设原始数据集为

$$ \mathcal{D}=\{(s_i,y_i)\}_{i=1}^{N} \tag{1} $$

其中 \(s_i\) 是第 \(i\) 条文本,\(y_i\) 为标签。界面要求用户显式指定:

  • 文本列 text_col
  • 标签列 label_col
  • 任务类型 classificationregression

程序还支持切换预训练模型名称或本地模型路径,默认值为 bert-base-chinese

2. 数据准备与划分

2.1 文本与标签抽取

程序只会保留文本列与标签列,并删除其中任一为空的样本。得到清洗后的样本集合

$$ \mathcal{D}'=\{(s_i,y_i)\}_{i=1}^{N'} \tag{2} $$

其中 \(N'\le N\)。

2.2 分类标签编码与回归数值化

分类任务中,代码使用 LabelEncoder 将原始标签映射为整数类别:

$$ \phi:\mathcal{Y}\to\{0,1,\ldots,C-1\} \tag{3} $$

其中 \(C\) 为类别数。映射后的整数标签用于训练,原始标签名称会保存在 label_names 中,并导出到 Excel 的 Labels 工作表。

回归任务中,标签列会被逐项转换为浮点数:

$$ y_i^{\ast}=\mathrm{float}(y_i) \tag{4} $$

若存在无法转成有限数值的样本,程序会直接报错。

2.3 分词与张量化

当前实现对全部文本一次性调用 tokenizer:

$$ (\text{input\_ids}_i,\text{attention\_mask}_i)=\mathrm{Tokenizer}(s_i;L_{\max}) \tag{5} $$

其中 \(L_{\max}=\text{max\_length}\)。代码固定启用:

  • truncation=True
  • padding=True

因此过长文本会被截断,短文本会被补齐到批内统一长度。

2.4 训练/验证切分

该模块没有单独测试集。它只会把全部样本切成训练集和验证集。设验证比例为 \(r=\text{valid\_split}\),则

$$ \mathcal{D}_{\mathrm{train}}\cup \mathcal{D}_{\mathrm{val}}=\mathcal{D}',\qquad |\mathcal{D}_{\mathrm{val}}|\approx rN' \tag{6} $$

分类任务下,若类别数和样本数允许,切分时会尝试分层抽样;否则退化为普通随机切分。

需要特别强调:

  • valid_split>0 且样本量足够,最终 Predictions/Metrics 基于验证集
  • valid_split=0 或样本数过少,则不会创建验证集,最终指标直接在训练集上计算。

因此,当前模块并没有真正意义上的独立测试集评估。

3. 模型结构

3.1 预训练底座与任务头

程序调用

$$ \mathrm{AutoModelForSequenceClassification}(\text{model\_name},\text{num\_labels}) \tag{7} $$

构建模型。对输入文本 \(s_i\) 编码后,底座模型生成序列级表示 \(h_i\),再由任务头得到输出:

$$ z_i=W h_i+b \tag{8} $$

这里 \(z_i\) 为:

  • 分类任务下的类别 logits;
  • 回归任务下的单个连续值输出。

虽然模块名称写的是 BERT_Finetune,但真实实现使用 AutoModel...,所以只要兼容 HuggingFace 的模型名称或本地路径,底层并不一定严格限定为原始 BERT。

3.2 分类输出

分类任务中,预测概率由 softmax 给出:

$$ p_{ic}=\frac{\exp(z_{ic})}{\sum_{k=1}^{C}\exp(z_{ik})} \tag{9} $$

最终预测类别为

$$ \hat{y}_i=\arg\max_{c} p_{ic} \tag{10} $$

3.3 回归输出

回归任务中,模型输出单个实数:

$$ \hat{y}_i=z_i \tag{11} $$

代码还会尝试设置

$$ \text{problem\_type}=\text{regression} \tag{12} $$

以便让 HuggingFace 的序列分类头按回归模式计算损失。

3.4 冻结底座

若勾选 freeze_base=True,程序会冻结底座模型参数,只训练任务头。记底座参数为 \(\theta_b\),分类/回归头参数为 \(\theta_h\),则冻结状态下有

$$ \nabla_{\theta_b}\mathcal{L}=0,\qquad \nabla_{\theta_h}\mathcal{L}\neq 0 \tag{13} $$

这会显著减少可训练参数,但也会限制模型适应当前数据集的能力。

4. 训练目标与优化

4.1 分类损失

分类任务使用交叉熵损失:

$$ \mathcal{L}_{\mathrm{cls}}=-\frac{1}{|\mathcal{D}_{\mathrm{train}}|}\sum_i \log p_{i,y_i} \tag{14} $$

4.2 回归损失

回归任务使用均方误差:

$$ \mathcal{L}_{\mathrm{reg}}=\frac{1}{|\mathcal{D}_{\mathrm{train}}|}\sum_i (y_i-\hat{y}_i)^2 \tag{15} $$

4.3 参数更新

训练阶段使用 AdamW 优化器:

$$ \theta \leftarrow \mathrm{AdamW}\!\left(\theta,\eta,\lambda\right) \tag{16} $$

其中 \(\eta=\text{learning\_rate}\),\(\lambda=\text{weight\_decay}\)。

当前实现中没有

  • 学习率调度器;
  • 早停;
  • 梯度裁剪;
  • 最优 epoch 选择;
  • 测试集单独推理阶段。

4.4 每轮损失记录

对第 \(e\) 轮,训练损失记为

$$ \mathrm{TrainLoss}^{(e)}=\frac{1}{B}\sum_{b=1}^{B}\ell_b^{(e)} \tag{17} $$

若存在验证集,则还会额外计算

$$ \mathrm{ValLoss}^{(e)}=\frac{1}{B_{\mathrm{val}}}\sum_{b=1}^{B_{\mathrm{val}}}\ell_{b,\mathrm{val}}^{(e)} \tag{18} $$

这些值会被写入 Training_Loss 工作表,并绘制 train_loss_*.png

5. 评价指标、输出结果与实现细节

5.1 分类指标

分类任务输出:

  • accuracy
  • precision_macro
  • recall_macro
  • f1_macro
  • precision_weighted
  • recall_weighted
  • f1_weighted

其中准确率为

$$ \mathrm{Accuracy}=\frac{1}{n}\sum_{i=1}^{n}\mathbf{1}(\hat{y}_i=y_i) \tag{19} $$

加权 F1 为

$$ \mathrm{F1}_{\mathrm{weighted}}=\sum_{c=1}^{C}\frac{n_c}{\sum_j n_j}\cdot \mathrm{F1}_c \tag{20} $$

分类任务还会输出混淆矩阵图 confusion_matrix_*.png

5.2 回归指标

回归任务输出:

  • mse
  • rmse
  • mae
  • r2

其定义分别为

$$ \mathrm{MSE}=\frac{1}{n}\sum_{i=1}^{n}(y_i-\hat{y}_i)^2 \tag{21} $$

$$ \mathrm{RMSE}=\sqrt{\mathrm{MSE}} \tag{22} $$

$$ \mathrm{MAE}=\frac{1}{n}\sum_{i=1}^{n}|y_i-\hat{y}_i| \tag{23} $$

$$ R^2=1-\frac{\sum_i(y_i-\hat{y}_i)^2}{\sum_i(y_i-\bar{y})^2} \tag{24} $$

回归任务会绘制 pred_vs_true_*.png 散点图。

5.3 预测结果表

Predictions 工作表对两种任务分别导出:

  • 分类:text, y_true, y_pred, y_true_label, y_pred_label, pred_prob
  • 回归:text, y_true, y_pred

其中 pred_prob 取的是

$$ \max_c p_{ic} \tag{25} $$

即预测类别的最大 softmax 概率。

5.4 实际导出结构的几个关键特点

当前模块导出的 Excel 包含:

  • RawData_Preview
  • Predictions
  • RawData
  • Processed
  • Training_Loss
  • Metrics
  • Parameters
  • Params
  • Labels
  • Charts_Index

但要注意几个实现细节:

  1. RawData_PreviewRawData 实际上都只保存了 df.head(50) 的预览,而不是完整原始数据;
  2. Processed 实际上直接复用了 Predictions,并不是 token id、attention mask 或其它真正的“处理后特征”;
  3. ParametersParams 内容重复;
  4. Metrics/Predictions 默认对应验证集;若没有验证集,则对应训练集。

6. 复现脚本与实现说明

6.1 自动复现脚本

结果页会自动生成 repro_bert_finetune_*.py。脚本会:

  1. 把当前数据另存到 repro_inputs/
  2. 重新构造同样的 analysis_params
  3. 再次调用 BertFinetuneCalculator.run_analysis()
  4. 重新训练并生成一份 *_reproduce.xlsx

因此它不是“加载已训练权重后推理”,而是:

$$ \text{repro}=\text{同参数重新训练一次} \tag{26} $$

6.2 实现说明与注意事项

结合 core/bert_finetune_calculator.pyui/upload_widget.pyui/results_widget.py 与真实导出的结果文件,可以把该模块概括为:

  • 它确实是基于 HuggingFace 的真实文本微调实现;
  • 支持文本分类和文本回归;
  • 可选冻结预训练底座,仅训练顶部任务头;
  • 训练过程较轻量,没有调度器、早停和独立测试集;
  • 最终指标默认落在验证集上,若无验证集则退回训练集;
  • Excel 导出做了兼容性补充,但部分 sheet 名与内容并不完全匹配其字面含义。

因此,在论文说明中更准确的写法应是:该软件实现了一个基于 HuggingFace AutoModelForSequenceClassification 的文本分类/回归微调模块,但评估流程只有训练/验证切分,没有独立测试集,且导出层包含若干为兼容而保留的重复或简化工作表。

7. 论文写作模板

可在论文“方法部分”中写为:

“本文采用基于 HuggingFace 预训练语言模型的 BERT 微调方法进行文本建模。首先,利用分词器将原始文本编码为 token 序列,并构造训练集与验证集;其次,以 AutoModelForSequenceClassification 为基础建立分类或回归任务头,并根据任务类型选择交叉熵损失或均方误差损失进行参数优化;随后,在验证样本上输出预测结果与评价指标,用于衡量模型性能;最后,结合预测结果表和训练损失曲线,对模型的文本判别或文本回归能力进行分析。”

8. 单篇终审补充

8.1 图题与表题对齐建议

  • RawData_Preview 表可写为:表X BERT 微调原始数据预览表。
  • Predictions 表可写为:表X BERT 微调预测结果表。
  • RawData 表可写为:表X BERT 微调原始数据预览副本表。
  • Processed 表可写为:表X BERT 微调处理后结果兼容表。
  • Training_Loss 表可写为:表X BERT 微调训练损失记录表。
  • Metrics 表可写为:表X BERT 微调评价指标汇总表。
  • Parameters 表可写为:表X BERT 微调参数设置表。
  • Params 表可写为:表X BERT 微调兼容参数表。
  • Labels 表可写为:表X BERT 微调标签映射表。
  • Charts_Index 表可写为:表X BERT 微调图表索引与路径清单。
  • confusion_matrix_*.png 建议写为:图X BERT 微调混淆矩阵图。
  • train_loss_*.png 建议写为:图X BERT 微调训练损失曲线图。

8.2 终审说明

  • 当前代表性结果目录中的真实主工作簿为 bert_finetune_results_20260316_040038.xlsx,复现输出为 bert_finetune_results_20260316_040038_reproduce.xlsx。论文若列实验输出文件,应明确区分主运行结果与 reproduce 结果。
  • 当前真实工作表包含 ParametersParams 两张重复参数表,且 RawData_PreviewRawData 都只是预览性质数据。终稿中不要把这些兼容性工作表误解释为两套不同实验或完整原始数据存档。
  • Processed 当前并不是真正的 token id / attention mask 中间结果,而是兼容导出层保留下来的简化内容。正文若介绍“处理后数据”,应避免把它写成严格的 BERT 输入张量。
  • 真实 repro 脚本为 repro_bert_finetune_20260316_040038.py,其参数中 file_path 指向 repro_inputs/bert_finetune_20260316_040038_data.csv。附录里的复现实验说明应保持这一 repro_inputs/...csv 相对路径口径。
  • 当前指标默认对应验证集;若没有验证集才退回训练集。论文结果部分不能泛写成“测试集指标”,应按真实实现写成“验证集评估指标”更准确。

8.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/NLP基础/BERT_Finetune-BERT 微调,本次采用的代表性结果目录为 具体的算法3/NLP基础/BERT_Finetune-BERT 微调/results/BERT_Finetune-BERT 微调分析结果_20260316_040038

当前目录中真实存在两份工作簿:

  • bert_finetune_results_20260316_040038.xlsx
  • bert_finetune_results_20260316_040038_reproduce.xlsx

两者实测工作表一致,均包含:

  • RawData_Preview
  • Predictions
  • RawData
  • Processed
  • Training_Loss
  • Metrics
  • Parameters
  • Params
  • Labels
  • Charts_Index

因此这一轮应把 ...040038.xlsx 作为主结果,把 ...040038_reproduce.xlsx 作为重新训练再生产物。ParametersParams 是兼容重复表;RawData_PreviewRawData 都是预览性质,不应写成完整原始数据留档。

当前目录中的真实图文件为:

  • confusion_matrix_20260316_040038.png
  • confusion_matrix_20260316_040041.png
  • confusion_matrix_20260316_040045.png
  • train_loss_20260316_040038.png
  • train_loss_20260316_040041.png
  • train_loss_20260316_040045.png

这说明该目录里存在主运行和 reproduce 相邻时间戳图,图型只有混淆矩阵与训练损失曲线两类。论文中不要把它写成包含 ROC/PR 或 attention 可视化。

复现实物方面,该目录实际包含:

  • 具体的算法3/NLP基础/BERT_Finetune-BERT 微调/results/BERT_Finetune-BERT 微调分析结果_20260316_040038/repro_bert_finetune_20260316_040038.py
  • 具体的算法3/NLP基础/BERT_Finetune-BERT 微调/results/BERT_Finetune-BERT 微调分析结果_20260316_040038/repro_inputs/bert_finetune_20260316_040038_data.csv
  • 具体的算法3/NLP基础/BERT_Finetune-BERT 微调/results/BERT_Finetune-BERT 微调分析结果_20260316_040038/repro_bert_finetune_20260316_040038_output.txt

脚本中把 analysis_params['file_path'] 设为 repro_inputs/bert_finetune_20260316_040038_data.csv,但 model_name 仍指向本机 HuggingFace 缓存中的 tiny-random-bert 绝对路径。因此这篇可写“输入文件已相对路径化”,但不能美化成“模型路径也完全可移植”。

9. 软件实现核查补充(2026-07)

  • 当前实现的主结果目录应写作 具体的算法3/NLP基础/BERT_Finetune-BERT 微调/results/BERT_Finetune-BERT 微调分析结果_20260316_040038,主工作簿以 BERT_Finetune-BERT 微调分析结果_20260316_040038.xlsx 为准。
  • 正文应围绕 ParametersRawDataProcessedDataTrainInfoTrainingMetricsPredictionsConfusionMatrixClassificationReportCharts 来写,不要把复现输出当成另一套不同模型。
  • 图证应对应 confusion_matrix_20260316_040038.pngtrain_loss_20260316_040038.png 以及同轮相邻时间戳图,但不要把它写成 ROC/PR 或 attention 图。
  • repro_bert_finetune_20260316_040038.py + repro_inputs/bert_finetune_20260316_040038_data.csv 属于标准结果目录内复现口径,但 model_name 路径依赖本机缓存,终稿说明要把这一依赖写清楚。