1. 程式人生 > >文字分類中attention理解

文字分類中attention理解

綜述

今天,基本上所有的NLP方面的應用,如果想取得state-of-art的結果,就必須要經過attention model的加持。比如machine translation, QA(question-answer), NLI(natural language inference), etc, etc…. 但是這裡有個問題: 傳統上的attention的應用,總是要求我們的task本身同時有源和目標的概念。比如在machine translation裡, 我們有源語言和目標語言,在QA裡我們有問題和答案,NLI裡我們有sentence pairs …… 而Attention常常被定義為目標和源的相關程度。

但是還有很多task不同時具有源和目標的概念。比如document classification, 它只有原文,沒有目標語言/文章, 再比如sentiment analysis(也可以看做是最簡單的一種document classification),它也只有原文。那麼這種情況下attention如何展開呢? 這就需要一個變種的技術,叫intra-attention(或者self-attention), 顧名思義,就是原文自己內部的注意力機制。

intra-attention有不同的做法。比如前一段Google發的那篇《Attention is All You Need》,在machine translation這個任務中,通過把attention機制formularize成Key-Value的形式,很自然的表達出源語言和目標語言各自的intra-attention. 這麼做的好處是在句子內部產生清晰的1.語法修飾 2. 語義指代關係 方面的理解,也就是說對句子的結構和意義有了更好的把控。

如下盜圖所示: 
一種self-attention的結果

如上兩圖分別代表了原文在兩個不同子空間的投影的注意力結果(具體做法見原Google的論文,這裡的介紹從略)。我們可以看到清晰的指代關係和修飾關係。文章引入的self-attention機制加上positional embedding的做法,可能是將來的一個發展方向。

方法

這篇論文采取了非常不一樣的做法。它引入了context vector用來發現每個詞語和每個句子的重要性。

它基於這樣的observation:

每個document由多個句子組成,而在決定文章的型別時,每個句子有不同的重要性。有的更相關一些,有的用處不大。比如說在一篇有關動物科學的文章中,某些句子和文章的主題相關性就很高。比如包含類似於“斑馬”或者“獵食者”,“偽裝”這樣詞語的句子。我們在建造模型時,最好能夠給這樣的句子更多的“attention”。 同樣的,對於每個句子而言,它所包含的每個詞語的重要性也不一樣,比如在IMDB的review中, 如like, amazing, terrible這樣的詞語更能夠決定句子的sentiment

所以,在分類任務中,如果我們給模型一篇文章,我們想問模型的問題是:1. 在這篇文章中,哪些句子更重要,能夠決定它的分類? 2. 在這篇文章的某個句子中,哪些詞語最重要,能夠影響句子在文章裡的重要性?

那麼,如何向模型提出這樣的問題呢? 或者說如何讓模型理解我們的意圖呢? 作者是通過引入context vector做到的。這個context vector 有點天外飛仙的感覺, 之所以給我這樣的感覺,是因為:

  1. context vector是人工引入的,它不屬於task的一部分。它是隨機初始化的。

  2. 它代替了inter-attention中目標語言/句子,能夠和task中的原文產生相互作用,計算出原文各個部分的相關程度,也就是我們關心的attention。

  3. 它是jointly learned。 也就是說,它本身,也是學習得來的 !!

具體而言,網路的架構如下: 
hierarchical attention網路結構

網路由四個部分組成:word sequence layer, word-attention layer, sentence sequence layer, and sentence-attention layer

如果沒有圖中的uwuw(詞語級別的context vector)和usus(句子級別的context vector),這個模型也沒有什麼特殊的地方。它無非是由word sequence layer和sentence sequence layer組成的一個簡單的層級的sequence模型而已。而有了這兩個context vector, 我們就可以利用它們產生attention layer, 求出每個詞語和每個句子的任務相關程度。

具體做法如下,針對每一個句子,用sequence model, 就是雙向的rnn給表達出來,在這裡用的是GRU cell。每個詞語對應的hidden vector的輸出經過變換(affine+tanh)之後和uwuw相互作用(點積),結果就是每個詞語的權重。加權以後就可以產生整個sentence的表示。從高一級的層面來看(hierarchical的由來),每個document有L個句子組成,那麼這L個句子就可以連線成另一個sequence model, 同樣是雙向GRU cell的雙向rnn,同樣的對輸出層進行變換後和usus相互作用,產生每個句子的權重,加權以後我們就產生了對整個document的表示。最後用softmax就可以產生對分類的預測。

每次的“提問”,都是由uwuw和usus來實現的,它們用來找到高權重的詞語和句子。下面看看實現。

實現

word-sequence和sentence-sequence都通過下面這個module實現。

sequence model的實現

這裡使用了雙向的dynamic的rnn,實際上static的rnn效果也不錯

不同的IMDB的reviews大小不一樣,有的包含了幾十個句子,有的只包含了幾個句子, 為了讓rnn模型更加精確,我把每個batch內部的review的實際長度(review所包含的句子個數)存在了seq_lens裡面。這樣在呼叫bidirectional_dynamic_rnn時,rnn精確的知道計算該在哪裡停止。

word-attention和sentence-attention都通過呼叫這個module來實現

attention model的實現

注意第65行 uwuw就是我們說的context vector (我在第69行把它稱之為summarizing question vector)

結果

根據原paper的做法,利用data先pretrain了word embeddings

sequence層之後加了dropout, 用處不甚明顯。

最大的review長度控制在15個句子, 每個句子的長度固定為70。

最後的大概精度是0.9左右。我現在的計算資源非常有限,所以不能實驗太多別的引數。

以下是幾個例子。紅色的深度代表句子對於review的sentiment的重要性,黃色的深度代表詞語對於句子的重要性。

0代表negative, 1代表positive

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

總結一下: 這種 intra-attention 機制很有創意,也挺有效。根據我不完全的實驗,hierarchical attention model 明顯好於其他的比如stacked bi-directional RNN, CNN text(Yoon Kim的版本)。 說不完全是因為我的計算資源非常有限,我只是實現了這些模型,沒有仔細的調參, 而且我只對2-class的IMDB作了實驗。 所以上面的結論不夠嚴謹,僅供參考。

我當然相信attention的效果,但是比較無法忍受sequence model的速度。最近新的突破(SRU)或許能夠大幅度提升sequence model的效率,但是我還是想試試CNN+attention, 原因是一來比較看好CNN的速度,而來attention可以一定程度上彌補CNN在長程相關性上的缺陷。