天天看點

深度學習與文本分類總結

轉自:https://blog.csdn.net/liuchonge/article/details/77140719

https://blog.csdn.net/liuchonge/article/details/77585222

前面一段時間一直忙着參加知乎看山杯機器學習挑戰賽,現在比賽結束了想着總結一下最近的收獲。因為這是一個多标簽多類别的文本分類問題,而且題目非常适合用深度學習相關的知識去做,正好結合着這個競賽把之前一段時間的學習成果檢驗一下。接下來我會分成常用模型總結、多标簽/多類别專題、競賽實戰三部分進行介紹。 

首先我們先來總結一下文本分類中常用的幾個深度學習模型,這裡可以參考brightsmart大神在github上面開源出來的代碼,自己在做競賽的時候也進行了參考,收獲很大,下面我也會部分引用其代碼來闡述。他給出了幾乎可以用于文本分類的所有基礎模型及相關代碼實作(基于TensorFlow),是一份很棒的總結!接下來我們詳細的介紹一下每個模型的原理。

FastText

正好最近做商品分類的時候用到這個模型,了解了一下,是facebook在2016年提出來的模型,代碼可以直接使用這裡的。這個模型其實算不上深度學習,他跟word2vec的模型極其相似,即輸入層是文本中的單詞,然後經過一個嵌入層将單詞轉化為詞向量,接下來對文本中所有的詞進行求平均的操作得到一個文本的向量,然後再經過一個輸出層映射到所有類别中,可以參考Bag of Tricks for Efficient Text Classification這篇論文,裡面還詳細論述了如何使用n-gram feature考慮單詞的順序關系,以及如何使用Hierarchical softmax機制加速softmax函數的計算速度。模型的原理圖如下所示: 

深度學習與文本分類總結
  1. 這種模型的優點在于簡單,無論訓練還是預測的速度都很快,比其他深度學習模型高了幾個量級
  2. 缺點是模型過于簡單,準确度較低。(但是我聽說有人隻用這個模型競賽裡就做到了0.4的準确度,很厲害)

這裡想說的是很多公司的實際場景裡面,他們的資料并不像我們平時跑實驗那麼完美,各種人工标注,資料量也很大等等,很多應用的資料量又小、又很雜亂、甚至還沒有标記==,是以那些深度學習的模型并不一定能派上很大的用場,反而這種簡單快速的模型用的很多。這裡也可以看一下其模型建構部分的代碼,真的很簡單: 

深度學習與文本分類總結

TextCNN

這個模型我們就不再贅述了,放張圖鎮樓。很經典想要了解的可以戳下面幾個連結: 

深度學習與文本分類總結
  1. 論文Convolutional Neural Networks for Sentence Classification
  2. 我寫的對模型架構的了解
  3. dennybritz使用TensorFlow實作的代碼
  4. 我寫的分析上面代碼的部落格

TextRNN

這種模型與TextCNN很像,隻不過是把上面的Conv+Pooling替換成了Bi-LSTM,最後将兩個方向上的輸出進行拼接再傳給輸出層即可。但是這種模型僅僅是對TextCNN應用到RNN上進行的一個小改動,效果并不是很好。因為RNN模型在訓練時速度很慢,是以并不推薦使用這種方法。

RCNN

這個模型是在Recurrent Convolutional Neural Network for Text Classification一文中提出的模型,架構如下圖所示: 

深度學習與文本分類總結

這種模型的想法是在word embedding的基礎上,求解每個單詞左邊和右邊上下文的表示,然後将三者融合在一起作為單詞的representation。在經過隐藏層、pooling層、輸出層得到文本的representation。采用了一種recurrent的方式替代CNN中的卷積層。這樣做的好處是,每個單詞最終的表示都不僅僅是一個單詞的表示這麼簡單,而是融合了其上下文資訊,可以更好地反映其含義,下面跟一個max-pooling層相當于取出對文本資訊貢獻較大的單詞及其組合,這樣我們就可以得到其分類。具體圖中的每個元素可以按照下面的公式計算: 

cl和cr是上下文representation,等于前面一個詞的上下文表示與目前單詞的embedding分别乘以權重參數再組合起來。最終的單詞表示xi為cl、embed、cr三者的聯合。在接下來将其通過一層神經網絡得到yi。

深度學習與文本分類總結
深度學習與文本分類總結
深度學習與文本分類總結

這種方法相比TextRNN而言,組合了單詞之間的上下文資訊,可以更好的得到文本中的長依賴關系。而且相比RNN來講,熟練速度更快,基本上可以與TextCNN達到相同的效果。也是一種十分優秀的文本分類模型。

Char CNN、Char RNN

這兩種模型都是從char級别開始進行文本分類的方法,在這之前我已經對兩種模型進行過分析和實作。可以參考我之前的幾篇文章進行了解,由于參賽的時間有限,是以在競賽過程中并未使用這兩種方法進行檢驗效果。原因是官方提供了詞向量和字元向量,但是據别的參賽選手反應使用字元向量效果普遍不好。而且官方給的語聊是經過脫敏處理的,并不适合使用char-cnn模型進行模組化。

  • 字元級卷積神經網絡(Char-CNN)實作文本分類–模型介紹與TensorFlow實作
  • 使用TensorFlow實作RNN模型入門篇2–char-rnn語言模組化模型

HAN

這是Hierarchical Attention Network for Document Classification論文中提出的模型,這部分内容可以參考我之前的兩篇文章,已經對模型和tf實作做了詳細的介紹:

  • HAN模型介紹
  • 使用TensorFlow實作HAN代碼詳解
深度學習與文本分類總結
深度學習與文本分類總結

其基本思路就是将文本按層次分成單詞、句子、文本三層關系,然後分别用兩個Bi-LSTM模型去模組化word-sentence、sentence-doc的模型。而且在每個模型中都引入了Attention機制來捕獲更長的依賴關系,進而得出不同詞/句子在建構句子/文本時的重要程度。這種模型相對來說效果在RNN模型中還是算不錯的,因為它綜合考慮了文本結構、詞句的重要性等因素。

Dynamic Memory Network

這個模型是“Ask Me Anything: Dynamic Memory Networks for Natural Language Processing”一文提出來的。他的思路是所有的NLP任務都可以歸為QA任務,也就是由輸入、問題、答案構成。是以DMN是建構了一個QA的模型,然後也可以用于分類、翻譯、序列資料等多重任務中。其模型主要有四部分組成:

深度學習與文本分類總結

這裡輸入是一段話,然後question相當于一種門控機制,會用Attention機制選擇性的将input中的資訊儲存在episodic memory當中。接下來episodic memory的輸出在經過answer子產品産生問題的答案。具體的每個子產品細節如下圖所示:

深度學習與文本分類總結
  1. 輸入子產品的作用是将輸入的文本表示成向量,這裡采用RNN模型作為文本表示的模型。如果輸入是一句話就使用RNN的hidden state作為其representation,如果輸入是多句話,則在每句話後面添加辨別符,然後給每句話都生成一個representation,如圖中藍色的小條。
  2. question子產品的作用是将question表示成向量,與輸入子產品相似同樣使用RNN作為模型,将最終的hidden state作為輸出向量傳入episodic memory子產品,作為其初始狀态。
  3. episodic memory子產品通過疊代産生記憶。輸入子產品産生的句子表示會根據question子產品進行注意力機制的權重,按照問題針對性的選擇出相應的表示。記憶子產品的兩條線分别代表帶着問題q第一次閱讀input的記憶,以及帶着問題q第二次閱讀的記憶。
  4. answer module是根據episodic memory的最後一個memory作為模型的初始狀态,這裡使用GRU進行模組化。然後生成最終的答案

這部分的詳細介紹可以參考碼農場對這篇論文的筆記。

Entity Network

在看到brightmart的分享之前并未聽說過這個模型,後來查了一下,發現是2017年ICLR剛發的文章“Tracking the World State with Recurrent Entity Networks”,這些大牛們真的是緊跟業内最前沿==這篇論文等我之後有時間會專門去研究一下然後寫篇部落格來講,這裡先不說。放張模型的架構圖感受一下~~ 

深度學習與文本分類總結

Attention is all your need

這是谷歌今年剛發的論文,對标Facebook之前釋出的“Attention is all your need”。由于時間關系同樣還沒有仔細閱讀過,先寫在這占個坑位吧,看之後什麼時候有時間實作一下。

總結

至此我們已經把主流的文本分類中會用到的深度學習模型說了個遍,從CNN到RNN,從seq2seq到Attention,我覺得這些模型各有優劣,在不同的任務上會有不同的表現效果。但是基本上來講如果追求簡單速度,可以使用fasttext,想要提升效果先可以試試textCNN和RCNN這兩種模型,在接下來可以試試HAN這類LSTM或者GRU的模型,剩下幾種也會有不錯的效果,可以根據自己的精力和項目要求判斷是否進行嘗試。因為有的并不是專門為了文本分類設計的,是以效果上可能更需要自己針對具體的任務進行調整。

但是其實深度學習裡面模型可能隻是一部分,不同的模型肯定會取得不一樣的效果。但是更加重要的參數調整,因為按照具體的任務和資料不一樣,參數的選擇會給最終的效果帶來很大的差距。就單純地按照這次競賽來講,相同的單模型分數會在0.30-0.41範圍中波動,然而參數的選擇和調優卻是十分麻煩和困難的事情,是以很多人稱之為黑盒==是門學問,等之後競賽前排大神出了分享之後,我也會參考他們的經驗寫一下我對于這部分的了解。

上一篇部落格中我們已經總結了文本分類中常用的深度學習模型,因為知乎的本次競賽是多标簽的文本分類任務,這也是我第一次接觸多标簽分類,是以想單獨寫一篇部落格來記錄這方面的相關知識。 

在這裡首先列出幾篇參考的文章:

  1. 基于神經網絡的多标簽分類可以追溯到周志華在2006年發表的文章: Multi-Label Neural Networks with Applications to Functional Genomics and Text Categorization。其貢獻在于提出了BP-MLL(多标簽反向傳播)以及新的誤差函數: 
    深度學習與文本分類總結
  2. 然後是一篇基于周志華文章改進的論文:Large-scale Multi-label Text Classification Revisiting Neural Networks。這篇文章提出使用Adagrad,dropout等技術,此外還提出使用标準的交叉熵函數作為目标函數效果更好。
  3. 上面的文章還是使用普通的神經網絡進行分類,接下來就出現了基于深度學習模型的方法。比如:Large Scale Multi-label Text Classification with Semantic Word Vectors。這篇文章很簡單,就是把TextCNN和GRU直接用到多标簽文本分類裡,最後根據一個門檻值alpha來确定樣本是否屬于某個類别。
  4. Improved Neural Network-based Multi-label Classification with Better Initialization Leveraging Label Co-occurrence。這篇文章提出了一種根據類别标簽之間的共現關系來初始化最後輸出層參數的方法。其也是基于TextCNN,不同之處是最後一個輸出層的權重不使用随機初始化,而是根據标簽之間的共現關系進行初始化。據作者說這樣可以獲得标簽之間的關系,這樣有一種聚類的效果。相似的樣本會标記為相同的标簽。此外他還提出了損失函數的計算方法。具體的細節部分可以去看相關論文。 
    深度學習與文本分類總結
    深度學習與文本分類總結
  5. 模型上的改進:Ensemble Application of Convolutional and Recurrent Neural Networks for Multi-label Text Categorization。這篇論文主要提出了一種CNN和RNN融合的機制,将CNN的輸出作為RNN的初始狀态然後進行類别的預測。架構圖如下所示: 
    深度學習與文本分類總結

上面幾篇論文是我在做競賽的過程中閱讀的幾篇相關論文,每篇都會有一定的特點,但是實際的效果如何其實并不會像論文中提到的那樣,也有可能是自己調參跳的不好。但是論文裡面提到的創新點還是值得我們學習的。然後我們來總結一下多标簽文本分類相關的東西,這裡參考上面第三篇論文。首先來講,多标簽分類的算法可以分成下面三種類型:

  1. multi-label classification:将标簽分成Y和Y的補集兩個分區
  2. label ranking:将标簽進行排序,排名靠前的就是預測為相關的類别
  3. multi-label ranking:上述二者的綜合,同時産生分區和rank。設定門檻值函數進行判斷

此外,我們還可以使用Binary Relevance(BR)算法,将多标簽問題轉化為L個二分類問題。訓練L個模型,每個模型處理一個類别,這樣做的好處是可以并行訓練L個模型,降低訓練複雜度,而且可以友善的增删标簽數量。最終隻需要把結果合并成一個輸出向量就可以了。但是也有一點的缺點,比如說由于分開訓練L個模型,是以忽視了标簽之間的相關性。而且當當資料集出現類别不均衡等現象時,效果也會變差。

上面說了幾種如何看待多标簽分類問題的思路和看法。其實就是将多标簽分類進行轉化。我感覺比較常用的應該是ranking和BR的方法。再反過來看這次知乎的競賽,其實我看了前幾名的解決方案,大都是隻用了深度學習模型的堆砌,比如說CNN,RNN然後再加上模型融合和資料增強的一些手段得到了比較好的分數。但是我之前也采訪過知乎機器學習團隊的負責人,他當時也明确的表明現在選手使用的方法還都是比較老派,沒有什麼十分大的創新點出來,而且幾乎沒怎麼利用标簽之間的關系等資訊。這裡我就說一下我在競賽裡面做過的幾種嘗試。

1,首先來分析一下知乎所提供的資料都有哪些特點,第一給了1999個标簽之間的父子關系,這樣我們就可以将其構成一張樹狀關系圖。

2,其次他給出了每個label的描述資訊,我覺得這個資訊是最重要的,因為這樣我們最簡單也可以計算樣本和1999個标簽之間的相似性然後排名取出前5個就可以粗略地進行類别标注。當然我們在結合深度學習的時候可以将其放在最後一層跟CNN的輸出進行結合計算。我當時采用的方法是,将樣本和1999個标簽的title分别經過CNN進行計算,然後再将得到的文本表示和标簽資訊進行一個相似性計算得到每個類别的相似性機率表示。但是這種方法的缺點在于速度太慢,我當時訓練了一天兩夜才跑了2個epoch(CPU),是以中途放棄了,至今也不知道效果如何==

3,使用上面第四篇文獻中所提出的方法,首先對資料進行預處理,得到所有訓練資料中所出現的标簽共現資訊,取共現次數最高的前N個标簽對作為初始化的依據。該模型的想法是通過這種自定義初始化網絡權重的方法讓模型學習到這種标簽的共現資訊,進而更加準确地進行類别預測。

4,在查閱文獻的過程中,看到了一篇“Multi-Label Classification on Tree- and DAG-Structured Hierarchies”的論文,其提出将标簽資訊建構成有向無環圖或者樹狀的分層結構。但是該方法是基于傳統機器學習模型做的,由于競賽過程中時間有限,是以并未加以嘗試。此外,我還考慮是否可以将标簽資訊使用類似于word2vec中的分層softmax的機制進行處理。總之是盡量的把标簽之間的父子關系圖利用起來,以增強分類的準确度。這裡也不過是一些自己的想法罷了,還并未進行實踐,也希望有懂這方面知識的同學可以指點一二。

至此,關于多标簽文本分類相關的知識就暫時總結到這裡,其實也就是看的幾篇論文和知乎競賽中的一些思考。接下來抽時間把自己參加競賽的一些具體的代碼等再整理出一篇部落格就将完結這個系列。

繼續閱讀