知乎 “看山杯” 夺冠记

知乎看山杯夺冠记

比赛源码(PyTorch 实现)github 地址 https://github.com/chenyuntc/PyTorchText
比赛官网: https://biendata.com/competition/zhihu/
比赛结果官方通告: https://zhuanlan.zhihu.com/p/28912353

七月,酷暑难耐,认识的几位同学参加知乎看山杯,均取得不错的排名。当时天池 AI 医疗大赛初赛结束,官方正在为复赛进行平台调试,复赛时间一拖再拖。看着几位同学在比赛中排名都还很不错,于是决定抽空试一试。结果一发不可收拾,又找了两个同学一起组队(队伍 init)以至于整个暑假都投入到这个比赛之中,并最终以一定的优势夺得第一名(参见最终排名 )。

1. 比赛介绍

这是一个文本多分类的问题:目标是 “参赛者根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出对未标注数据自动标注的模型”。通俗点讲就是:当用户在知乎上提问题时,程序要能够根据问题的内容自动为其添加话题标签。一个问题可能对应着多个话题标签,如下图所示。

这是一个文本多分类,多 label 的分类问题(一个样本可能属于多个类别)。总共有 300 万条问题 - 话题对,超过 2 亿词,4 亿字,共 1999 个类别。

1.1 数据介绍

参考 https://biendata.com/competition/zhihu/data/

总的来说就是:

  • 数据经过脱敏处理,看到的不是 “如何评价 2017 知乎看山杯机器学习比赛”,而是 “w2w34w234w54w909w2343w1"这种经过映射的词的形式,或者是”c13c44c4c5642c782c934c02c2309c42c13c234c97c8425c98c4c340" 这种经过映射的字的形式。
  • 因为词和字经过脱敏处理,所以无法使用第三方的词向量,官方特地提供了预训练好的词向量,即 char_embedding.txt 和 word_embedding.txt ,都是 256 维。
  • 主办方提供了 1999 个类别的描述和类别之间的父子关系(比如机器学习的父话题是人工智能,统计学和计算机科学),但这个知识没有用上。
  • 训练集包含 300 万条问题的标题(title),问题的描述(description)和问题的话题(topic)
  • 测试集包含 21 万条问题的标题(title), 问题的描述 (description),需要给出最有可能的 5 个话题(topic)

1.2 数据处理

数据处理主要包括两部分:

  • char_embedding.txt 和 word_embedding.txt 转为 numpy 格式,这个很简单,直接使用 word2vec 的 python 工具即可
  • 对于不同长度的问题文本,pad 和截断成一样长度的(利用 pad_sequence 函数,也可以自己写代码 pad)。太短的就补空格,太长的就截断。操作图示如下:

1.3 数据增强

文本中数据增强不太常见,这里我们使用了 shuffle 和 drop 两种数据增强,前者打乱词顺序,后者随机的删除掉某些词。效果举例如图:

1.4 评价指标

每个预测样本,提供最有可能的五个话题标签,计算加权后的准确率和召回率,再计算 F1 值。注意准确率是加权累加的,意味着越靠前的正确预测对分数贡献越大,同时也意味着准确率可能高于 1,但是 F1 值计算的时候分子没有乘以 2,所以 0.5 是很难达到的。

具体评价指标说明请参照

https://biendata.com/competition/zhihu/evaluation/

2 模型介绍

建议大家先阅读这篇文章,了解文本多分类问题几个常用模型:用深度学习(CNN RNN Attention)解决大规模文本分类问题

2.1 通用模型结构

文本分类的模型很多,这次比赛中用到的模型基本上都遵循以下的架构:

基本思路就是,词(或者字)经过 embedding 层之后,利用 CNN/RNN 等结构,提取局部信息、全局信息或上下文信息,利用分类器进行分类,分类器的是由两层全连接层组成的。

在开始介绍每个模型之前,这里先下个结论:

当模型复杂到一定程度的时候,不同模型的分数差距很小!

2.2 TextCNN

这是最经典的文本分类模型,这里就不细说了,模型架构如下图:

和原始的论文的区别就在于:

  • 使用两层卷积
  • 使用更多的卷积核,更多尺度的卷积核
  • 使用了 BatchNorm
  • 分类的时候使用了两层的全连接

总之就是更深,更复杂。不过卷积核的尺寸设计的不够合理,导致感受野差距过大。

2.3 TextRNN

没找到论文,我就凭感觉实现了一下:

相比于其他人的做法,这里的不同点在于:

  • 使用了两层的双向 LSTM。
  • 分类的时候不是只使用最后一个隐藏元的输出,而是把所有隐藏元的输出做 K-MaxPooling 再分类。

2.4 TextRCNN

参考原论文的实现,和 RNN 类似,也是两层双向 LSTM,但是需要和 Embedding 层的输出 Concat(类似于 resnet 的 shortcut 直连)。

2.5 TextInception

这个是我自己提出来的,参照 TextCNN 的思想(多尺度卷积核),模仿 Inception 的结构设计出来的,一层的 Inception 结构如下图所示,比赛中用了两层的 Inception 结构,最深有 4 层卷积,比 TextCNN 更深。

2.6 各个模型分数计算

训练的时候,每个模型要么只训练基于词(word)的模型,要么只训练基于字(char)的模型。各个模型的分数都差不多,这里不再单独列出来了,只区分训练的模型的类型和数据增强与否。

可以看出来

  • 基于词的模型效果远远好于基于字的(说明中文分词很有必要)。
  • 数据增强对基于词(word)的模型有一定的提升,但是对于基于字(char)的模型主要是起到副作用。
  • 各个模型之间的分数差距不大。

2.7 模型融合

像这种模型比较简单,数据量相对比较小的比赛,模型融合是比赛获胜的关键。

在这里,我只使用到了最简单的模型融合方法 ----- 概率等权重融合。对于每个样本,单模型会给出一个 1999 维的向量,代表着这个模型属于 1999 个话题的概率。融合的方式就是把每一个模型输出的向量直接相加,然后选择概率最大的 5 个话题提交。结构如图所示:

下面我们再来看看两个模型融合的分数:

第一列的对比模型采用的是 RNN(不采用数据增强,使用 word 作为训练数据),第二列是四个不同的模型(不同的结构,或者是不同的数据)。

我们可以得出以下几个结论:

  • 从第一行和第二行的对比之中我们可以看出,模型差异越大提升越多(RNN 和 RCNN 比较相似,因为他们底层都采用了双向 LSTM 提取特征),虽然 RCNN 的分数比 Inception 要高,Inception 对模型融合的提升更大。
  • 从第一行和第四行的对比之中我们可以看出,数据的差异越大,融合的提升越多,虽然基于字(char)训练的模型分数比较低,但是和基于词训练的模型进行融合,还是能有极大的提升。
  • 采用数据增强,有助于提升数据的差异性,对模型融合的提升帮助也很大。

总结: 差异性越大,模型融合效果越好。没有差异性,创造条件也要制造差异性。

2.8 MultiModel

其实模型融合的方式,我们换一种角度考虑,其实就是一个很大的模型,每一个分支就像多通道的 TextCNN 一样。那么我们能不能训练一个超级大的模型?答案是可以的,但是效果往往很差。因为模型过于复杂,太难以训练。这里我尝试了两种改进的方法。

第一种方法,利用预训练好的单模型初始化复杂模型的某一部分参数,模型架构如图所示:

但是这种做法会带来一个问题: 模型过拟合很严重,难以学习到新的东西。因为单模型在训练集上的分数都接近 0.5,已经逼近理论上的极限分数,这时候很难接着学习到新的内容。这里采取的应对策略是采用较高的初始学习率,强行把模型从过拟合点拉出来,使得模型在训练集上的分数迅速降低到 0.4 左右,然后再降低学习率,缓慢学习,提升模型的分数。

第二种做法是修改预训练模型的 embedding 矩阵为官方给的 embedding 权重。这样共享 embedding 的做法,能够一定程度上抑制模型过拟合,减少参数量。虽然 CNN/RNN 等模型的参数过拟合,但是由于相对应的 embedding 没有过拟合,所以模型一开始分数就会下降许多,然后再缓慢提升。这种做法更优。在最后提交模型复现成绩的时候,我只提交了七个这种模型,里面包含着不同子模型的组合,一般包含 3-4 个子模型。这种方式生成的权重文件也比较小(600M-700M 左右),上传到网盘相对来说更方便。

2.9 失败的模型和方法

MultiMode 只是我诸多尝试的方法中比较成功的一个,其它方法大多以失败告终(或者效果不明显)

  • 数据多折训练:因为过拟合严重,想着先拿一半数据训,允许它充分过拟合,然后再拿另外一半数据训。效果不如之前的模型。
  • Attention Stack,参考了这篇文章,其实本质上相当于调权重,但是效果有限,还麻烦,所以最后直接用等权重融合(权重全设为 1)。
  • Stack,太费时费力,浪费了不少时间,也有可能是实现有误,提升有限,没有继续研究下去。
  • Boost,和第二名 Koala 的方法很像,先训一个模型,然后再训第二个模型和第一个模型的输出相加,但是固定第一个模型的参数。相当于不停的修正上一个模型误判的 (可以尝试计算一下梯度,你会发现第一个模型已经判对的样本,即使第二个模型判别错了,第二个模型的梯度也不会很大,即第二个模型不会花费太多时间学习这个样本)。但是效果不好,原因:过拟合很严重,第一个模型在训练集上的分数直接就逼近 0.5,导致第二个模型什么都没学到。Koala 队伍最终就是凭借着这个 Boost 模型拿到了第二名,我过早放弃,没能在这个方法上有所突破十分遗憾。
  • TTA(测试时数据增强),相当于在测试的时候人为的制造差异性,对单模型的效果一般,对融合几乎没有帮助。
  • Hyperopt 进行超参数查询,主要用来查询模型融合的权重,效果一般,最后就也没有使用了,就手动稍微调了一下。
  • label 设权重,对于正样本给予更高的权重,训练模型,然后和正常权重的模型进行融合,在单模型上能够提升 2-3 个千分点(十分巨大),但是在最后的模型融合是效果很有限(0.0002),而且需要调整权重比较麻烦,遂舍弃。

3 结束语

我之前虽然学过 CS224D 的课程,也做了前两次的作业,但是除此之外几乎从来没写过自然语言处理相关的代码,能拿第一离不开队友的支持,和同学们不断的激励。

这次比赛入门对我帮助最大的两篇文章是用深度学习(CNN RNN Attention)解决大规模文本分类问题和 deep-learning-nlp-best-practices

第一篇是北邮某学长(但我并不认识~)写的,介绍了许多文本分类的模型(CNN/RNN/RCNN),对我入门帮助很大。

第二篇是国外某博士写的,当时我已经把分数刷到前三,在家看到了这篇文章,叹为观止,解释了我很多的疑惑,提到的很多经验总结和我的情况也确实相符。

P.S. 为什么队伍名叫 init? 因为git init,linux init,python __init__  。我最喜欢的三个工具。而且pidof init is 1.

P.S. 欢迎报考北邮模式识别实验室

最后的最后:人生苦短,快用 PyTorch!

本文作者:AI研习社

本文转自雷锋网禁止二次转载,原文链接

时间: 2017-10-24

知乎 “看山杯” 夺冠记的相关文章

2017 知乎看山杯从入门到第二

利用一个暑假的时间,做了研究生生涯中的第一个正式比赛,最终排名第二,有些小遗憾,但收获更多的是成长和经验.我们之前没有参加过机器学习和文本相关的比赛,只是学过一些理论基础知识,没有付诸过实践,看过的几篇论文也多亏前辈的分享(一个是用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践,另一个是 brightmart 的 text_classification,里面用 Keras 实现了很多文本分类的模型).这些为我们的入门打下了良好的基础,在比赛过程中也是反复研读

雪花啤酒未过保质期现"霉花"引看欧洲杯球迷呕吐

市民展示有悬浮物的问题啤酒. 市民展示有悬浮物的问题啤酒. 这瓶雪花长霉 青岛啤酒公司向消费者表示歉意,并表示会立即对此事展开调查,将在最近两天给消费者一个答复. 雪花啤酒公司工作人员在向负责人请示过后表示,既然事情发生,该咋办就咋办. 6月12日,自贡市民李先生喝啤酒时,突然发现酒杯中出现了一片黏糊糊的漂浮物,随后李先生和经销商与啤酒生产商雪花公司进行了交涉.然而过了一天,雪花公司没有给出任何答复. 吃惊:雪花出现了"霉花" 6月12日中午12点10分,李先生和几名好友在自贡市汇东区

看欧洲杯精彩赛事 用Windows 7录播留住经典

欧洲杯火热开幕,众多足球粉丝怎么能错过如此精彩的比赛,但是很悲剧的是,欧洲杯都是晚上凌晨直播,由于很多人第二天要上班, 所以不能欣赏到精彩的球赛了,于是有人会想,能不能有一个方法既可以让我看足球,又不会耽误我们正常的工作和学习呢?答案当然是 "有",答案就在Win7里.原来Win7自带的Windows Media Center中心有一个叫电视录制功能,他可以很好的解决这个问题,可以将Win7 接入家里的电视机上,你就可以将直播的欧洲杯录制到你的Win7当中,你甚至可以提前制定录制计划,

看欧洲杯精彩赛事用Win7录播留住经典

欧洲杯火热开幕,众多足球粉丝怎么能错过如此精彩的比赛,但是很悲剧的是,欧洲杯都是晚上凌晨直播,由于很多人第二天要上班,所以不能欣赏到精彩的球赛了,于是有人会想,能不能有一个方法既可以让我看足球,又不会耽误我们正常的工作和学习呢?答案当然是"有",答案就在Win7里.原来Win7自带的Windows Media Center中心有一个叫电视录制功能,他可以很好的解决这个问题,可以将Win7接入家里的电视机上,你就可以将直播的欧洲杯录制到你的Win7当中,你甚至可以提前制定录制计划,或者采

谁是欧洲杯夺冠热门球队 德国居榜首英格兰垫底

这几天,激战正酣的欧洲杯成为了办公室里的热门话题.在小组赛结束后,16支晋级球队已经产生.而在被淘汰的球队中,由伊布拉希莫维奇率领的瑞典队未能出线最为让人惋惜.不过总体来看,这届欧洲杯可谓波澜不惊,传统强队都通过了小组赛的考验.而在淘汰赛阶段,下半区强队林立的局面也让冠军的归属提前成为了球迷们关注的焦点. 在互联网时代,真实的数据最能反映出用户对一件事的态度或声音.欧洲杯期间由神马搜索推出的投票活动你支持哪只球队夺冠中,德国队作为巴西世界杯的冠军自然成为了广大球迷心中支持率最高的球队.而西班牙.

完爆华为喵王, 看山那边P520揭幕而来!

随着手机,ipad等智能产品的飞速增长以及3G网络的普及,网络飞速发展的今天.缺电.缺wifi已成共识.面对这巨大的市场需求,许多厂商纷至沓来逐一推出自己的新产品,品质参差不齐,整体实际使用体验差,面对这一乱象,山那边科技早在今年10月份就曾呼吁业界本着行业有序健康发展,造福大众为主题发表过一篇文章. 3G移动电源浅析_百度文库 http://wenku.baidu.com/view/50174c6c33687e21af45a981.html 山那边科技 华为企业虽然是wifi移动电源的后来者,

300万知乎多标签文本分类任务经验分享(附源码)

七月,酷暑难耐,认识的几位同学参加知乎看山杯,均取得不错的排名.当时天池AI医疗大赛初赛结束,官方正在为复赛进行平台调试,复赛时间一拖再拖.看着几位同学在比赛中排名都还很不错,于是决定抽空试一试.结果一发不可收拾,又找了两个同学一起组队(队伍init)以至于整个暑假都投入到这个比赛之中,并最终以一定的优势夺得第一名. 比赛介绍 这是一个文本多分类的问题:目标是"参赛者根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出对未标注数据自动标注的模型".通俗点讲就是:当用户在知乎上提问题

【天池直播】机器学习平台赛经验分享

近年来随着机器学习慢慢进入企业,越来越多的算法需要与生产环境接轨,各大数据比赛平台也开始重视平台赛项目. 本次邀请的嘉宾会分享一些算法在工业级应用上的迁移方式,以及平台赛的经验. 直播主题:机器学习平台赛经验分享 直播时间:12月14日 20:30 直播链接:点击跳转 直播嘉宾: 应缜哲 天池昵称:bird827 bird,西安交通大学硕士,大数据仓库高级工程师.熟悉机器学习算法并多次参与国内外数据竞赛,同时擅长工程算法实现及建模. 曾获得2017滴滴DiTech无人驾驶大赛冠军.2017 Da

【看了流泪】一个母亲一生撒的8个谎言_经典网摘

                1.儿时,小男孩家很穷,吃饭时,饭常常不够吃,母亲就把自己碗里的饭分给孩子吃.母亲说,孩子们,快吃吧,我不饿!--母亲撒的第一个谎            2.男孩长身体的时候,勤劳的母亲常用周日休息时间去县郊农村河沟里捞些鱼来给孩子们补钙.鱼很好吃,鱼汤也很鲜.孩子们吃鱼的时候,母亲就在一旁啃鱼骨头,用舌头舔鱼骨头上的肉渍.男孩心疼,就把自己碗里的鱼夹到母亲碗里,请母亲吃鱼.母亲不吃,母亲又用筷子把鱼夹回男孩的碗里.母亲说,孩子,快吃吧,我不爱吃鱼!--母亲撒的第