1 引言 RNN(Recurrent Neural Networks) 一般翻譯為“遞歸神經(jīng)網(wǎng)絡” 或 “循環(huán)神經(jīng)網(wǎng)絡”,,這里面涉及到初學編程中經(jīng)常使用的兩個技巧:遞歸/循環(huán)。遞歸的典型例子就是斐波那契數(shù)列: int Fibonacci(int x) { if(x >= 3) { return Fibonacci(x - 1) + Fibonacci(x - 2); } else { return 1; } } 如果需要計算 Fibonacci(n), n > 3 則必須先計算 Finonacci(n-1) 和 Fibonacci(n-2),,依次類推,,直到 Fibonacci(1), Fibonacci(2), ..., Fibonacci(n-2), Fibonacci(n-1) 全部計算完成,才能得到 Fibonacci(n),。 利用循環(huán)同樣可以計算斐波那契數(shù)列: const int L = 30; int Fib[L] = {1, 1, 0}; for(int i = 2; i < l;=""> { Fib[i] = Fib[i-1] + Fib[i-2]; } 兩種實現(xiàn)是等價的,。 2 序列學習 上面的斐波那契數(shù)列就是一種序列(Sequence),語音信號也是一種序列,,你每天手機上推送的新聞,、公眾號文章,互聯(lián)網(wǎng)上的博客,、視頻,,客廳觀看的電視,收聽的廣播,、音樂,,閱讀的書,銀行打印的流水賬……都是序列,。 序列中的元素是存在相關性的,,比如你閱讀公眾號文章,如果只看文章中一兩個字,,獲取信息是極其有限的,,只有全部讀完才覺得“這篇文章很贊”或“上篇文章很水”。 前饋網(wǎng)絡(DNN,、CNN)只能接收固定維度的輸入,,處理序列數(shù)據(jù)時需要“截斷”為若干組,各組在處理時互相獨立,,這顯然不適合分析變長的序列數(shù)據(jù),,如語音識別時單從某個片段無法區(qū)分同一讀音的兩個詞(不行/步行),,必須聯(lián)系語境上下文。RNN 則在網(wǎng)絡結構中加入反饋機制,,將前一時刻輸出重新作為當前時刻輸入,,這也是 RNN 中 Recurrent 名字來源。RNN 結構如下圖所示: 我們可以把 st 看作網(wǎng)絡的記憶單元,,它可以捕獲之前時刻的信息,。RNN 是面向序列學習(Sequence Learning)的一款強大工具。 序列學習模型可以干嘛,?
輸入一組單詞,,利用這些單詞預測下一個單詞。訓練好的語言模型可以產(chǎn)生新文本,?;谏勘葋喿髌酚柧毜恼Z言模型可以產(chǎn)生類似莎士比亞作品的文本。
輸入為某種語言的文本,,輸出為另一種語言文本,。德語到英語的機器翻譯系統(tǒng)如下圖所示:
輸入為聲波中提取的語音信號,輸出一組音節(jié)片段以及相應概率密度,。
RNN 同卷積神經(jīng)網(wǎng)絡結合,,可以生成圖像描述,輸入為一張圖片,,輸出為描述該圖片的自然語言描述語句,。我們前面文章《利用 TensorFlow 實現(xiàn)“看圖說話”》介紹過該類型應用。 思考:能否用 RNN 學習斐波那契數(shù)列的規(guī)律,? 3 RNN 結構改進 訓練 RNN 和訓練傳統(tǒng)神經(jīng)網(wǎng)絡類似,,同樣使用反向傳播算法,但由于網(wǎng)絡參數(shù)被所有時刻共享,,每個時刻輸出計算的梯度不僅依賴當前時刻,,也依賴之前時刻。例如,,為了計算 t=4 時刻梯度,,我們應當反向傳播 3 次再將梯度累加。這種方法稱為沿時間反向傳播(BPTT,,Backpropagation Through Time),。實際上用 BPTT 訓練 RNN 會出現(xiàn)著名的“梯度爆炸/消失”問題。為了解決該問題,,RNN 逐步發(fā)展了多個變種。其中應用最廣泛的當屬 LSTM(Long Short Term Memories),,結構如下: 看上去有些雜亂,,最核心的實際上就是中央的細胞(C),,而三個標記 σ 的圓圈表示“三重門”:輸入門 i,輸出門 o,,遺忘門 f,,均使用 Sigmoid 函數(shù)將取值范圍限制到 (0, 1) 之內(nèi)。計算公式如下:
注意到 LSTM 結構圖中藍色箭頭其實代替了 RNN 中的反饋連接,。使用三個門可以控制不同時刻信息流動方向,,通過控制遺忘門和輸入門,選擇合適的信息進入細胞,,將無關信息拒之門外,;通過控制輸出門,選擇最合適的時刻輸出細胞處理后的信息,。 從公式可以看出 LSTM 計算較為復雜,,參數(shù)也非常多,難以訓練,。GRU(Gated Recurrent Units)應運而生,。 在 GRU 中,大幅簡化了 LSTM 結構:
計算公式如下: 通過以上改進,,GRU 計算相比 LSTM 得到簡化,,在一些應用中也得到驗證【2】,但在 GPU 上實現(xiàn)時,,效率不高,,主要是由于前后兩個時刻 t-1 和 t 的計算存在依賴性,只有當 ready 時,,才能計算 t 時刻的其他值等,,這樣無法完全發(fā)揮出 GPU 上硬件并行計算的優(yōu)勢。 最近論文【3】 SRU(Simple Recurrent Unit)則提出更激進的架構,,去掉了前后時刻計算的依賴,。 公式如下: 這樣可以將 t = 0, 1, ..., n 時刻的計算并行,從而獲得更高的加速比,。 偽代碼如下: 不同實現(xiàn)的耗時對比: SRU 相比 cuDNN LSTM 訓練提速超過 10 倍,! 原始論文中只提供了 PyTorch 和 CNTK 上的 SRU 實現(xiàn),github 上有開源的基于 Keras 的 SRU 實現(xiàn)【4】,,有條件的讀者可以利用它基于 TensorFlow Backend 做做試驗,,看看能否達到論文中的速度,。 4 補充信息 RNN 家族歷史悠久,使用廣泛,,目前仍面臨很多挑戰(zhàn),。 除了上述細胞結構的改進,網(wǎng)絡結構有如下擴展:
如果 t 時刻輸出不僅取決于之前時刻的序列輸入,,還取決于將來時刻序列輸入,,那么雙向 RNN 能更好地建模。典型例子:英語考試中的完形填空,。
將單層 RNN/LSTM/GRU/SRU 堆疊,,增加了網(wǎng)絡容量,同時需要大量訓練數(shù)據(jù),。 5 參考 【1】 www.wildml.com/2015/09/recurrent-neural-networks-tutorial-part-1-introduction-to-rnns/ 【2】Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling, arXiv:1412.3555v1 【3】Training RNNs as Fast as CNNs, https:///pdf/1709.02755.pdf 【4】 https://github.com/titu1994/keras-SRU |
|
來自: DISTANCE_A > 《dm》