Google大腦提出「洗髮水」二階優化演算法,Transformer訓練時間減少40%,Jeff Dean點贊
- 2020 年 3 月 31 日
- 筆記
曉查 發自 凹非寺 量子位 報道 | 公眾號 QbitAI
機器學習的優化步驟,目前都是一階方法主導。
無論是SGD還是Adam,此類優化演算法在都是計算損失函數的一階導數——梯度,然後按照某種規定的方式讓權重隨梯度下滑方向迭代。
其實二階梯度會有更好的特性,因為它是計算梯度的導數,能夠更快地找到最合適的下降方向和速度。
然而出於計算量和存儲成本的考慮,二階優化演算法很少用到。
最近,Google大腦提出了一種新的二階預處理方法,帶來很大改進,優於SGD、Adam和AdaGrad等一階演算法,縮短了神經網路的訓練時間。
它在Transformer訓練任務中比任何一階方法都快得多,而且能達到相同甚至更高的精度。連Jeff Dean也不禁在Twitter上點贊。

「洗髮水」演算法
這篇文章是對之前一種二階方法洗髮水演算法(Shampoo algorithm)做的實用化改進。
為何叫「洗髮水演算法」?其實是對此類演算法的一種幽默稱呼。洗髮水的廣告詞一般是「搓揉、沖洗、重複」,表示簡單重複式的無限循環,最後導致洗髮水用盡(out of bottle)。
而這種演算法用於機器學習優化,最早來自於本文通訊作者Yoram Singer在2018年被ICML收錄的一篇文章Shampoo: Preconditioned Stochastic Tensor Optimization。
洗髮水演算法需要跟蹤2個預條件運算元(Preconditioner)的統計數值Lt和Rt。
然後計算這2個預條件運算元的四次根再求逆。將這兩個矩陣分別左乘和右乘梯度向量,迭代出t+1步的梯度再由以下公式得出:

上述過程像不像一種簡單重複,所以被作者自稱為「洗髮水」。
2018年的那篇論文更側重於理論解釋,然而就是如此簡單的「洗頭」步驟實際應用起來也會面臨諸多困難。
這一步中最大的計算量來自於Lt-1/4和Rt-1/4。計算這個兩個數需要用到代價高昂的奇異值分解。
實際上,四次逆根不僅可以用SVD方法算出,也可以用舒爾-牛頓法(Schur-Newton algorithm)算出,而且隨著矩陣維度的增大,後者節約的時間越來越可觀。

舒爾-牛頓法可以在普通CPU上計算,不必消耗GPU、TPU這類神經網路加速器的計算資源。
但即使是這樣,計算矩陣根的逆仍然相當耗時。如果不解決這個問題,訓練速度就不可能提高。
所以作者使用了非同步計算的方法,並使用了TensorFlow中的Lingvo來對訓練循環進行改進。
CPU負責收集和處理訓練數據以及輔助活動,例如檢查點和訓練狀態摘要。而在GPU、TPU等加速器運行訓練循環時通常處於空閑或低利用率狀態,並自動提供雙精度計算。
這使它們成為計算預條件運算元的理想選擇,而不會增加訓練消耗的資源。
使用非同步計算
他們在每一步中都計算所有張量的預條件運算元,但是預處理後的梯度卻是每N步計算一次,並交由CPU處理。
這期間,GPU或TPU依然在計算,過去的預條件運算元在訓練過程中會一直使用,直到獲得更新後的預訓練運算元為止。

計算過程像流水線一樣,並且非同步運行而不會阻塞訓練循環。結果是,洗髮水演算法中最難計算的步驟幾乎沒有增加總的訓練時間。
僅有這些還不夠,作者對洗髮水演算法又做了幾點改進,使它可以適應大型模型的訓練。包括解耦步長大小和方向、預處理大型張量還有將大型張量劃分成多個塊。
最高提速67%
在WMT』14英語到法語翻譯的Transformer訓練任務中,該演算法實現了1.67倍的加速,將時間減少了40%。

洗髮水演算法在和Adam或AdaGrad精度相同的情況下,只需後兩者實現了約一半的相同的精度AdaGrad或亞當許多步驟,而且對學習率的寬容度比AdaGrad高。
之前非同步計算中的N是一個可調參數,決定了訓練的計算量,N越大,計算量越小。當然N也會對結果造成影響。我們需要在訓練過程的性能和結果的品質之間做出權衡。
實驗表明,這種方法可以承受多達1200個步驟的延遲,而不會造成任何明顯的品質損失。

洗髮水也可以用在影像分類任務中。
作者還在ImageNet-2012數據集上訓練了ResNet-50模型,結果比帶動量的SGD收斂更快,但是訓練損失與SGD相近,但是在測試集上的效果不如後者。


至於在泛化能力上的劣勢,洗髮水演算法還有待進一步的改進。
論文地址:
https://arxiv.org/abs/2002.09018
https://arxiv.org/abs/1802.09568
作者系網易新聞·網易號「各有態度」簽約作者
— 完 —