记一次小白调参baseline——NLP中文预训练模型泛化能力比赛

目的

  前情提要
  根据Datawhale大佬们提供的baseline训练模型以及优化方向,对baseline进行改进以期提高分数。对于小白本白来说,very very hard,特此记录过程以鞭策自己,目前仍在艰难探索ing~再次感谢大佬们的指点!

背景

个人配置

  • 本机显卡:RTX3070;
  • 目前租用两块3090试一试水;
  • 以及第一次调baseline的小白~

赛题要求

baseline提供的优化方向

  1. 修改 calculate_loss.py 改变loss的计算方式,从平衡子任务难度以及各子任务类别样本不均匀入手;
  2. 修改 net.py 改变模型的结构,加入attention层,或者其他层;
  3. 使用 cleanlab 等工具对训练文本进行清洗;
  4. 做文本数据增强,或者在预训练时候用其他数据集pretrain;
  5. 对训练好的模型再在完整数据集(包括验证集和训练集)上用小的学习率训练一个epoch;
  6. 调整batchSize和a_step,变更梯度累计的程度,当前是batchSize=16,a_step=16;
  7. 用 chinese-roberta-wwm-ext 作为预训练模型;

调优过程(随缘更新~)

调整batchSize和epochs

  在第一次跑baseline的时候,batchSize=16就已经爆破了我的8g显存,随即我调整batchSize=8成功跑通,结果如图:
在这里插入图片描述
  之后大幅度调小epoch=6,结果又有了一次提升。
在这里插入图片描述

  在往后的训练过程中,epoch基本在4~6之间浮动,batchSize4~8观察提交得分发现又回到了解放前。在这里插入图片描述

cleanlab(仍在尝试ing)

  开始尝试使用cleanlab清洗数据。简言之,就是通过某种方式(置信学习)自动清洗那些标注质量不过关的“脏数据”。而cleanlab就是来自于ICML2020的一篇由MIT和Google联合提出的paper(原文链接)中开源的数据清洗工具,只需要pip install cleanlab安装即可使用。详细讲解可以看这篇文章——> 夕小瑶:别让数据坑了你,写得灰常好!
  如果想找出标注错误的样本,我们仅需要提供两个输入:一个输入是原始的样本标签(由于原始标签可能有错误,这里称为噪声标签);另一个输入就是通过对训练集交叉验证,来预测的每一个样本在不同标签类别下的概率,这是一个 n × m n\times m n×m的概率矩阵( n n n为数据集大小, m m m为标签类别总数)。

from cleanlab.pruning import get_noise_indices
# 输入
# s:噪声标签
# psx: n x m 的预测概率概率,通过交叉验证获得
ordered_label_errors = get_noise_indices(
    s=numpy_array_of_noisy_labels,
    psx=numpy_array_of_predicted_probabilities,
    sorted_index_method='normalized_margin', # Orders label errors
 )

如果我们不只是想找到错误标注的样本,还想把这些标注噪音clean掉之后重新继续学习:

from cleanlab.classification import LearningWithNoisyLabels
from sklearn.linear_model import LogisticRegression

# 其实可以封装任意一个你自定义的模型.
lnl = LearningWithNoisyLabels(clf=LogisticRegression())
lnl.fit(X=X_train_data, s=train_noisy_labels)
# 对真实世界进行验证.
predicted_test_labels = lnl.predict(X_test)

  目前还在学习baseline代码结构,我一直在(数据准备阶段)generate_data.py做文章,经过几番尝试之后,并没有跑通代码。
  在写博客的时候,我发现可能是我对于数据清洗与模型训练的结合点不够清晰(错误地在数据集划分的时候做文章),而且需要进一步明确cleanlab的输入参数的来源和含义,也就是说需要再重新读一遍文章解析,然后参考一下源码解读

更换预训练模型

  在尝试cleanlab无果后,我选择了一个比较容易实现的方向。将原来的bert-base-chinese更换为chinese-roberta-wwm-ext(下载地址)。下载config.json,vocab.txt,pytorch_model.bin,把这三个文件放进tianchi-multi-task-nlp/bert_pretrain_model文件夹下。
在这里插入图片描述
  而后,为了体验一下batchSize=32的感觉,我租了两块3090(知乎搜索适合自己方案吧,也可以在了解清楚情况后,用colab或aistudio)试一试水,瞬间提速。老黄刀法名不虚传!
在这里插入图片描述
之后,为了测试一下两块3090的实力,我将batchSize调到了64,没想到居然爆了(一定是我操作失误~~)。写博客前最后一次在租用的环境中测试,参数调整如下:batchSize=48epoch=8,提交结果如图:
在这里插入图片描述
并没有明显的变化。。。质量优秀的数据才是关键啊!

总结

  调整batchSize以及epochs用于适配显存(贯穿调优全程),一开始尝试使用cleanlab清洗训练集;在不得方法精髓后,选择替换预训练模型,将bert-base-chinese替换为chinese-roberta-wwm-ext;在写博客的时候,我秃然想起了方法5(请原谅一只小白的愚钝~),与李宏毅老师(ML20课程主页)在讲解模型训练的Basic Concept章节中所提到的(N-fold)cross validation方法类似,该方法可能会平衡variance和bias以减小total error。感觉还可以再抢救一下模型,写完之后继续愉快地学习吧!

参考

猜你喜欢

转载自blog.csdn.net/weixin_40807714/article/details/114108607