查看原文
其他

Kaggle Quora Insincere Question Classification Rank 13 方案分享

灿明 剑指风险 2020-10-22





在kaggle上第一次参加NLP类比赛,前前后后总共花了3个月,使用keras构建模型在A榜分数不稳定,即使设置所有随机数,还是会有小波动,论坛上都倾向于使用PyTorch最后选择一份A榜最高的和一份CV最高的结果提交, 结果CV最高的在B榜成功排到13th,solo金牌。本次竞赛是在kaggle提供的kernel上进行,环境和时间有所限制,加上不允许使用外部数据,所以想要在限定的因素下进入前排,感觉挺不容易。开榜后能成功排上榜单只有1401支队伍,原本有4000多支队伍,大部分队伍由于各种原因被刷了,其中一个是超时,因此大家必须留出足够时间才能运行7倍的B榜数据。


01 时间规划 


本次比赛限定2h(7200s),经过测试和计算确定使用三种NN模型结构,使用7折之前3折,每一折对应一种模型结构,最大化差异性。


* 三个模型训练:6600s

* 文本预处理:100s

* 读取词嵌入:200s


剩下的时间当做冗余,因为B榜数据没有给出,必须留出相应的时间。


02文本预处理


测试了词干还原,词形转换,生词替换,大小写转换等等一些常见NLP预处理手段,对LaTex公式和http链接清洗;清洗后对连接符进行分隔,以保证能找到大部分词的嵌入向量,如果说不做任何处理直接按空格分隔只能找32.77%的glove词汇量, 文本覆盖率88%, 文本预处理完可以达到69.09%的glove词汇量, 文本覆盖率达到99.58%,可见预处理是提升分数一大手段。

在使用keras的tokenizer进行词编码时,需要更改默认的过滤链接符, 本次比赛不过滤任何字符, 事实上在glove预训练文件能找到的字符向量都会提分;同时设置最大词汇量20W,足以涵盖99.9%文本,更大的数字需要读入更多向量可能会造成kernel内存不足,保险起见。

本次比赛大概花了40%时间来处理文本,参考了公开kernel的做法,数字代替、缩写还原、名词代替etc..但是由于CV都没有提升,这些处理手段都被弃掉了。

03 词嵌入 


读取词嵌入时有两种方法初始化oov词汇权重: 0值,或者根据预训练权重分布随机初始化值,经过测试,后者效果较好,这也是我在这次比赛学到的一点。

寻找词汇的预训练向量时,只寻找原词、原词首大写或原词全大写的三种形式的向量,步步递进,并不寻找词干、派生词的词向量。

对预训练向量进行结合,主办方提供4种预训练权重,结合的方法根据论坛讨论得知,常见有Mean Embed,Concat Embed,Projection Meta Embed(没有测试)。

Mean Embed方法是将同一词的的N种不同预训练向量按相应维度与比例系数取值,每个词向量表示为300维,内存消耗较小,能训练较多epochs;在对每一种结合都需要设计不同模型参数来获取稳定CV分数,最终决定选择两种差异性较大的预训练向量按比例64:36结合。每次换参数都需要花约9个小时运行获取CV,所以没有足够多机器训练很难得到好的参数。

Concat Embed方法是将同一词的N种不同预训练向量直接连接,即每个词向量表示为 N \* 300 维,缺点是训练时间加大很多以及内存消耗大,训练效果一般。

04 模型 


LSTM_GRU



poorRNN



BiLSTM_CNN


       

本次比赛使用的模型如上,像第一个模型没有使用全连接层,一是处于时间考虑,能省则省,二是无全连接的训练效果并不差;三个模型都是用RNN(LSTM\GRU)对嵌入词向量获取特征后再进行其他操作运算,或卷积、或直接池化、或使用注意力机制。实际上第三个模型RCNN这种结构训练得到最好CV,出于差异性融合考虑,分别设计了下游不同结构获取不同结果,模型里每个参数除了随机种子数和一些固定参数外,其余参数都需要大量调参以获取稳定较高CV。

如何在有限时间里把每个模型训练好,先是把每个模型单独训练数个epoch,观察val loss,val loss达到一定epoch便不会下降,val loss不下降再多训练一个或两个epoch,通过这样的方法固定每个模型的epoch数量,不使用早停,保存最好权重检查点以及学习率调整;模型训练使用自定义AdamW优化器,唯一好处是调整权重衰减系数weight_decay使模型不容易过拟合。

04 总结 


       花三个月时间,拿到一枚gold medal是对自己的最好的奖励。同时,学到不少东西,在kaggle上没有最厉害的,不能小看每一位kaggler,比如说融合预训练权重我就是在论坛上学到的,再经过自己思考调整下方向,就能获得不错的效果, 一些文本预处理在公开kernel直接搬过来,调整参数,舍弃降分操作;由于限制因素,有很多tricks都没办法用到,如伪标签,数据增加等。


下面是分享的地址

https://www.kaggle.com/canming/ensemble-mean-iii-64-36

如果有问题可在公众号留言,作者会解答哦



▼▼




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存