再探循環神經網絡

  • 2020 年 3 月 14 日
  • 筆記

上一篇中,我們討論了循環神經網絡相關的基本內容,今天我們繼續探討一下循環神經網絡還有那些需要注意的更高級的用法。

降低過擬合

在之前的討論中,我們經常聊起過擬合的問題,我們一般判斷訓練的網絡什麼情況下算作訓練完成,查看其精度和損失時,也都看的是其過擬合之前的數據,避免過擬合的一種方法是用 dropout 方法,隨機清零的方式去實現,但是在循環神經網絡中,這個問題就有點複雜了。

人們在大量的實驗中早已經發現,在循環層前進行 dropout 對於降低過擬合沒什麼幫助,甚至可能會影響網絡的正常訓練,在循環層中如何 dropout 是在 2015 年的一篇論文中提出來的,具體的方式是:在每一個時間步中,使用相同的 dropout 掩碼,並且將這個不隨時間步變化的 dropout 掩碼應用於層的內部循環激活,這樣就可以將其學習的誤差傳遞下去,如果在 Keras 中使用 LSTM、GRU 等循環神經網絡都可以通過設置 dropout(輸入單元 dropout) 和 recurrent_out (循環單元 dropout)來降低過擬合,一般情況下,最佳情況不會有大的下降,但會穩定更多,是調優網絡的一個思路。用的方法是:

model.add(layers.GRU(32, dropout=0.2, recurrent_dropout=0.2, input_shape=(None, float_data.shape[-1])))

循環層堆疊

我們訓練網絡一般的過程都是構建一個網絡,在未出現嚴重過擬合前我們都會儘可能大的增加網絡容量(讓特徵點更多),這有助於讓網絡模型更好的抓住數據的特徵,對於循環神經網絡,也是類似的思路,進行循環層的堆疊,且一般情況下,都會讓數據變得更好,這是最常用其有效(使數據變好,具體提高程度視情況而不同)的調優方法,Google 產品中有挺多類似的做法。用的方法是:

model.add(layers.GRU(32, dropout=0.1, recurrent_dropout=0.5, return_sequences=True, input_shape=(None, float_data.shape[-1])))  model.add(layers.GRU(64, activation='relu', dropout=0.1, recurrent_dropout=0.5))

使用雙向 RNN

針對這個問題,我一直覺得是一個玄學。雙向 RNN,顧名思義,就是這個循環網絡中包含兩個方向相反的普通 RN,一個正向處理數據,一個反向處理數據,因為我們知道 RNN 是對順序敏感的前一項處理出的數據值,會作用到下一項數據上,因此數據的不同不同方向的處理會獲取到數據的不同特徵,或者說反向的 RN 會識別出被正向 RN 忽略的特徵,進而補充正向 RN 的不足,如此一來,可能使得整個 RNN 效果更好,略有玄學特徵但是也可以理解吧,總之這也是一個有效的辦法。用的方法是:

model.add(layers.Bidirectional(layers.LSTM(32)))

對於神經網絡來說,具體哪一種調優的方法真的有效效果更好,其實根據實際問題實際的數據有比較大的差別,不能一概而論,因此這也是一項需要經驗和耐心的工作,也許你還會發出這樣的疑問:「我去,為什麼這樣不行?我去,為什麼這樣還不行?我去,為什麼這樣行了?」

當然,還有一些其他的方法對於更好的訓練網絡可能有用,比如調節激活函數、調節優化器學習率等,用點耐心會訓練出你滿意的網絡的。

循環神經網絡就暫時先討論這些吧,還有很多細節但是很重要的問題還沒有詳細介紹,日後有機會繼續討論。

願世界和平!

  • 本文首發自公眾號:RAIS