nlp大赛冠军总结
1. 比賽介紹
這是一個(gè)文本多分類的問題:目標(biāo)是“參賽者根據(jù)知乎給出的問題及話題標(biāo)簽的綁定關(guān)系的訓(xùn)練數(shù)據(jù),訓(xùn)練出對(duì)未標(biāo)注數(shù)據(jù)自動(dòng)標(biāo)注的模型”。通俗點(diǎn)講就是:當(dāng)用戶在知乎上提問題時(shí),程序要能夠根據(jù)問題的內(nèi)容自動(dòng)為其添加話題標(biāo)簽。一個(gè)問題可能對(duì)應(yīng)著多個(gè)話題標(biāo)簽,如下圖所示。
?
這是一個(gè)文本多分類,多l(xiāng)abel的分類問題(一個(gè)樣本可能屬于多個(gè)類別)。總共有300萬(wàn)條問題-話題對(duì),超過2億詞,4億字,共1999個(gè)類別。
1.1 數(shù)據(jù)介紹
參考?https://biendata.com/competition/zhihu/data/
https://biendata.com/competition/zhihu/rules/?next_url=%2Fcompetition%2Fzhihu%2Fdata%2F
?
總的來(lái)說就是:
-
數(shù)據(jù)經(jīng)過脫敏處理,看到的不是“如何評(píng)價(jià)2017知乎看山杯機(jī)器學(xué)習(xí)比賽”,而是“w2w34w234w54w909w2343w1"這種經(jīng)過映射的詞的形式,或者是”c13c44c4c5642c782c934c02c2309c42c13c234c97c8425c98c4c340"這種經(jīng)過映射的字的形式。
-
因?yàn)樵~和字經(jīng)過脫敏處理,所以無(wú)法使用第三方的詞向量,官方特地提供了預(yù)訓(xùn)練好的詞向量,即char_embedding.txt和word_embedding.txt ,都是256 維。
-
主辦方提供了1999個(gè)類別的描述和類別之間的父子關(guān)系(比如機(jī)器學(xué)習(xí)的父話題是人工智能,統(tǒng)計(jì)學(xué)和計(jì)算機(jī)科學(xué)),但這個(gè)知識(shí)沒有用上。
-
訓(xùn)練集包含300萬(wàn)條問題的標(biāo)題(title),問題的描述(description)和問題的話題(topic)
-
測(cè)試集包含21萬(wàn)條問題的標(biāo)題(title),問題的描述(description),需要給出最有可能的5個(gè)話題(topic)
1.2 數(shù)據(jù)處理
數(shù)據(jù)處理主要包括兩部分:
-
char_embedding.txt 和 word_embedding.txt 轉(zhuǎn)為numpy格式,這個(gè)很簡(jiǎn)單,直接使用word2vec的python工具即可
-
對(duì)于不同長(zhǎng)度的問題文本,pad和截?cái)喑梢粯娱L(zhǎng)度的(利用pad_sequence 函數(shù),也可以自己寫代碼pad)。太短的就補(bǔ)空格,太長(zhǎng)的就截?cái)唷2僮鲌D示如下:
?
1.3 數(shù)據(jù)增強(qiáng)
文本中數(shù)據(jù)增強(qiáng)不太常見,這里我們使用了shuffle和drop兩種數(shù)據(jù)增強(qiáng),前者打亂詞順序,后者隨機(jī)的刪除掉某些詞。效果舉例如圖:
?
1.4 評(píng)價(jià)指標(biāo)
每個(gè)預(yù)測(cè)樣本,提供最有可能的五個(gè)話題標(biāo)簽,計(jì)算加權(quán)后的準(zhǔn)確率和召回率,再計(jì)算F1值。注意準(zhǔn)確率是加權(quán)累加的,意味著越靠前的正確預(yù)測(cè)對(duì)分?jǐn)?shù)貢獻(xiàn)越大,同時(shí)也意味著準(zhǔn)確率可能高于1,但是F1值計(jì)算的時(shí)候分子沒有乘以2,所以0.5是很難達(dá)到的。
?
?
2 模型介紹
建議大家先閱讀這篇文章,了解文本多分類問題幾個(gè)常用模型:用深度學(xué)習(xí)(CNN RNN Attention)解決大規(guī)模文本分類問題
https://zhuanlan.zhihu.com/p/25928551
?
2.1 通用模型結(jié)構(gòu)
文本分類的模型很多,這次比賽中用到的模型基本上都遵循以下的架構(gòu):
?
基本思路就是,詞(或者字)經(jīng)過embedding層之后,利用CNN/RNN等結(jié)構(gòu),提取局部信息、全局信息或上下文信息,利用分類器進(jìn)行分類,分類器的是由兩層全連接層組成的。
在開始介紹每個(gè)模型之前,這里先下幾個(gè)結(jié)論:
如果你的模型分?jǐn)?shù)不夠高,試著把模型變得更深更寬更復(fù)雜
當(dāng)模型復(fù)雜到一定程度的時(shí)候,不同模型的分?jǐn)?shù)差距很小
當(dāng)模型復(fù)雜達(dá)到一定程度,繼續(xù)變復(fù)雜難以繼續(xù)提升模型的分?jǐn)?shù)
?
2.2 TextCNN
這是最經(jīng)典的文本分類模型,這里就不細(xì)說了,模型架構(gòu)如下圖:
?
?
?
?
?
和原始的論文的區(qū)別就在于:
-
使用兩層卷積
-
使用更多的卷積核,更多尺度的卷積核
-
使用了BatchNorm
-
分類的時(shí)候使用了兩層的全連接
總之就是更深,更復(fù)雜。不過卷積核的尺寸設(shè)計(jì)的不夠合理,導(dǎo)致感受野差距過大。
2.3 TextRNN
沒找到論文,我就憑感覺實(shí)現(xiàn)了一下:
?
相比于其他人的做法,這里的不同點(diǎn)在于:
-
使用了兩層的雙向LSTM。
-
分類的時(shí)候不是只使用最后一個(gè)隱藏元的輸出,而是把所有隱藏元的輸出做K-MaxPooling再分類。
2.4 TextRCNN
參考原論文的實(shí)現(xiàn),和RNN類似,也是兩層雙向LSTM,但是需要和Embedding層的輸出Concat(類似于resnet的shortcut直連)。
?
2.5 TextInception
這個(gè)是我自己提出來(lái)的,參照TextCNN的思想(多尺度卷積核),模仿Inception的結(jié)構(gòu)設(shè)計(jì)出來(lái)的,一層的Inception結(jié)構(gòu)如下圖所示,比賽中用了兩層的Inception結(jié)構(gòu),最深有4層卷積,比TextCNN更深。
?
2.6 訓(xùn)練方法
要點(diǎn):
-
基于詞和基于字的模型要分開訓(xùn),然后融合,一起訓(xùn)的效果不好
-
使用官方給的word-embedding.txt和char-embedding.txt初始化Embedding層的權(quán)重
-
剛開始訓(xùn)練的時(shí)候Embedding層的學(xué)習(xí)率為0,其它層的學(xué)習(xí)率為1e-3,采用Adam優(yōu)化器(一開始的時(shí)候卷積層都是隨機(jī)初始化的,反向傳播得到的Embedding層的梯度受到卷積層的影響,相當(dāng)于噪聲)
-
訓(xùn)練1-2個(gè)epoch之后,Embedding層的學(xué)習(xí)率設(shè)為2e-4
-
每個(gè)epoch或者半個(gè)epoch統(tǒng)計(jì)一次在驗(yàn)證集的分?jǐn)?shù)
-
如果分?jǐn)?shù)上升,保存模型,并記下保存路徑
-
如果分?jǐn)?shù)下降,加載上一個(gè)模型的保存路徑,并降低學(xué)習(xí)率為一半(重新初始化優(yōu)化器,清空動(dòng)量信息,而不是只修改學(xué)習(xí)率----使用PyTorch的話新建一個(gè)新優(yōu)化器即可)
-
2.7 各個(gè)模型分?jǐn)?shù)計(jì)算
訓(xùn)練的時(shí)候,每個(gè)模型要么只訓(xùn)練基于詞(word)的模型,要么只訓(xùn)練基于字(char)的模型。各個(gè)模型的分?jǐn)?shù)都差不多,這里不再單獨(dú)列出來(lái)了,只區(qū)分訓(xùn)練的模型的類型和數(shù)據(jù)增強(qiáng)與否。
?
可以看出來(lái)
-
基于詞的模型效果遠(yuǎn)遠(yuǎn)好于基于字的(說明中文分詞很有必要)。
-
數(shù)據(jù)增強(qiáng)對(duì)基于詞(word)的模型有一定的提升,但是對(duì)于基于字(char)的模型主要是起到副作用。
-
各個(gè)模型之間的分?jǐn)?shù)差距不大。
?
2.8 模型融合
像這種模型比較簡(jiǎn)單,數(shù)據(jù)量相對(duì)比較小的比賽,模型融合是比賽獲勝的關(guān)鍵。
在這里,我只使用到了最簡(jiǎn)單的模型融合方法-----概率等權(quán)重融合。對(duì)于每個(gè)樣本,單模型會(huì)給出一個(gè)1999維的向量,代表著這個(gè)模型屬于1999個(gè)話題的概率。融合的方式就是把每一個(gè)模型輸出的向量直接相加,然后選擇概率最大的5個(gè)話題提交。結(jié)構(gòu)如圖所示:
?
下面我們?cè)賮?lái)看看兩個(gè)模型融合的分?jǐn)?shù):
?
?
第一列的對(duì)比模型采用的是RNN(不采用數(shù)據(jù)增強(qiáng),使用word作為訓(xùn)練數(shù)據(jù)),第二列是四個(gè)不同的模型(不同的結(jié)構(gòu),或者是不同的數(shù)據(jù))。
我們可以得出以下幾個(gè)結(jié)論:
-
從第一行和第二行的對(duì)比之中我們可以看出,模型差異越大提升越多(RNN和RCNN比較相似,因?yàn)樗麄兊讓佣疾捎昧穗p向LSTM提取特征),雖然RCNN的分?jǐn)?shù)比Inception要高,Inception對(duì)模型融合的提升更大。
-
從第一行和第四行的對(duì)比之中我們可以看出,數(shù)據(jù)的差異越大,融合的提升越多,雖然基于字(char)訓(xùn)練的模型分?jǐn)?shù)比較低,但是和基于詞訓(xùn)練的模型進(jìn)行融合,還是能有極大的提升。
-
采用數(shù)據(jù)增強(qiáng),有助于提升數(shù)據(jù)的差異性,對(duì)模型融合的提升幫助也很大。
總結(jié):?差異性越大,模型融合效果越好。沒有差異性,創(chuàng)造條件也要制造差異性。
另外模型融合還有個(gè)規(guī)律:越往上越難提升,有些模型在你分?jǐn)?shù)較低的時(shí)候,對(duì)融合提升很明顯,當(dāng)你分?jǐn)?shù)較高的時(shí)候就沒什么幫助,甚至?xí)懈蓴_
2.9 MultiModel
其實(shí)模型融合的方式,我們換一種角度考慮,其實(shí)就是一個(gè)很大的模型,每一個(gè)分支就像多通道的TextCNN一樣。那么我們能不能訓(xùn)練一個(gè)超級(jí)大的模型?答案是可以的,但是效果往往很差。因?yàn)槟P瓦^于復(fù)雜,太難以訓(xùn)練。這里我嘗試了兩種改進(jìn)的方法。
第一種方法,利用預(yù)訓(xùn)練好的單模型初始化復(fù)雜模型的某一部分參數(shù),模型架構(gòu)如圖所示:
?
但是這種做法會(huì)帶來(lái)一個(gè)問題: 模型過擬合很嚴(yán)重,難以學(xué)習(xí)到新的東西。因?yàn)閱文P驮谟?xùn)練集上的分?jǐn)?shù)都接近0.5,已經(jīng)逼近理論上的極限分?jǐn)?shù),這時(shí)候很難接著學(xué)習(xí)到新的內(nèi)容。這里采取的應(yīng)對(duì)策略是采用較高的初始學(xué)習(xí)率,強(qiáng)行把模型從過擬合點(diǎn)拉出來(lái),使得模型在訓(xùn)練集上的分?jǐn)?shù)迅速降低到0.4左右,然后再降低學(xué)習(xí)率,緩慢學(xué)習(xí),提升模型的分?jǐn)?shù)。
第二種做法是修改預(yù)訓(xùn)練模型的embedding矩陣為官方給的embedding權(quán)重。這樣共享embedding的做法,能夠一定程度上抑制模型過擬合,減少參數(shù)量。雖然CNN/RNN等模型的參數(shù)過擬合,但是由于相對(duì)應(yīng)的embedding沒有過擬合,所以模型一開始分?jǐn)?shù)就會(huì)下降許多,然后再緩慢提升。這種做法更優(yōu)。在最后提交模型復(fù)現(xiàn)成績(jī)的時(shí)候,我只提交了七個(gè)這種模型,里面包含著不同子模型的組合,一般包含3-4個(gè)子模型。這種方式生成的權(quán)重文件也比較小(600M-700M左右),上傳到網(wǎng)盤相對(duì)來(lái)說更方便。
?
2.10 失敗的模型或沒什么用的方法
MultiMode只是我諸多嘗試的方法中比較成功的一個(gè),其它方法大多以失敗告終(或者效果不明顯)
-
數(shù)據(jù)多折訓(xùn)練:因?yàn)檫^擬合嚴(yán)重,想著先拿一半數(shù)據(jù)訓(xùn),允許它充分過擬合,然后再拿另外一半數(shù)據(jù)訓(xùn)。效果不如之前的模型。
-
Attention Stack,參考了這篇文章,其實(shí)本質(zhì)上相當(dāng)于調(diào)權(quán)重,但是效果有限,還麻煩,所以最后直接用等權(quán)重融合(權(quán)重全設(shè)為1)。
?
-
Stack,太費(fèi)時(shí)費(fèi)力,浪費(fèi)了不少時(shí)間,也有可能是實(shí)現(xiàn)有誤,提升有限,沒有繼續(xù)研究下去。
-
Boost,和第二名Koala的方法很像,先訓(xùn)一個(gè)模型,然后再訓(xùn)第二個(gè)模型和第一個(gè)模型的輸出相加,但是固定第一個(gè)模型的參數(shù)。相當(dāng)于不停的修正上一個(gè)模型誤判的(可以嘗試計(jì)算一下梯度,你會(huì)發(fā)現(xiàn)第一個(gè)模型已經(jīng)判對(duì)的樣本,即使第二個(gè)模型判別錯(cuò)了,第二個(gè)模型的梯度也不會(huì)很大,即第二個(gè)模型不會(huì)花費(fèi)太多時(shí)間學(xué)習(xí)這個(gè)樣本)。但是效果不好,原因:過擬合很嚴(yán)重,第一個(gè)模型在訓(xùn)練集上的分?jǐn)?shù)直接就逼近0.5,導(dǎo)致第二個(gè)模型什么都沒學(xué)到。Koala隊(duì)伍最終就是憑借著這個(gè)Boost模型拿到了第二名,我過早放棄,沒能在這個(gè)方法上有所突破十分遺憾。
-
TTA(測(cè)試時(shí)數(shù)據(jù)增強(qiáng)),相當(dāng)于在測(cè)試的時(shí)候人為的制造差異性,對(duì)單模型的效果一般,對(duì)融合幾乎沒有幫助。
-
Hyperopt進(jìn)行超參數(shù)查詢,主要用來(lái)查詢模型融合的權(quán)重,效果一般,最后就也沒有使用了,就手動(dòng)稍微調(diào)了一下。
-
label設(shè)權(quán)重,對(duì)于正樣本給予更高的權(quán)重,訓(xùn)練模型,然后和正常權(quán)重的模型進(jìn)行融合,在單模型上能夠提升2-3個(gè)千分點(diǎn)(十分巨大),但是在最后的模型融合是效果很有限(0.0002),而且需要調(diào)整權(quán)重比較麻煩,遂舍棄。
-
用分類得到的詞向量作為下一個(gè)模型的embedding的初始值,因?yàn)楣俜浇o的word embedding是用無(wú)監(jiān)督的word2vec訓(xùn)練的,和有監(jiān)督的分類問題還是有一定偏差的。沒有深入研究下去,對(duì)單模型應(yīng)該是有提升,但是對(duì)融合可能沒什么幫助。
3 結(jié)束語(yǔ)
我之前雖然學(xué)過CS224D的課程,也做了前兩次的作業(yè),但是除此之外幾乎從來(lái)沒寫過自然語(yǔ)言處理相關(guān)的代碼,能拿第一離不開隊(duì)友的支持,和同學(xué)們不斷的激勵(lì)。
這次比賽入門對(duì)我?guī)椭畲蟮膬善恼率怯蒙疃葘W(xué)習(xí)(CNN RNN Attention)解決大規(guī)模文本分類問題
https://zhuanlan.zhihu.com/p/25928551
和deep-learning-nlp-best-practices
http://ruder.io/deep-learning-nlp-best-practices/index.html
第一篇是北郵某學(xué)長(zhǎng)(但我并不認(rèn)識(shí)~)寫的,介紹了許多文本分類的模型(CNN/RNN/RCNN),對(duì)我入門幫助很大。
第二篇是國(guó)外某博士寫的,當(dāng)時(shí)我已經(jīng)把分?jǐn)?shù)刷到前三,在家看到了這篇文章,嘆為觀止,解釋了我很多的疑惑,提到的很多經(jīng)驗(yàn)總結(jié)和我的情況也確實(shí)相符。https://zhuanlan.zhihu.com/p/28923961
總結(jié)
- 上一篇: 基于朴素贝叶斯的垃圾邮件分类-着重理解拉
- 下一篇: vim编码规则