1. 程式人生 > >再探迴圈神經網路

再探迴圈神經網路

上一篇中,我們討論了迴圈神經網路相關的基本內容,今天我們繼續探討一下迴圈神經網路還有那些需要注意的更高階的用法。 ## 降低過擬合 在之前的討論中,我們經常聊起過擬合的問題,我們一般判斷訓練的網路什麼情況下算作訓練完成,檢視其精度和損失時,也都看的是其過擬合之前的資料,避免過擬合的一種方法是用 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 產品中有挺多類似的做法。用的方法是: ```python 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 效果更好,略有玄學特徵但是也可以理解吧,總之這也是一個有效的辦法。用的方法是: ```python model.add(layers.Bidirectional(layers.LSTM(32))) ``` 對於神經網路來說,具體哪一種調優的方法真的有效效果更好,其實根據實際問題實際的資料有比較大的差別,不能一概而論,因此這也是一項需要經驗和耐心的工作,也許你還會發出這樣的疑問:“我去,為什麼這樣不行?我去,為什麼這樣還不行?我去,為什麼這樣行了?” 當然,還有一些其他的方法對於更好的訓練網路可能有用,比如調節啟用函式、調節優化器學習率等,用點耐心會訓練出你滿意的網路的。 迴圈神經網路就暫時先討論這些吧,還有很多細節但是很重要的問題還沒有詳細介紹,日後有機會繼續討論。 願世界和平! - 本文首發自公眾號:[RAIS](https://ai.renyuzhuo.cn)