由于在語言識別、機器翻譯和語言建模等領域表現出了優異的性能,為序列預測而設計的神經網絡最近再次引起了人們的興趣,但是這些模型都是計算密集型的,成本非常高。比如在語言建模領域,最新的成果依然需要在大規模GPU集群上訓練幾周的時間,雖然效果不錯,但是這些計算密集型的實踐對大規模計算基礎設施的依賴性非常強,這限制了其在學術和生產環境中的研究速度與應用。
針對這一計算瓶頸,Facebook AI 研究院(FAIR)設計了一個新的、幾乎是為GPU量身定制的softmax函數,能夠非常有效地通過大規模詞庫訓練神經網絡語言模型。該函數名為自適應softmax,它能根據不均衡的單詞分布構建集群,使計算復雜度最小化,避免了對詞庫大小的線性依賴。同時能夠在訓練和測試階段充分利用現代架構的特點和多維向量運算進一步降低計算消耗。與分層softmax、NCE以及重要性抽樣等之前的、大部分為標準CPU設計的方法相比,該方法更適合GPU。
此外,FAIR還開發并開源了一個名為torch-rnnlib 的類庫,該類庫允許研究者設計新的遞歸模型,并以最小的努力在GPU上測試這些原型。最近Edouard Grave、Justin Chiu 和Armand Joulin在Facebook的網站上發表了一篇文章,介紹了用戶如何通過該類庫設計新的遞歸網絡。
使用torch-rnnlib構建遞歸模型
1. 什么是語言建模?
語言建模就是通過給定詞典中的單詞序列學習其概率分布,根據單詞過去的概率計算其條件分布。T個單詞序列(w1,..., w[T])的概率可以表示為:
P(w1,..., w[T])) = P(w[T]|w[T-1],..., w1)...P(w1)
該問題通常通過非參數化的計數統計模型來解決,但是目前基于遞歸神經網絡的參數化模型已經被廣泛應用于語言建模。
2. 如何使用Torch-rnnlib構建標準模型
Torch-rnnlib為遞歸神經網絡的構建提供了三種不同的接口:
1). nn.{RNN, LSTM, GRU} 接口,用于構建所有層具有相同數量隱藏單元的遞歸網絡。
2). rnnlib.recurrentnetwork接口,用于構建任意形狀的遞歸網絡。
3). nn.SequenceTable 接口,用于將各種計算有效地鏈接到一起。nn.RecurrentTable 構造器僅是一個輕量級的包裝器,它會隨著時間的遷移克隆遞歸模塊。要注意的是,這是最底層的接口,必須調用rnnlib.setupRecurrent(model, initializationfunctions) 設置遞歸隱藏狀態行為。
3. 構建自己的遞歸模型
可以通過定義cell函數或者cell狀態初始化函數來創建自己的模型。下面的代碼展示了如何從零開始構建一個RNN:
4. 在GPU上訓練torch-rnnlib
因為torch-rnnlib遵循nn模塊接口,所以調用模型的:cuda()方法就能將其拉到GPU上執行。rnnlib的目的就是讓用戶能夠靈活地創建新的cell函數或者使用快基線。
此外,無論使用前面提到的第一個還是第二個接口構建遞歸網絡,都能非常容易地使用cudnn來加速網絡。對于第一個接口,通過usecudnn = true來調用構造函數:
對于第二個接口,將rnnlib.makeRecurrent替換成rnnlib.makeCudnnRecurrent,然后將cell函數修改為cudnn接口中的cellstring。例如:
這樣模型的遞歸部分通常會有至少兩倍的速度提升。但是這并不是說整個模型會提速至少兩倍,特別是當主要計算工作并不在遞歸部分的時候,此時提升會更小一些。
圖:torch-rnnlib及其他torch類庫隨著隱藏層數量的增加其運行時間的折線圖
5. 自適應Softmax
在處理語言模型等大規模輸出空間的時候,分類器可能是模型的計算瓶頸。過去提出的很多解決方案通常都是針對標準CPU而設計的,很少充分利用GPU所特有的能力。
Facebook開發的、新的自適應softmax能夠根據數據的分布情況調配計算資源。它能通過加快常用類的訪問速度,提供更多計算資源,來實現更好近似值和更快運行時間之間的平衡。更確切地說,它實現了一種k-way 分層softmax,能夠根據GPU的架構,通過動態規劃算法實現計算資源的有效分配。為了進一步降低分類器的計算負擔,自適應softmax還使用了一些技巧:使用淺樹(shallow trees)避免順序計算;為每個集群設置類數量的最小值,避免浪費GPU的并行計算能力。
正如圖表1所展示的那樣,自適應softmax的性能與完整softmax的性能幾乎不相上下,但是訓練時間非常短。
圖表1:基于Text8的性能。 ppl越低越好。
圖:不同softmax近似函數語言模型的收斂性。該數據基于LSTM。
測試結果
Facebook兩個模型的參數配置如下:小模型使用了有2048個單元的單層LSTM,大模型使用了每層有2048個神經元的雙層LSTM。訓練模型使用Adagrad,權重調整使用L2。批處理大小為128,反向傳播窗口大小為20。
圖表2:基于10億單詞進行訓練后的模型復雜度(越低越好)的比較。
如圖表2所示,小模型經過幾天的訓練復雜度達到了43.9,大模型經過6天的時間復雜度達到了39.8。目前最佳復雜度是由Jozefowicz et al.在2016年實現的30.0,但是Jozefowicz et al.達到這一數值使用了32顆GPU,花了3周多的時間;而Facebook僅用1顆GPU花了幾天時間。