最近在做一个法律文书分类的项目,用开源的BERT-base-chinese做底座,自己攒了大概2万条标注数据。第一次微调时learning rate设的2e-5,batch size 16,跑了3个epoch,结果验证集F1比原模型直接掉了4个点。后来试着把学习率降到1e-5,又加了warmup,稍微好一点但训练集loss和验证集loss差距越来越大,明显过拟合了。我怀疑是不是数据里类别分布太不均匀(最少的类别只有200多条),但试过class weight和focal loss也没改善多少。有没有大佬遇到过类似情况?是应该先做数据增强还是干脆换更大的模型?或者我这种任务量根本不适合微调,直接用什么更轻量的方案?求指点,卡在这好几天了。
微调后的模型越训越差,是数据问题还是我超参没调对?
全部回复
共 29 条你这情况我太熟了,之前做司法文书分类也栽过跟头。2万条数据其实够用,但法律文本长句多,BERT-base吃不住,建议先试试不同max_length截断策略,别急着换大模型。类别不平衡不是主因,你试过给少数类做简单的回译或同义词替换没?我经验是数据增强比调loss管用,但注意别破坏原文案术语。另外你epoch才3个,如果数据本身噪声大,early stopping设严点,别看验证集F1,直接盯每个类别的recall。
2万条对法律文书来说真不算多,类别又这么偏,建议先试试冻结底层只训顶层,比折腾数据增强省事。
看到你这个情况我太有同感了,之前做医疗文本分类也栽过一模一样的跟头。我猜你那个“越训越差”的4个点可能不是过拟合那么简单,因为BERT微调在2万条数据上通常不会这么脆弱,建议先检查一下数据划分时是不是按类别随机分的,法律文书里很多长文本和特殊标点会导致句子被截断,这比类别不均衡更致命。另外你试了class weight和focal loss没效果,我怀疑你是在loss层面做文章,但真正的问题可能出现在输出层的初始化上——对极端不均衡类别,把分类头的bias手动设成log(先验概率)往往有奇效,这招我试过能直接拉回2-3个点。至于要不要换大模型,我觉得先别急着上法律领域预训练模型,你2万条数据对BERT-base来说其实够用,关键是你有没有尝试过冻结前8层只训练后4层?这样能大幅缓解灾难性遗忘,尤其当你的文书风格和预训练语料差很远的时候。最后关于数据增强,别用回译那些花活,法律术语一改意思就变了,不如去搞点无监督的领域数据做二次预训练,哪怕只有5万条,也比硬调超参有用。如果这些还不行,你试试把学习率改成3e-5但加线性衰减和早停,我最后就是这么救回来的。
我觉着你这个问题大概率出在数据和任务适配性上,而不是单纯超参。BERT-base-chinese做法律文书这种领域性极强的文本,本身词表和预训练分布就跟通用语料差很远,你2万条数据看着不少,但分摊到十几个类别里,尤其那个200条的 minority class,模型根本学不到稳定特征,class weight和focal loss只是调整了梯度权重,没解决表征空间里类别重叠的根本问题。你提到训练集和验证集loss差距拉大,这不只是过拟合,更像是模型在死记硬背那些高频类别的模板化表达,法律文书里很多固定句式,一旦遇到稍变通的表述就崩。我建议你先别急着换大模型或者上数据增强,拿几百条训练集出来做一次错误分析,看看是不是模型把“法条引用”和“判决结果”这类关键词当成了分类信号,如果是,那得考虑加一个领域自适应的中间训练步骤,比如用你手上的2万条无监督文本先做一遍MLM继续预训练,再微调分类头。另外学习率降到5e-6配合线性warmup,batch size加到32试试,有时候小batch在类别不均衡时反而会让梯度震荡更严重。你直接放弃微调应该不至于,但确实得承认BERT在严肃长文本分类上不如那些带全局注意力或可处理长序列的模型,比如法律文本动辄上千字,BERT截断512后丢掉大量上下文,这本身就可能让你损失好几个点。
F1掉4个点这个幅度其实挺典型的,不一定是超参的锅。先确认一个事:你微调时有没有把分类头重新初始化?如果直接拿原模型接了个新分类层,前几个epoch loss震荡很正常,但F1反降这么多,我第一反应是标签质量或者数据里有噪声。法律文书这种领域,标注一致性很容易出问题,尤其是200多条那个小类别,可能标注标准本身就不统一,模型学到的就是矛盾信号。
另外你说训练集和验证集loss差距越来越大,说明模型容量对这两万条数据来说是够的,甚至有点过剩。这时候继续加warmup或者调lr其实治标不治本,不如先做个简单的baseline:冻结BERT只训分类头,看看F1能到多少,再逐步解冻顶层。如果冻结状态下就不行,那基本是数据或标签的问题,跟超参关系不大。
类别不均衡用focal loss没效果,我猜可能是小类别样本本身区分度太低,不是权重能救的。可以试试对少数类做针对性采样或者合成,但法律文书这种文本做增强容易失真。换更大模型不一定有用,两万条数据喂大模型反而更容易过拟合。建议先拿500条做个错误分析,看看模型到底错在哪,比盲目调参有用得多。
2万条数据做法律文书分类其实不算少了,BERT-base-chinese正常微调应该能work。你验证集F1掉4个点这个现象,我第一反应是label mapping或者数据里有没有脏标,尤其法律文书这种专业领域,标注一致性很容易出问题,建议先抽几十条看看标签有没有明显矛盾的。过拟合那个信号倒是挺明确的,train和val loss越拉越开,说明模型在死记训练集,这时候加class weight和focal loss确实帮助有限,因为它们主要解决的是类别不平衡导致的偏置,不是泛化问题。200多条的少数类,如果它本身区分度就低,强行加权反而可能让模型在边界上更混乱,不如试试对少数类做定向的数据增强或者回译。学习率2e-5对BERT微调来说不算激进,但如果你只跑3个epoch就掉点,也可能是warmup比例没设好,前几百步直接把预训练权重带偏了。我个人经验是法律领域这种分布,换更大的模型收益不一定明显,先把数据质量和标签一致性过一遍,再考虑用早停加小学习率多跑几轮看看曲线。
你这个情况我去年做类似任务时也踩过,2万条数据看着不少,但法律文书类别边界本来就模糊,模型很容易学偏。验证集F1掉4个点不一定是过拟合,也可能是学习率把预训练学到的通用语义冲垮了,试试分层学习率或者只微调后几层。训练loss和验证loss差距大,先别急着怪数据,检查下验证集和训练集是不是同分布,比如不同年份或来源的文书混在一起。类别不均衡那200条如果和多数类语义重叠,class weight反而会让模型把边界推歪,focal loss也不是万能药。我建议先做个简单的错误分析,看验证集错分的是不是集中在少数类,如果是,再考虑针对性采样或合成数据。换大模型不一定有用,法律领域更吃数据质量和标注一致性,不如先拿1000条数据人工复查标注。另外你最后一个epoch是不是早停没设好,有时候F1掉是因为训练后期模型在记忆噪声。
2万条数据对BERT微调来说其实不算少,问题可能出在你的学习率还是偏大,BERT-base在中文小数据集上1e-5都算激进,试试2e-5配合更小的batch或者梯度累积。类别不均衡那个方向先放一放,200条最少的类虽然少但也不是不能学,重点看下验证集是不是分布也偏,F1掉4个点很可能是模型还没收敛就过拟合了。我建议先冻结底层只训分类头跑几个epoch看看效果,再决定要不要全量微调,直接换大模型大概率更糟。
2万条数据不算少,先别急着换模型,查查标注质量吧,法律文书类别边界模糊很容易标错。