七月,酷暑难耐,认识的几位同窗参加知乎看山杯,均取得不错的排名。当时天池AI医疗大赛初赛结束,官方正在为复赛进行平台调试,复赛时间一拖再拖。看着几位同窗在比赛中排名都还很不错,因而决定抽空试一试。结果一发不可收拾,又找了两个同窗一块儿组队(队伍init)以致于整个暑假都投入到这个比赛之中,并最终以必定的优点夺得第一名。html 1. 比赛介绍这是一个文本多分类的问题:目标是“参赛者根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出对未标注数据自动标注的模型”。通俗点讲就是:当用户在知乎上提问题时,程序要可以根据问题的内容自动为其添加话题标签。一个问题可能对应着多个话题标签,以下图所示。python
![]() 这是一个文本多分类,多label的分类问题(一个样本可能属于多个类别)。总共有300万条问题-话题对,超过2亿词,4亿字,共1999个类别。架构 1.1 数据介绍参考 https://biendata.com/competition/zhihu/data/机器学习 https://biendata.com/competition/zhihu/rules/?next_url=%2Fcompetition%2Fzhihu%2Fdata%2F函数
总的来讲就是:工具
1.2 数据处理数据处理主要包括两部分:
![]()
1.3 数据加强文本中数据加强不太常见,这里咱们使用了shuffle和drop两种数据加强,前者打乱词顺序,后者随机的删除掉某些词。效果举例如图:
1.4 评价指标每一个预测样本,提供最有可能的五个话题标签,计算加权后的准确率和召回率,再计算F1值。注意准确率是加权累加的,意味着越靠前的正确预测对分数贡献越大,同时也意味着准确率可能高于1,可是F1值计算的时候分子没有乘以2,因此0.5是很难达到的。
2 模型介绍建议你们先阅读这篇文章,了解文本多分类问题几个经常使用模型:用深度学习(CNN RNN Attention)解决大规模文本分类问题 https://zhuanlan.zhihu.com/p/25928551
2.1 通用模型结构文本分类的模型不少,此次比赛中用到的模型基本上都遵循如下的架构:
![]()
基本思路就是,词(或者字)通过embedding层以后,利用CNN/RNN等结构,提取局部信息、全局信息或上下文信息,利用分类器进行分类,分类器的是由两层全链接层组成的。 在开始介绍每一个模型以前,这里先下几个结论:
2.2 TextCNN这是最经典的文本分类模型,这里就不细说了,模型架构以下图:
![]()
和原始的论文的区别就在于:
总之就是更深,更复杂。不过卷积核的尺寸设计的不够合理,致使感觉野差距过大。 2.3 TextRNN没找到论文,我就凭感受实现了一下:
![]()
相比于其余人的作法,这里的不一样点在于:
2.4 TextRCNN参考原论文的实现,和RNN相似,也是两层双向LSTM,可是须要和Embedding层的输出Concat(相似于resnet的shortcut直连)。
![]()
2.5 TextInception这个是我本身提出来的,参照TextCNN的思想(多尺度卷积核),模仿Inception的结构设计出来的,一层的Inception结构以下图所示,比赛中用了两层的Inception结构,最深有4层卷积,比TextCNN更深。
![]()
2.6 训练方法要点:
2.7 各个模型分数计算训练的时候,每一个模型要么只训练基于词(word)的模型,要么只训练基于字(char)的模型。各个模型的分数都差很少,这里再也不单独列出来了,只区分训练的模型的类型和数据加强与否。
![]()
能够看出来
2.8 模型融合像这种模型比较简单,数据量相对比较小的比赛,模型融合是比赛获胜的关键。 在这里,我只使用到了最简单的模型融合方法-----几率等权重融合。对于每一个样本,单模型会给出一个1999维的向量,表明着这个模型属于1999个话题的几率。融合的方式就是把每个模型输出的向量直接相加,而后选择几率最大的5个话题提交。结构如图所示:
![]()
下面咱们再来看看两个模型融合的分数:
![]()
第一列的对比模型采用的是RNN(不采用数据加强,使用word做为训练数据),第二列是四个不一样的模型(不一样的结构,或者是不一样的数据)。 咱们能够得出如下几个结论:
总结: 差别性越大,模型融合效果越好。没有差别性,创造条件也要制造差别性。 另外模型融合还有个规律:越往上越难提高,有些模型在你分数较低的时候,对融合提高很明显,当你分数较高的时候就没什么帮助,甚至会有干扰 2.9 MultiModel其实模型融合的方式,咱们换一种角度考虑,其实就是一个很大的模型,每个分支就像多通道的TextCNN同样。那么咱们能不能训练一个超级大的模型?答案是能够的,可是效果每每不好。由于模型过于复杂,太难以训练。这里我尝试了两种改进的方法。 第一种方法,利用预训练好的单模型初始化复杂模型的某一部分参数,模型架构如图所示:
![]()
可是这种作法会带来一个问题: 模型过拟合很严重,难以学习到新的东西。由于单模型在训练集上的分数都接近0.5,已经逼近理论上的极限分数,这时候很难接着学习到新的内容。这里采起的应对策略是采用较高的初始学习率,强行把模型从过拟合点拉出来,使得模型在训练集上的分数迅速下降到0.4左右,而后再下降学习率,缓慢学习,提高模型的分数。 第二种作法是修改预训练模型的embedding矩阵为官方给的embedding权重。这样共享embedding的作法,可以必定程度上抑制模型过拟合,减小参数量。虽然CNN/RNN等模型的参数过拟合,可是因为相对应的embedding没有过拟合,因此模型一开始分数就会降低许多,而后再缓慢提高。这种作法更优。在最后提交模型复现成绩的时候,我只提交了七个这种模型,里面包含着不一样子模型的组合,通常包含3-4个子模型。这种方式生成的权重文件也比较小(600M-700M左右),上传到网盘相对来讲更方便。
![]()
2.10 失败的模型或没什么用的方法MultiMode只是我诸多尝试的方法中比较成功的一个,其它方法大多以失败了结(或者效果不明显)
3 结束语我以前虽然学过CS224D的课程,也作了前两次的做业,可是除此以外几乎历来没写过天然语言处理相关的代码,能拿第一离不开队友的支持,和同窗们不断的激励。 此次比赛入门对我帮助最大的两篇文章是用深度学习(CNN RNN Attention)解决大规模文本分类问题 https://zhuanlan.zhihu.com/p/25928551 和deep-learning-nlp-best-practices http://ruder.io/deep-learning-nlp-best-practices/index.html 第一篇是北邮某学长(但我并不认识~)写的,介绍了许多文本分类的模型(CNN/RNN/RCNN),对我入门帮助很大。 第二篇是国外某博士写的,当时我已经把分数刷到前三,在家看到了这篇文章,叹为观止,解释了我不少的疑惑,提到的不少经验总结和个人状况也确实相符。https://zhuanlan.zhihu.com/p/28923961 |