- python==3.6
- pytorch==1.6
- cuda==10.1
- transformers==4.1.0
这个比赛最开始的时候,我是完全抛弃了以前的NLP代码结构,开始重构我的代码,但是重构的代码没有做好规划,后面才发现结构太乱了,很多地方封装得太死,导致想改动模型的时候,就出现了困难,也导致了我前期写完baseline以后,就没怎么做这个比赛,一直到后期才过来融合了几次结果。所以其实方案里面并没有做太多的内容,就是对简单的bert 文本分类的baseline调了调参,上面开源的这部分是我的bert wwm单模五折,A榜0.9585。最后再通过各种bert,各种融合达到了B榜最高的成绩。
首先贴出赛题链接:https://www.sodic.com.cn/competitions/900010
本赛题目标是要对企业上报的隐患进行分类,判断他们上报的隐患是否合格,并且也给出了隐患自查的标准。简单来说,这个题目就是一个文本分类问题,具体的分类怎么做,有几种不同的方法。
- 最简单的方式就是直接拿content出来用文本分类的方式去做,以为题目所要判断的主要是企业上报的内容,所以前面隐患自查的标准level重要性就没那么大。直接用content文本分类效果也挺好的。初次以外,还可以把level和content直接拼在一起,再进行分类。具体操作的方案很多,我主要尝试的是直接对content分类以及level和content拼接再分类,效果其实差不多。
- 第二种就是当做文本匹配来做,第一句话就是level,第二句话则是content。题目的大部分数据长度都不足512,但是少数拼接以后的数据会超过512,所以还要做一个截断处理。 两种方案的结果,在我这里是第二种略微好于第一种,但是为了模型融合的时候模型之间具有大的差异性,也可以将不同的方案都做起来,然后再融合。
我主要采用的还是bert wwm模型,对bert进行预训练,然后微调。
预训练的部分主要是采用了MLM任务来预训练,加入了动态MASK和N-gram MASK策略来提升任务难度。
虽然我是做了预训练,但是其实这部分收益几乎为0,很小很小的抖动。
关于微调,首先我想说的就是这个题目的验证集实在太不准了,两个epoch之间的F1抖动都能够达到2个百分点,尽管学习率调小了,但是效果依然不好,可以说这个题目就只能用线上成绩来验证模型效果。
最基础的不调参的bert baseline在A榜也可以达到0.952左右的分数。然后我主要加入了FGM对抗训练,余弦退火等操作。但我也测试过,就算不加这些操作,线上成绩也不会发生太大的变化。反而是通过调参,最终线上提升到了0.955左右的分数。还有像lookahead和ema,我也都尝试了,效果都不怎么好。
另外一个上分trick就是阈值搜索,几乎所有的F1为指标的任务,都可以采用这个操作,也基本上是稳定上分的操作。这个操作大概就能上0.957左右的分数了。然后通过多次换随机数种子,A榜分数在0.956到0.959之间抖动。这基本上就是我单模bert进行的所有操作。
另外,这个题目用五折或者十折交叉,并没有太大的提升,至少把阈值拿来平均的方式,提升几乎为0,不过还可以尝试一下把五折得到的结果拿来投票,我认为这种方式应该是更科学的。但是因为我代码结构的限制,导致我实在不想修改代码,所以其他方案也都没有尝试。
剩下的上分技巧就是模型融合了,bert base,robert,macbert,nazha,全部跑起来,然后直接投票融合,选个合适的阈值,这题基本上就结束了。
对于本次比赛,可以说就是简单的跑了一个bert文本分类的baseline,没有尝试新东西,也没有做太多的操作,因为其他比赛的缘故,这个比赛每天就用一次机会调一个参数就结束了。因为有一些新人也在问我关于这个比赛的情况,所以这里就开源一份代码(结构真的非常混乱),主要看下思路就差不多了。打完这个比赛,最大的感想就是,还是别乱改代码了,祖传代码upup。