文本分類是NLP的必備入門任務,在搜索、推薦、對話等場景中隨處可見,並有情感分析、新聞分類、標籤分類等成熟的研究分支和數據集。
本文主要介紹深度學習文本分類的常用模型原理、優缺點以及技巧。
P.S. 有基礎的同學可以直接看文末的技巧
Fasttext論文:https://arxiv.org/abs/1607.01759
代碼:https://github.com/facebookresearch/fastTextFasttext是Facebook推出的一個便捷的工具,包含文本分類和詞向量訓練兩個功能。
Fasttext的分類實現很簡單:把輸入轉化為詞向量,取平均,再經過線性分類器得到類別。輸入的詞向量可以是預先訓練好的,也可以隨機初始化,跟著分類任務一起訓練。
Fasttext直到現在還被不少人使用,主要有以下優點:
模型本身複雜度低,但效果不錯,能快速產生任務的baselineFacebook使用C++進行實現,進一步提升了計算效率採用了char-level的n-gram作為附加特徵,比如paper的trigram是 [pap, ape, per],在將輸入paper轉為向量的同時也會把trigram轉為向量一起參與計算。這樣一方面解決了長尾詞的OOV (out-of-vocabulary)問題,一方面利用n-gram特徵提升了表現當類別過多時,支持採用hierarchical softmax進行分類,提升效率對於文本長且對速度要求高的場景,Fasttext是baseline首選。同時用它在無監督語料上訓練詞向量,進行文本表示也不錯。不過想繼續提升效果還需要更複雜的模型。
TextCNN論文:https://arxiv.org/abs/1408.5882
代碼:https://github.com/yoonkim/CNN_sentenceTextCNN是Yoon Kim小哥在2014年提出的模型,開創了用CNN編碼n-gram特徵的先河。
模型結構如圖,圖像中的卷積都是二維的,而TextCNN則使用「一維卷積」,即filter_size * embedding_dim,有一個維度和embedding相等。這樣就能抽取filter_size個gram的信息。以1個樣本為例,整體的前向邏輯是:
對詞進行embedding,得到[seq_length, embedding_dim]用N個卷積核,得到N個seq_length-filter_size+1長度的一維feature map對feature map進行max-pooling(因為是時間維度的,也稱max-over-time pooling),得到N個1x1的數值,拼接成一個N維向量,作為文本的句子表示在TextCNN的實踐中,有很多地方可以優化(參考這篇論文[1]):
Filter尺寸:這個參數決定了抽取n-gram特徵的長度,這個參數主要跟數據有關,平均長度在50以內的話,用10以下就可以了,否則可以長一些。在調參時可以先用一個尺寸grid search,找到一個最優尺寸,然後嘗試最優尺寸和附近尺寸的組合Filter個數:這個參數會影響最終特徵的維度,維度太大的話訓練速度就會變慢。這裡在100-600之間調參即可CNN的激活函數:可以嘗試Identity、ReLU、tanh正則化:指對CNN參數的正則化,可以使用dropout或L2,但能起的作用很小,可以試下小的dropout率(<0.5),L2限制大一點Pooling方法:根據情況選擇mean、max、k-max pooling,大部分時候max表現就很好,因為分類任務對細粒度語義的要求不高,只抓住最大特徵就好了Embedding表:中文可以選擇char或word級別的輸入,也可以兩種都用,會提升些效果。如果訓練數據充足(10w+),也可以從頭訓練加深全連接:原論文只使用了一層全連接,而加到3、4層左右效果會更好[2]TextCNN是很適合中短文本場景的強baseline,但不太適合長文本,因為卷積核尺寸通常不會設很大,無法捕獲長距離特徵。同時max-pooling也存在局限,會丟掉一些有用特徵。另外再仔細想的話,TextCNN和傳統的n-gram詞袋模型本質是一樣的,它的好效果很大部分來自於詞向量的引入[3],因為解決了詞袋模型的稀疏性問題。
DPCNN論文:https://ai.tencent.com/ailab/media/publications/ACL3-Brady.pdf
代碼:https://github.com/649453932/Chinese-Text-Classification-Pytorch上面介紹TextCNN有太淺和長距離依賴的問題,那直接多懟幾層CNN是否可以呢?感興趣的同學可以試試,就會發現事情沒想像的那麼簡單。直到2017年,騰訊才提出了把TextCNN做到更深的DPCNN模型:
上圖中的ShallowCNN指TextCNN。DPCNN的核心改進如下:
在Region embedding時不採用CNN那樣加權卷積的做法,而是對n個詞進行pooling後再加個1x1的卷積,因為實驗下來效果差不多,且作者認為前者的表示能力更強,容易過擬合使用1/2池化層,用size=3 stride=2的卷積核,直接讓模型可編碼的sequence長度翻倍(自己在紙上畫一下就get啦)憑藉以上一些精妙的改進,DPCNN相比TextCNN有1-2個百分點的提升。
TextRCNN論文:https://dl.acm.org/doi/10.5555/2886521.2886636
代碼:https://github.com/649453932/Chinese-Text-Classification-Pytorch除了DPCNN那樣增加感受野的方式,RNN也可以緩解長距離依賴的問題。下面介紹一篇經典TextRCNN。
模型的前向過程是:
對多個