在之前的討論中,我們經常聊起過擬合的問題,我們一般判斷訓練的網路什麼情況下算作訓練完成,檢視其精度和損失時,也都看的是其過擬合之前的資料,避免過擬合的一種方法是用 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,顧名思義,就是這個迴圈網路中包含兩個方向相反的普通 rn,乙個正向處理資料,乙個反向處理資料,因為我們知道 rnn 是對順序敏感的前一項處理出的資料值,會作用到下一項資料上,因此資料的不同不同方向的處理會獲取到資料的不同特徵,或者說反向的 rn 會識別出被正向 rn 忽略的特徵,進而補充正向 rn 的不足,如此一來,可能使得整個 rnn 效果更好,略有玄學特徵但是也可以理解吧,總之這也是乙個有效的辦法。用的方法是:
model.add(layers.bidirectional(layers.lstm(32)))
對於神經網路來說,具體哪一種調優的方法真的有效效果更好,其實根據實際問題實際的資料有比較大的差別,不能一概而論,因此這也是一項需要經驗和耐心的工作,也許你還會發出這樣的疑問:「我去,為什麼這樣不行?我去,為什麼這樣還不行?我去,為什麼這樣行了?」
當然,還有一些其他的方法對於更好的訓練網路可能有用,比如調節啟用函式、調節優化器學習率等,用點耐心會訓練出你滿意的網路的。
迴圈神經網路就暫時先討論這些吧,還有很多細節但是很重要的問題還沒有詳細介紹,日後有機會繼續討論。
願世界和平!
迴圈神經網路
原文 迴圈神經網路也可以畫成下面這個樣子 對於語言模型來說,很多時候光看前面的詞是不夠的,比如下面這句話 我的手機壞了,我打算 一部新手機。可以想象,如果我們只看橫線前面的詞,手機壞了,那麼我是打算修一修?換一部新的?還是大哭一場?這些都是無法確定的。但如果我們也看到了橫線後面的詞是 一部新手機 那...
迴圈神經網路
原文 迴圈神經網路也可以畫成下面這個樣子 對於語言模型來說,很多時候光看前面的詞是不夠的,比如下面這句話 我的手機壞了,我打算 一部新手機。可以想象,如果我們只看橫線前面的詞,手機壞了,那麼我是打算修一修?換一部新的?還是大哭一場?這些都是無法確定的。但如果我們也看到了橫線後面的詞是 一部新手機 那...
迴圈神經網路
特點 上一階段 時間步 的輸出作為輸入進入當前時間步。迴圈神經網路由迴圈神經原組成,迴圈神經元一般有兩個輸入,乙個是前階段的資訊,乙個是當前階段的資訊。同時產生乙個輸出,可以作為下一階段的輸入。迴圈神經網路採用多種模型。左上 每個時間步有乙個輸入,同時產生乙個輸出 右上 一串輸入,最後產生乙個輸出。...