語言建模的王者:AWD-LSTM指南
作者:Yashu Seth
編譯:weakish
AWD-LSTM 算是當前最先進的語言建模的統治者。所有關於世界級的模型的頂尖研究論文都採用了AWD-LSTM。它在字元模型上的表現也很棒。
這篇文章將解讀引入AWD-LSTM的研究論文Regularizing and Optimizing LSTM Language Models(正則化、優化LSTM語言模型),解釋其中討論的各種技術。這篇論文調查了一些面向基於單詞的語言建模任務的正則化和優化策略,這些策略不僅非常高效,而且可以不加修改地直接應用於現有的LSTM實現。
AWD-LSTM是 ASGD Weight-Dropped LSTM 的簡稱。它使用了 DropConnect 和 Average-SGD 的一個變體(NT-ASGD),還有其他一些知名的正則化策略。我們將講解所有這些技術的細節。儘管所有這些方法以前都有人提出過,也在理論上解釋過,這篇論文的妙處在於成功地將這些方法應用於語言模型得到當前最先進的結果。
相關復現程式碼可以在GitHub倉庫salesforce/awd-lstm-lm獲取。
如果你想要溫習一下LSTM網路的內部機制,那麼強烈推薦Christopher Olah撰寫的知名文章《一文詳解LSTM網路》。
LSTM的數學表述為:

其中, Wi 、 Wf 、 Wo 、 Wc 、 Ui 、 Uf 、 Uo 、 Uc 為權重矩陣, xt 為時刻 t 的向量輸入, ht 為當前隱藏狀態, ct 為記憶細胞狀態, ⊙ 為分素相乘。
下面我們將逐一講解論文作者討論的策略。
Weight-Dropped LSTM
RNN的迴圈連線傾向於過擬合。研究社群對預防這一傾向興趣濃厚,進行了廣泛的研究。在前饋網路和卷積神經網路中,dropout在緩解過擬合上取得了巨大的成功。但在RNN的隱藏狀態上應用類似dropout的技術效果不佳,因為這干擾了RNN保持長時依賴的能力。
有多種克服這一問題的挑戰,但大多數或者應用於隱藏狀態向量ht-1,或者應用於記憶狀態ct的更新。這妨礙了使用像NVIDIA的cuDNN LSTM這樣僵硬但高效的黑盒RNN實現。
為應對這一問題,論文作者提議使用DropConnect。我們知道,dropout歸零每一層中隨機選擇的啟用子集。DropConnect歸零的不是啟用,而是隨機選擇的權重子集。因此,每個單元接受來自前一層隨機單元子集的輸入。

DropConnect應用於隱藏狀態之間的權重矩陣( Ui, Uf, Uo, Uc) ,而不是隱藏狀態或記憶狀態。這一丟棄操作只在前向和反向傳播前進行一次,從而最小化對訓練速度的影響,並且適用於任何標準的黑盒RNN優化實現。通過丟棄隱藏狀態之間的權重矩陣的部分資訊,可以防止LSTM迴圈連線的過擬合。
具體實現可以檢視之前提到的程式碼倉庫的weight_drop.py模組。
論文作者指出,DropConnect同樣可以應用於LSTM的非迴圈權重,不過重點在於防止迴圈連線的過擬合。
NT-ASGD
人們發現,在語言建模任務中,傳統的不帶動量的SGD演算法比動量SGD、Adam、Adagrad、RMSProp等其他演算法要好。因此,論文作者調研了一種傳統SGD演算法的變體ASGD(平均SGD)。
平均SGD
我們首先講解下ASGD演算法。它採用和SGD演算法一樣的梯度更新步驟,但並不返回當前迭代計算的權重,而是同時考慮之前迭代的權重並返回一個均值。
傳統SGD更新:
w_t = w_prev - lr_t * grad(w_prev)
ASGD更新:
avg_fact = 1 / max(t - K, 1) if avg_fact != 1: w_t = avg_fact * (sum(w_prevs) + (w_prev - lr_t * grad(w_prev))) else: w_t = w_prev - lr_t * grad(w_prev)
其中,K為開始計算權重平均前執行的最小迭代數目。也就是說,在前K個迭代中,ASGD的行為和傳統SGD完全一致。t是當前完成的迭代數,sum(wprevs)是從迭代K至t的權重和,而lrt是迭代t的學習率,由學習率規劃器決定。
可以參考PyTorch的ASGD實現:torch/optim/asgd.py
論文作者指出了該方法的兩處不足:
- 學習率規劃器的調整原則不明。
- 引數K的選取原則不明。過小的值可能對這一方法的效果有負面影響,而過大的值可能導致需要額外的迭代才能收斂。
論文作者提議使用ASGD的一種非單調觸發變體(NT-ASGD),其中:
- 僅當驗證測度在多次迴圈後沒有改善的情況下才觸發平均。所以,當驗證測度在n次迴圈(n稱為非單調間隔超引數)後沒有改善時,演算法換用ASGD。論文作者發現n=5這一設定效果良好。
- 使用恆定學習率,因此無需進一步調整。
論文作者使用了這一NT-ASGD設定,並演示了它的效果要優於SGD。
擴充套件正則化技術
除了上面討論到的兩種技術,論文作者還使用了其他預防過擬合、提升資料效率的正則化技術。
可變長度反向傳播序列
論文作者指出了固定長度BPTT的低效。假設我們在100個元素上進行長度為10的固定視窗的BPTT。在這一情形下,任何可以被10整除的元素將沒有任何元素可以反向傳播。固定長度BPTT阻止了1/10的資料以迴圈的方式改善自身,還有8/10的資料僅僅使用部分BPTT視窗。
為了應對這一問題,論文作者提議使用可變長度反向傳播序列。首先選定基本序列長度,有p的概率選擇bptt,1-p的概率選擇bptt/2。在PyTorch實現中,論文作者將p設為0.95.
base_bptt = bptt if np.random.random() < 0.95 else bptt / 2
接著,據N(basebptt, s)得到seqlen,其中s是標準差,N是正態分佈。論文中是這麼寫的,不過PyTorch實現中是這麼計算的:
seq_len = max(5, int(np.random.normal(base_bptt, 5)))
然後再根據seq_len改變比例。這一步是必要的,因為取樣任意序列長度的情況下,使用固定學習率將傾向於短序列。
變分dropout
在標準dropout中,每次呼叫dropout時取樣一個新的dropout掩碼。而在變分dropout中,dropout掩碼只在第一次呼叫時取樣,接著鎖定的dropout掩碼重複應用於前向和反向過程中的所有連線。
儘管RNN的隱藏到隱藏轉換中使用了DropConnect,但其他所有dropout操作中使用了變分dropout,特別是在給定的前向和反向傳播中,LSTM的所有輸入和輸出使用同樣的dropout掩碼。mini-batch內的每個樣本使用不同的dropout掩碼,而不是在所有樣本上使用同一個掩碼,以確保元素丟棄的多樣性。
具體細節可以參考程式碼倉庫中的locked_dropout.py模組。
嵌入dropout
論文作者使用最早由A Theoretically Grounded Application of Dropout in Recurrent Neural Networks這篇論文提出的嵌入dropout。該技術在單詞的嵌入矩陣上應用dropout,導致在完整的前向和反向傳播上該特定單詞的所有使用都消失了。
減少嵌入尺寸
減少語言模型的總引數量的最簡單方法是降低詞向量的尺寸,儘管這無助於緩解過擬合。論文作者修改了第一個和最後一個LSTM層的輸入和輸出維度,以和降低了的嵌入尺寸保持一致。
啟用正則化
權重上常常使用L2正則以緩解過擬合。L2正則也同樣可以應用於單個單元啟用。啟用正則化懲罰顯著過大的啟用。
loss = loss + alpha * dropped_rnn_h.pow(2).mean()
時域啟用正則化
這一方法在RNN不同時步的輸出的差異上應用L2正則化,懲罰產生過大的隱藏狀態變動的模型。
loss = loss + beta * (rnn_h[1:] - rnn_h[:-1]).pow(2).mean()
上面的alpha和beta都是比例係數。啟用正則化和時域啟用正則化只應用於RNN最終層的輸出。
模型分析
論文作者也做了消融試驗,檢驗各種技術的有效性。

從上表我們可以看到,最劇烈的表現下降來自放棄使用DropConnect。
重要的實現細節
資料集 Penn Tree Bank (PTB)資料集和WikiText 2資料集。
網路架構 WT2上的batch尺寸設為80,PTB上的batch尺寸設為40。根據論文作者的經驗,較大的batch尺寸(例如,40-80)表現優於較小的尺寸(例如,10-20)。
指標模型 論文作者也演示瞭如何在基於指標的注意力模型上應用這些技術。
其他超引數的細節請參閱論文。超引數的選取基於試錯法,使用細粒度超引數搜尋可能進一步提升表現。
結語
AWD-LSTM精彩地解釋瞭如何在語言模型上應用現有正則化和優化策略。我覺得這是任何NLP研究者(包括初學者在內)必讀的經典論文。論文作者同時指出,儘管這些策略是在語言建模的任務上演示的,它們應該通用於其他序列學習任務。這為未來的研究提供了許多可能性。
希望你享受閱讀本文的時間,也希望本文能讓你更容易理解原論文。非常感謝。
十分感謝Stephen Merity(論文第一作者)的認可:blush: