quora文本匹配实验简单小结

  • 2021 年 5 月 25 日
  • AI

最近把kaggle quora的文本匹配比赛过了一下,第一名的结果的logloss为0.11左右,尝试了一些论文和网文中的方案,这里记录一下:

1、预训练模型秒杀matchzoo里的所有文本匹配模型;

2、matchzoo里的模型效果不是很好啊。。做了一些activation的替换之后效果上升很多,实现有问题;

3、colab升级pro之后尽量用tpu,速度比gpu快太多,节约很多时间,美中不足的是,huggingface的trainer对tpu基本没有支持,虽然设计了参数,但是官方上的issue里提到没有针对tpu内的循环计算进行优化,导致使用了tpu之后反而更慢了,我在使用pytorch-lightning的时候也遇到了这个问题,还是tensorflow支持的最好,毕竟都是google家自己的东西;

4、tpu的支持,torch有xla,tensorflow有直接的tpu接口无缝衔接keras,上收起来,torch的xla用起来真的挺费劲的,又要写主函数,又要xla.spawn,模型记录起来也很麻烦,所以后面用tpu的实验我基本用tf.keras重写了一遍;

后面的实验基本上用的roberta和bert,matchzoo里的算法就测试了esim,效果很差,大佬给的代码提分太多。

5、数据预处理仍旧是非常有必要的,没有预处理的validation loss的第一个epoch的logloss大概是0.40+,进行预处理之后(邮箱格式标准化,转义字符的删除等等),第一个epochs的logloss下降到0.37,最终10个epochs的结果也是后者比前者高2~3个点(一开始用的gpu,跑的比较慢);

6、nn对参数和超参数都非常敏感,尤其是复杂的模型,越复杂的模型越敏感,一个weight decay的系数大小就可以决定2~3个点的loss了,非常夸张,所以超参数调整要做,不行参考下kaggle上的一些现成的设置,还有label smooth,lr schedule之类的常见训练技巧;

7、huggingface的trainer非常的方便,扩展性也很好,自定义loss,分层学习率之类的策略都可以通过继承Trainer来实现,官方教程有写,比较好的地方是fp16,多gpu计算,deepspped等加快训练的功能都封装好了可以直接调用避免了大量冗余的代码,这一点的设计模式和pytorch-lightning几乎一样,闪电也涉及了很好的trainer封装了这些烦人的过程;

8、超参数这类设置妥当之后,剩下的最重要的还是对数据的处理和抽取了,这点和lgb之类的模型基本一样,使用一些比较好的祖传参数设置好了之后,就去做特征工程,这一点差异特别大,看了kaggle quora的第一名的解决方案,涉及到非常大量的细致的特征工程,0.11的loss简直逆天,反正我用bert尝试过各种方案基本上都没能下0.20的logloss。。。

9、数据很重要的地方除了体现在文本数据的预处理和一些特征工程之外(比如文本匹配问题中各种sentence pairs的距离计算的结果等等),还有一个非常显著的方法是对当前语料继续做mlm任务的pretrain 任务,效果非常明显,第一个epoch的loss直接下降了6个点,但是pretrain任务的迭代次数太多效果反而差,太少效果也不明显,我训练了1个epoch和100个epochs的结果都比较一般,大概训练10~20个epochs左右效果比较惊人;

10、后续还有几个实验没跑,一个是多任务结果,mlm任务和text match的二分类任务一起跑,多任务的训练方式还挺多,有的地方是每个任务分别交替训练,我使用的方式是两个任务一起训练迭代,这个具体效果就不清楚了,目前暂时不知道val loss能到多少,但是从第一个epoch的loss来看,效果非常好,第一个epoch的text match的logloss就很低了,这个和之前的实验结果不符,之前的一个文本匹配的比赛测试里多任务的效果很差,主要原因在于我当时用的是cosine similarity loss,和mlm的多分类的loss的量纲差异很大导致效果很不好;

11、还有一个就是多模态的bert了,冠军方案没有涉及到bert这类的模型,毕竟是很早之前的比赛那个时候huggingface还没开源transformer估计,但是通过大量的特征工程取得了很好的效果,比如说各种距离的计算,这类数据如果要囊括到bert中来就要走多模态的路子了,人工衍生的特征走一个分支,文本对走bert,二者concat之后再进行交互得到最终的结果这样,不知道效果如何,还没开始写;

12、text match模型其实都可以和bert结合起来的,只要把bert当作一个embedding来用就可以了