如何用深度學習做自然語言處理?這里有份實踐清單
簡介
本文是一系列關于如何使用神經網絡進行自然語言處理(NLP)的最佳實踐匯集,將隨著新觀點的出現定期進行更新,從而不斷提升我們對用于 NLP 的深度學習的理解。
NLP 社區(qū)中有這樣一句說法:帶有注意力的 LSTM 能在所有任務上實現當前最佳的表現。盡管在過去的兩年這確實是真的,NLP 社區(qū)卻在慢慢偏離帶有注意力的 LSTM,而去發(fā)現更有趣的模型。
但是,NLP 社區(qū)并非想再花費兩年獨立地(重新)發(fā)現下一個帶有注意力的 LSTM。我們不打算重新發(fā)明已經奏效的技巧或方法。盡管現存的深度學習庫已經從整體上編碼了神經網絡的最佳實踐,比如初始化方案,但是很多其他的細節(jié),尤其是特定任務或特定領域還有待從業(yè)者解決。
本文并不打算盤點當前最佳,而是收集與大量任務相關的最佳實踐。換言之,本文并不描述某個特定架構,而是旨在收集那些構建成功框架的特征。其中的很多特征對于推動當前最佳是最有用的,因此我希望對于它們的更廣泛了解將會帶來更強的評估、更有意義的基線對比,以及更多靈感,幫助我們覺察那些可能奏效的方法。
本文假設你對神經網絡應用于 NLP 的情況已經很熟悉(如果不熟悉,我建議你看一下 Yoav Goldberg 寫的A Primer on Neural Network Modelsfor Natural Language Processing: https://www.jair.org/media/4992/live-4992-9623-jair.pdf),并大體上對 NLP 或某個特定任務感興趣。本文的主要目標是使你快速掌握相關的最佳實踐,從而盡快做出有意義的貢獻。我首先會對與絕大多數任務相關的最佳實踐做一個概述,接著略述與最常見的任務相關的最佳實踐,尤其是分類、序列標注、自然語言生成和神經機器翻譯。
免責聲明:把某些東西定義為最佳實踐極其困難:最佳的標準是什么?如果有更好的實踐出現呢?本文基于我的個人理解和經驗(肯定不全面)。接下來,我將只討論被證明在至少兩個獨立的群體中有益的實踐。對于每個最佳實踐我將給出至少兩個參引。
最佳實踐
詞嵌入
在最近的 NLP 發(fā)展中,詞嵌入無疑是最廣為人知的最佳實踐,這是因為預訓練嵌入的使用對我們十分有幫助 (Kim, 2014) [12]。詞嵌入的最佳維度絕大多數是依賴任務的:一個更小的維度更多在句法任務上工作更好,比如命名實體識別(named entity recognition)(Melamud et al., 2016) [44],或者詞性標注(POS)(Plank et al., 2016) [32],盡管一個更大的維度對于更多的語義任務來說更有用,比如情感分析 (Ruder et al., 2016) [45]。
深度
雖然短時間內我們還無法達到計算機視覺的深度,但是 NLP 中的神經網絡已經發(fā)展地更深了。現在最佳的方法通常使用 deep Bi-LSTM,它通常包含 3-4 層,比如詞性標注 (Plank et al., 2016) 和語義角色標注 (He et al., 2017) [33]。一些任務的模型甚至更深。谷歌的 NMT 模型有 8 個編碼器和 8 個解碼器層,(Wu et al., 2016) [20]。然而,大多數情況下,模型超過 2 層所帶來的性能提升是最小的 (Reimers & Gurevych, 2017) [46]。
這些觀察適用于絕大多數序列標注和結構化預測問題。對于分類,深或者非常深的模型只在字符級的輸入中表現良好,并且淺層的字詞級模型依然是當前最佳 (Zhang et al., 2015; Conneau et al., 2016; Le et al., 2017) [28, 29, 30]。
層連接
訓練深度神經網絡時,可以使用一些核心技巧避免梯度消失問題。不同的層和連接因此被提出來了,這里我們將討論 3 點:i) Highway 層,ii) 殘差連接(residual connection),iii) 密集型殘差連接。
Highway 層:它受到 LSTM 的門控機制所啟發(fā) (Srivastava et al., 2015) [1]。首先讓我們假設一個單層的 MLP,它將一個非線性 g 的仿射變換應用到其輸入 x:
Highway 層接著計算以下函數:
其中 t=σ(WTx+bT) 被稱作變換門(transform gate),(1−t) 被稱作進位門(carry gate)。我們可以看到,Highway 層和 LSTM 門很相似,因為它們自適應地把輸入的一些維度直接傳遞到輸出。
Highway 層主要用于語言建模,并取得了當前最佳的結果 (Kim et al., 2016; Jozefowicz et al., 2016; Zilly et al., 2017) [2, 3, 4],但它同時也用于其他任務,如語音識別 (Zhang et al., 2016) [5]。想了解更多相關信息和代碼,可查看 Sristava 的主頁(http://people.idsia.ch/~rupesh/very_deep_learning/)。
殘差連接:殘差連接(He et al., 2016)[6] 的首次提出是應用于計算機視覺,也是計算機視覺在 ImageNet 2016 奪冠的最大助力。殘差連接甚至比 Highway 層更直接。我們使用代表當前層的指數 L 來增加之前的層輸出 h。然后,殘差連接學習以下函數:
僅通過一個快捷連接,殘差連接即可把之前層的輸入添加到當前層。這一簡單的更改緩解了梯度消失問題,因為層級不能變得更好,模型可以默認使用恒等函數(identity function)。
密集殘差連接:密集殘差連接 (Huang et al., 2017) [7] ( CVPR 2017 最佳論文獎)從每一個層向所有隨后的層添加連接,而不是從每一個層向下一個層添加層:
密集殘差連接已成功應用于計算機視覺,也被證明在神經機器翻譯方面的表現持續(xù)優(yōu)于殘差連接 (Britz et al., 2017) [27]。
Dropout
盡管在計算機視覺領域的多數應用中,批歸一化已使其他正則化器變得過時,但是 dropout (Srivasta et al., 2014) [8] 依然是應用于 NLP 深度神經網絡中的正則化器。0.5 的 dropout 率表明其在絕大多數場景中依然高效 (Kim, 2014)。近年來,dropout 的變體比如適應性 dropout((Ba & Frey, 2013) [9])和進化 dropout (Li et al., 2016) [10] 已被提出,但沒有一個在 NLP 社區(qū)中獲得廣泛應用。造成這一問題的主要原因是它無法用于循環(huán)連接,因為聚集 dropout masks 將會將嵌入清零。
循環(huán) dropout:循環(huán) dropout(Gal & Ghahramani, 2016)[11] 通過在層 ll 的時間步中應用相同的 dropout masks 來解決這一問題。這避免了放大序列中的 dropout 噪音,并為序列模型帶來了有效的正則化。循環(huán) dropout 已在語義角色標注 (He et al., 2017) 和語言建模 (Melis et al., 2017) [34] 中取得了當前最佳的結果。
多任務學習
如果有額外的數據,多任務學習(MTL)通??捎糜谠谀繕巳蝿罩刑嵘阅?。
輔助目標(auxiliary objective):我們通常能找到對我們所關心的任務有用的輔助目標 (Ruder, 2017) [13]。當我們已經預測了周圍詞以預訓練詞嵌入 (Mikolov et al., 2013) 時,我們還可以在訓練中將其作為輔助目標 (Rei, 2017) [35]。我們也經常在序列到序列模型中使用相似的目標(Ramachandran et al., 2016)[36]。
特定任務層:盡管把 MTL 用于 NLP 的標準方法是硬參數共享,但允許模型學習特定任務層很有意義。這可通過把一項任務的輸出層放置在較低級別來完成 (Søgaard & Goldberg, 2016) [47]。另一方法是誘導私有和共享的子空間 (Liu et al., 2017; Ruder et al., 2017) [48, 49]。
注意力機制
注意力機制是在序列到序列模型中用于注意編碼器狀態(tài)的最常用方法,它同時還可用于回顧序列模型的過去狀態(tài)。使用注意力機制,系統(tǒng)能基于隱藏狀態(tài) s_1,…,s_m 而獲得環(huán)境向量(context vector)c_i,這些環(huán)境向量可以和當前的隱藏狀態(tài) h_i 一起實現預測。環(huán)境向量 c_i 可以由前面狀態(tài)的加權平均數得出,其中狀態(tài)所加的權就是注意力權重 a_i:
注意力函數 f_att(h_i,s_j) 計算的是目前的隱藏狀態(tài) h_i 和前面的隱藏狀態(tài) s_j 之間的非歸一化分配值。在下文中,我們將討論四種注意力變體:加性注意力(additive attention)、乘法(點積)注意力(multiplicative attention)、自注意力(self-attention)和關鍵值注意力(key-value attention)。
加性注意力是最經典的注意力機制 (Bahdanau et al., 2015) [15],它使用了有一個隱藏層的前饋網絡來計算注意力的分配:
其中 v_a 和 W_a 是所學到的注意力參數,[* ; *] 代表了級聯。類似地,我們同樣能使用矩陣 W_1 和 W_2 分別為 h_i 和 s_j 學習單獨的轉換,這一過程可以表示為:
乘法注意力(Multiplicative attention)(Luong et al., 2015) [16] 通過計算以下函數而簡化了注意力操作:
加性注意力和乘法注意力在復雜度上是相似的,但是乘法注意力在實踐中往往要更快速、具有更高效的存儲,因為它可以使用矩陣操作更高效地實現。兩個變體在低維度 d_h 解碼器狀態(tài)中性能相似,但加性注意力機制在更高的維度上性能更優(yōu)。緩解這一現象的方法是將 f_att(h_i,s_j) 縮放到 d_h^(-1/2) 倍 (Vaswani et al., 2017) [17]。
注意力機制不僅能用來處理編碼器或前面的隱藏層,它同樣還能用來獲得其他特征的分布,例如閱讀理解任務中作為文本的詞嵌入 (Kadlec et al., 2017) [37]。然而,注意力機制并不直接適用于分類任務,因為這些任務并不需要情感分析(sentiment analysis)等額外的信息。在這些模型中,通常我們使用 LSTM 的最終隱藏狀態(tài)或像最大池化和平均池化那樣的累加函數來表征句子。
自注意力機制(Self-attention)通常也不會使用其他額外的信息,但是它能使用自注意力關注本身進而從句子中抽取相關信息 (Lin et al., 2017) [18]。自注意力又稱作內部注意力,它在很多任務上都有十分出色的表現,比如閱讀理解 (Cheng et al., 2016) [38]、文本繼承 (textual entailment/Parikh et al., 2016) [39]、自動文本摘要 (Paulus et al., 2017) [40]。
我們能計算每個隱藏狀態(tài) h_i 的非歸一化分配值從而簡化加性注意力:
在矩陣形式中,對于隱藏狀態(tài) H=h_1,…,h_n,我們能通過以下形式計算注意力向量 a 和最后的句子表征 c:
我們不僅可以抽取一個向量,同時還能通過將 v_a 替代為 V_a 矩陣而執(zhí)行一些其他注意力特征,這可以令我們抽取注意力矩陣 A:
在實踐中,我們可以執(zhí)行以下的正交約束而懲罰計算冗余,并以 Frobenius 范數平方的形式鼓勵注意力向量的多樣性:
Vaswani et al. (2017) 同樣使用了類似的多頭注意力(multi-head attention)。
最后,關鍵值注意力 (Daniluk et al., 2017) [19] 是最近出現的注意力變體機制,它將形式和函數分開,從而為注意力計算保持分離的向量。它同樣在多種文本建模任務 (Liu & Lapata, 2017) [41] 中發(fā)揮了很大的作用。具體來說,關鍵值注意力將每一個隱藏向量 h_i 分離為一個鍵值 k_i 和一個向量 v_i:[k_i;v_i]=h_i。鍵值使用加性注意力來計算注意力分布 a_i:
其中 L 為注意力窗體的長度,I 為所有單元為 1 的向量。然后使用注意力分布值可以求得環(huán)境表征 c_i:
其中環(huán)境向量 c_i 將聯合現階段的狀態(tài)值 v_i 進行預測。
最優(yōu)化
最優(yōu)化算法和方案通常是模型的一部分,并且常常被視為黑箱操作。有時算法輕微的變化,如在 Adam 算法中減少超參數β2 的值 (Dozat & Manning, 2017) [50] 將會造成優(yōu)化行為的巨大改變。
Adam 方法 (Kingma & Ba, 2015) [21] 是使用最廣泛、最常見的優(yōu)化算法,它通常也作為 NLP 研究員的優(yōu)化器。Adam 方法要明顯地比 vanilla 隨機梯度下降更優(yōu)秀,并且其收斂速度也十分迅速。但近來有研究表明通過精調并帶動量的梯度下降方法要比 Adam 方法更優(yōu)秀 (Zhang et al., 2017) [42]。
從優(yōu)化方案來說,因為 Adam 方法會適應性地為每一個參數調整學習速率 (Ruder, 2016) [22],所以我們可以使用 Adam 方法精確地執(zhí)行 SGD 風格的退火處理。特別是我們可以通過重啟(restart)執(zhí)行學習速率退火處理:即設定一個學習速率并訓練模型,直到模型收斂。然后,我們可以平分學習速率,并通過加載前面最好的模型而重啟優(yōu)化過程。在 Adam 中,這會令優(yōu)化器忘記預訓練參數的學習速率,并且重新開始。Denkowski & Neubig (2017) [23] 表示帶有兩個重啟和學習速率退火處理的 Adam 算法要比帶有退火處理的 SGD 算法更加優(yōu)秀。
集成方法
通過平均多個模型的預測將多個模型組合為一個集成模型被證明是提高模型性能的有效策略。盡管在測試時使用集成做預測十分昂貴,最近提取方面的一些進展允許我們把昂貴的集成壓縮成更小的模型 (Hinton et al., 2015; Kuncoro et al., 2016; Kim & Rush, 2016) [24, 25, 26]。
如果評估模型的多樣性增加 (Denkowski & Neubig, 2017),集成是確保結果可靠的重要方式。盡管集成一個模型的不同檢查點被證明很有效 (Jean et al., 2015; Sennrich et al., 2016) [51, 52],但這種方法犧牲了模型的多樣性。周期學習率有助于緩解這一影響 (Huang et al., 2017) [53]。但是,如果資源可用,我們更喜歡集成多個獨立訓練的模型以最大化模型多樣性。
超參數優(yōu)化
我們可以簡單地調整模型超參數從而在基線上獲得顯著提升,而不僅僅只是使用預定義或現有的超參數來訓練模型。最近 Bayesian Optimization 的新進展可以用于在神經網絡黑箱訓練中優(yōu)化超參數 (Snoek et al., 2012) [56],這種方法要比廣泛使用的網格搜索高效地多。LSTM 的自動超參數調整已經在語言建模產生了最佳的性能,遠遠勝過其他更復雜的模型 (Melis et al., 2017)。
LSTM 技巧
學習初始狀態(tài):我們通常初始化 LSTM 狀態(tài)為零向量。但我們可以將初始狀態(tài)看作參數進行優(yōu)化,而不是人為地調整來提升性能。這一方法十分受 Hinton 的推薦。關于這一技巧的 TensorFlow 實現,詳見:https://r2rt.com/non-zero-initial-states-for-recurrent-neural-networks.html
嘗試輸入和輸出嵌入:適合于輸入和輸出嵌入在 LSTM 模型中占了絕大多數參數數量的情況。如果 LSTM 在語言建模中預測詞匯,輸入和輸出參數可以共享 (Inan et al., 2016; Press & Wolf, 2017) [54, 55]。這一技巧在不允許學習大規(guī)模參數的小數據集中十分有用。
梯度范數截斷(Gradient norm clipping):降低梯度消失風險的一個方法是截斷其最大值 (Mikolov, 2012) [57]。但是這并沒有持續(xù)提升性能(Reimers & Gurevych, 2017)。與其獨立地截斷每個梯度,截斷梯度的全局范數 (Pascanu et al., 2013) 反而會帶來更加顯著的提升(這里有一個 Tensorflow 實現:https://stackoverflow.com/questions/36498127/how-to-effectively-apply-gradient-clipping-in-tensor-flow)。
下投影(Down-projection):為了進一步減少輸出參數的數量,LSTM 的隱態(tài)可以被投影到更小的尺寸。這對帶有大量輸出的任務尤其有用,比如語言建模(Melis et al., 2017)。
特定任務的最佳實踐
下面,我們要介紹特定任務的最佳實踐。大部分模型在執(zhí)行特定類型的單項任務時表現很好,部分模型可以應用于其他任務,不過在應用之前需要驗證其性能。我們還將討論以下任務:分類、序列標注、自然語言生成(NLG)和自然語言生成的特殊案例神經機器翻譯。
分類
由于卷積操作更加高效,近期 CNN 應用范圍擴大,成為處理 NLP 中分類任務的通用方法。下面的最佳實踐和 CNN 相關,可選擇多個最優(yōu)超參數(optimal hyperparameter)。
CNN 過濾器:使過濾器大小接近最優(yōu)過濾器大小,如 (3,4,5) 性能最佳(Kim, 2014; Kim et al., 2016)。特征映射的最佳數量范圍是 50~600(Zhang & Wallace, 2015)[59]。
聚合函數(Aggregation function):1-最大池化優(yōu)于平均池化和 k-最大池化(Zhang & Wallace, 2015)。
序列標注
序列標注在 NLP 中非常普遍?,F有的很多最佳實踐都是模型架構的一個環(huán)節(jié),下列指南主要討論模型輸出和預測階段。
標注策略(Tagging scheme): 對于將標簽分配到文本分隔的任務,不同的標注策略均可采用。比如:BIO,分隔的第一個符號處標注 B-tag,其他符號處標注 I-tag,分隔外的符號標注 O-tag;IOB,和 BIO 相似,不同之處在于如果前面的符號屬于相同的類別,但不屬于同一個分隔,則使用 B-tag 來標注;IOBES,還需要在單個符號實體處標注 S-tag,每個分隔的最后一個符號處標注 E-tag。IOBES 和 BIO 的性能相似。
條件隨機場輸出層(CRF output layer): 如果輸出之間存在依賴,如在命名實體識別(named entity recognition)中,可以用線性鏈條件隨機場(linear-chain conditional random field)代替最后的 softmax 層。經證實,這種方法對于要求對約束進行建模的任務有持續(xù)改善的效果(Huang et al., 2015; Max & Hovy, 2016; Lample et al., 2016)[60, 61, 62]。
約束解碼(Constrained decoding): 除了條件隨機場輸出層以外,還可用約束解碼來排除錯誤排序,即不產生有效的 BIO 過渡(BIO transition)(He et al., 2017)。約束解碼的優(yōu)勢在于可以執(zhí)行隨意約束(arbitrary constraint),如特定任務約束或句法約束。
自然語言生成
多數現有最佳實踐可用于自然語言生成(NLG)。事實上,目前出現的很多技巧都植根于語言建模方面的進步,語言建模是最典型的 NLP 任務。
建模覆蓋率(Modelling coverage): 重復是 NLG 任務的一大難題,因為當前的模型無法很好地記憶已經產生的輸出結果。在模型中直接設置建模覆蓋率是解決該問題的好方法。如果提前知道哪些實體應該出現在輸出結果中(就像菜譜中的調料),則需要使用一個檢查表(checklist)(Kiddon et al., 2016)[63]。如果使用注意力機制,我們可以追蹤覆蓋率向量 c_i,它是過去的時間步上注意力分布 a_t 的總和(Tu et al., 2016; See et al., 2017)[64, 65]:
該向量可以捕捉我們在源語言所有單詞上使用的注意力。現在我們可以在覆蓋率向量上設置加性注意力(additive attention),以鼓勵模型不重復關注同樣的單詞:
此外,我們可以添加輔助損失(auxiliary loss),該損失可以捕捉我們想關注的特定任務的注意力行為:我們希望神經機器翻譯可以做到一對一對齊(one-to-one alignment);如果最后的覆蓋率向量多于或少于每一個指數上的覆蓋率向量,那么模型將被罰分(Tu et al., 2016)。總之,如果模型重復處理同樣的位置,我們就會懲罰該模型(See et al., 2017)。
神經機器翻譯
雖然神經機器翻譯只是 NLG 的一個分支,但 NMT 獲得了大量關注,有許多方法專門為該任務開發(fā)。相似地,許多最佳實踐或超參數選擇只能應用到 NMT 領域。
嵌入維度(Embedding dimensionality):2048 維嵌入的性能最佳,但很少達到該效果。128 維嵌入的性能卻出乎意料地好,收斂速度幾乎達到之前的 2 倍(Britz et al., 2017)。
編碼器和解碼器深度: 編碼器的深度無需超過 2−4 層。深層模型性能優(yōu)于淺層模型,但多于 4 層對解碼器來說沒有必要(Britz et al., 2017)。
方向性(Directionality):雙向編碼器性能稍好于單向編碼器。Sutskever et al.(2014)[_67_] 提出顛倒源語言的順序,以減少長期依賴的數量。使用單向編碼器顛倒源語言順序優(yōu)于未顛倒語序(Britz et al., 2017)。
束搜索策略(Beam search strategy):大小 10、長度歸一化罰項為 1.0 的中型束(Wu et al., 2016)性能最佳(Britz et al., 2017)。
子詞翻譯(Sub-word translation):Senrich et al. (2016) [66] 提出根據字節(jié)對編碼(byte-pair encoding/BPE)將單詞分隔成子詞(sub-word)。BPE 迭代合并出現頻率高的符號對(symbol pair),最后將出現頻率高的 n 元合并成一個單獨的符號,進而有效去除非詞表詞(out-of-vocabulary-word)。該技術最初用來處理罕見單詞,但是子詞單元的模型性能全面超過全詞系統(tǒng),32000 個子詞單元是最高效的單詞數量(Denkowski & Neubig, 2017)。
結語
我確定這份清單上一定有遺漏的最佳實踐。相似地,也有很多我不熟悉的任務,如解析、信息提取,我沒辦法做出推薦。我希望本文對開始學習新的 NLP 任務有所幫助。即使你對這里列出的大部分內容都很熟悉,我也希望你能夠學到一些新的東西或者重新掌握有用的技巧。