1. 深度神經網路超參
模型的參數:就是模型可以根據數據可以自動學習出的變數,應該就是參數。比如,深度學習的權重,偏差等
超參數:就是用來確定模型的一些參數,超參數不同,模型是不同的(這個模型不同的意思就是有微小的區別,比如假設都是CNN模型,如果層數不同,模型不一樣,雖然都是CNN模型哈。),超參數一般就是根據經驗確定的變數。在深度學習中,超參數有:學習速率、迭代次數,層數,每層神經元的個數等等
2. 神經網路超參數選擇
深度學習模型通常由隨機梯度下降演算法進行訓練。隨機梯度下降演算法有許多變形:例如 Adam、RMSProp、Adagrad 等等。這些演算法都需要你設置學習率。學習率決定了在一個小批量(mini-batch)中權重在梯度方向要移動多遠。
如果學習率很低,訓練會變得更加可靠,但是優化會耗費較長的時間,因為朝向損失函數最小值的每個步長很小。
如果學習率很高,訓練可能根本不會收斂,損失函數一直處於波動中,甚至會發散。權重的改變數可能非常大,使得優化越過最小值,使得損失函數變得更糟。
訓練應當從相對較大的學習率開始。這是因為在開始時,初始的隨機權重遠離最優值。在訓練過程中,學習率應當下降,以允許細粒度的權重更新。
參考: https://www.jiqixin.com/articles/2017-11-17-2
批次大小是每一次訓練神經網路送入模型的樣本數。在 合理的范圍之內 ,越大的 batch size 使下降方向越准確,震盪越小,通常取值為[16,32,64,128]。
Batch_Size=全部數據集 缺點:
1) 隨著數據集的海量增長和內存限制,一次性載入所有的數據進來變得越來越不可行。
2) 以 Rprop 的方式迭代,會由於各個 Batch 之間的采樣差異性,各次梯度修正值相互抵消,無法修正。
Batch_Size = 1 缺點:
使用在線學習,每次修正方向以各自樣本的梯度方向修正,橫沖直撞各自為政,難以達到收斂。
在合理范圍內,增大 Batch_Size 有何好處?
1) 內存利用率提高了,大矩陣乘法的並行化效率提高。
2) 跑完一次 epoch(全數據集)所需的迭代次數減少,對於相同數據量的處理速度進一步加快。
3) 在一定范圍內,一般來說 Batch_Size 越大,其確定的下降方向越准,引起訓練震盪越小。
盲目增大 Batch_Size 有何壞處?
1) 內存利用率提高了,但是內存容量可能撐不住了。
2) 跑完一次 epoch(全數據集)所需的迭代次數減少,要想達到相同的精度,其所花費的時間大大增加了,從而對參數的修正也就顯得更加緩慢。
3) Batch_Size 增大到一定程度,其確定的下降方向已經基本不再變化。
參考: https://blog.csdn.net/juronghui/article/details/78612653
迭代次數是指整個訓練集輸入到神經網路進行訓練的次數,當測試錯誤率和訓練錯誤率相差較小,且測試准確率趨於穩定時(達到最優),可認為當前迭代次數合適;當測試錯誤率先變小後變大時則說明迭代次數過大了,需要減小迭代次數,否則容易出現過擬合。
用激活函數給神經網路加入一些非線性因素,使得網路可以更好地解決較為復雜的問題。參考: https://blog.csdn.net/tyhj_sf/article/details/79932893
它能夠把輸入的連續實值變換為0和1之間的輸出。
缺點:
1) 在深度神經網路中梯度反向傳遞時導致梯度爆炸和梯度消失,其中梯度爆炸發生的概率非常小,而梯度消失發生的概率比較大。
2) Sigmoid 的 output 不是0均值,使得收斂緩慢。batch的輸入能緩解這個問題。
它解決了Sigmoid函數的不是zero-centered輸出問題,然而梯度消失的問題和冪運算的問題仍然存在。
tanh函數具有中心對稱性,適合於有對稱性的二分類
雖然簡單,但卻是近幾年的重要成果,有以下幾大優點:
1) 解決了梯度消散問題 (在正區間)
2)計算速度非常快,只需要判斷輸入是否大於0
3)收斂速度遠快於sigmoid和tanh
ReLU也有幾個需要特別注意的問題:
1)ReLU的輸出不是zero-centered
2)Dead ReLU Problem,指的是某些神經元可能永遠不會被激活,導致相應的參數永遠不能被更新。有兩個主要原因可能導致這種情況產生: (1) 非常不幸的參數初始化,這種情況比較少見 (2) learning rate太高導致在訓練過程中參數更新太大,不幸使網路進入這種狀態。解決方法是可以採用Xavier初始化方法,以及避免將learning rate設置太大或使用adagrad等自動調節learning rate的演算法。
為了解決Dead ReLU Problem,提出了將ReLU的前半段設為 αx 而非 0 ,如 PReLU 。
1)深度學習往往需要大量時間來處理大量數據,模型的收斂速度是尤為重要的。所以,總體上來講,訓練深度學習網路盡量使用zero-centered數據 (可以經過數據預處理實現) 和zero-centered輸出。所以要盡量選擇輸出具有zero-centered特點的激活函數以加快模型的收斂速度。
2)如果使用 ReLU,那麼一定要小心設置 learning rate,而且要注意不要讓網路出現很多 「dead」 神經元,如果這個問題不好解決,那麼可以試試 Leaky ReLU、PReLU 或者 Maxout.
3)最好不要用 sigmoid,你可以試試 tanh,不過可以預期它的效果會比不上 ReLU 和 Maxout.
公式: https://www.cnblogs.com/xiaobingqianrui/p/10756046.html
優化器比較: https://blog.csdn.net/weixin_40170902/article/details/80092628
3. 循環神經網路(RNN)淺析
RNN是兩種神經網路模型的縮寫,一種是遞歸神經網路(Recursive Neural Network),一種是循環神經網路(Recurrent Neural Network)。雖然這兩種神經網路有著千絲萬縷的聯系,但是本文主要討論的是第二種神經網路模型——循環神經網路(Recurrent Neural Network)。
循環神經網路是指一個隨著時間的推移,重復發生的結構。在自然語言處理(NLP),語音圖像等多個領域均有非常廣泛的應用。RNN網路和其他網路最大的不同就在於RNN能夠實現某種「記憶功能」,是進行時間序列分析時最好的選擇。如同人類能夠憑借自己過往的記憶更好地認識這個世界一樣。RNN也實現了類似於人腦的這一機制,對所處理過的信息留存有一定的記憶,而不像其他類型的神經網路並不能對處理過的信息留存記憶。
循環神經網路的原理並不十分復雜,本節主要從原理上分析RNN的結構和功能,不涉及RNN的數學推導和證明,整個網路只有簡單的輸入輸出和網路狀態參數。一個典型的RNN神經網路如圖所示:
由上圖可以看出:一個典型的RNN網路包含一個輸入x,一個輸出h和一個神經網路單元A。和普通的神經網路不同的是,RNN網路的神經網路單元A不僅僅與輸入和輸出存在聯系,其與自身也存在一個迴路。這種網路結構就揭示了RNN的實質:上一個時刻的網路狀態信息將會作用於下一個時刻的網路狀態。如果上圖的網路結構仍不夠清晰,RNN網路還能夠以時間序列展開成如下形式:
等號右邊是RNN的展開形式。由於RNN一般用來處理序列信息,因此下文說明時都以時間序列來舉例,解釋。等號右邊的等價RNN網路中最初始的輸入是x0,輸出是h0,這代表著0時刻RNN網路的輸入為x0,輸出為h0,網路神經元在0時刻的狀態保存在A中。當下一個時刻1到來時,此時網路神經元的狀態不僅僅由1時刻的輸入x1決定,也由0時刻的神經元狀態決定。以後的情況都以此類推,直到時間序列的末尾t時刻。
上面的過程可以用一個簡單的例子來論證:假設現在有一句話「I want to play basketball」,由於自然語言本身就是一個時間序列,較早的語言會與較後的語言存在某種聯系,例如剛才的句子中「play」這個動詞意味著後面一定會有一個名詞,而這個名詞具體是什麼可能需要更遙遠的語境來決定,因此一句話也可以作為RNN的輸入。回到剛才的那句話,這句話中的5個單詞是以時序出現的,我們現在將這五個單詞編碼後依次輸入到RNN中。首先是單詞「I」,它作為時序上第一個出現的單詞被用作x0輸入,擁有一個h0輸出,並且改變了初始神經元A的狀態。單詞「want」作為時序上第二個出現的單詞作為x1輸入,這時RNN的輸出和神經元狀態將不僅僅由x1決定,也將由上一時刻的神經元狀態或者說上一時刻的輸入x0決定。之後的情況以此類推,直到上述句子輸入到最後一個單詞「basketball」。
接下來我們需要關注RNN的神經元結構:
上圖依然是一個RNN神經網路的時序展開模型,中間t時刻的網路模型揭示了RNN的結構。可以看到,原始的RNN網路的內部結構非常簡單。神經元A在t時刻的狀態僅僅是t-1時刻神經元狀態與t時刻網路輸入的雙曲正切函數的值,這個值不僅僅作為該時刻網路的輸出,也作為該時刻網路的狀態被傳入到下一個時刻的網路狀態中,這個過程叫做RNN的正向傳播(forward propagation)。註:雙曲正切函數的解析式如下:
雙曲正切函數的求導如下:
雙曲正切函數的圖像如下所示:
這里就帶來一個問題:為什麼RNN網路的激活函數要選用雙曲正切而不是sigmod呢?(RNN的激活函數除了雙曲正切,RELU函數也用的非常多)原因在於RNN網路在求解時涉及時間序列上的大量求導運算,使用sigmod函數容易出現梯度消失,且sigmod的導數形式較為復雜。事實上,即使使用雙曲正切函數,傳統的RNN網路依然存在梯度消失問題,無法「記憶」長時間序列上的信息,這個bug直到LSTM上引入了單元狀態後才算較好地解決。
這一節主要介紹與RNN相關的數學推導,由於RNN是一個時序模型,因此其求解過程可能和一般的神經網路不太相同。首先需要介紹一下RNN完整的結構圖,上一節給出的RNN結構圖省去了很多內部參數,僅僅作為一個概念模型給出。
上圖表明了RNN網路的完整拓撲結構,從圖中我們可以看到RNN網路中的參數情況。在這里我們只分析t時刻網路的行為與數學推導。t時刻網路迎來一個輸入xt,網路此時刻的神經元狀態st用如下式子表達:
t時刻的網路狀態st不僅僅要輸入到下一個時刻t+1的網路狀態中去,還要作為該時刻的網路輸出。當然,st不能直接輸出,在輸出之前還要再乘上一個系數V,而且為了誤差逆傳播時的方便通常還要對輸出進行歸一化處理,也就是對輸出進行softmax化。因此,t時刻網路的輸出ot表達為如下形式:
為了表達方便,筆者將上述兩個公式做如下變換:
以上,就是RNN網路的數學表達了,接下來我們需要求解這個模型。在論述具體解法之前首先需要明確兩個問題:優化目標函數是什麼?待優化的量是什麼?
只有在明確了這兩個問題之後才能對模型進行具體的推導和求解。關於第一個問題,筆者選取模型的損失函數作為優化目標;關於第二個問題,我們從RNN的結構圖中不難發現:只要我們得到了模型的U,V,W這三個參數就能完全確定模型的狀態。因此該優化問題的優化變數就是RNN的這三個參數。順便說一句,RNN模型的U,V,W三個參數是全局共享的,也就是說不同時刻的模型參數是完全一致的,這個特性使RNN得參數變得稍微少了一些。
不做過多的討論,RNN的損失函數選用交叉熵(Cross Entropy),這是機器學習中使用最廣泛的損失函數之一了,其通常的表達式如下所示:
上面式子是交叉熵的標量形式,y_i是真實的標簽值,y_i*是模型給出的預測值,最外面之所以有一個累加符號是因為模型輸出的一般都是一個多維的向量,只有把n維損失都加和才能得到真實的損失值。交叉熵在應用於RNN時需要做一些改變:首先,RNN的輸出是向量形式,沒有必要將所有維度都加在一起,直接把損失值用向量表達就可以了;其次,由於RNN模型處理的是序列問題,因此其模型損失不能只是一個時刻的損失,應該包含全部N個時刻的損失。
故RNN模型在t時刻的損失函數寫成如下形式:
全部N個時刻的損失函數(全局損失)表達為如下形式:
需要說明的是:yt是t時刻輸入的真實標簽值,ot為模型的預測值,N代表全部N個時刻。下文中為了書寫方便,將Loss簡記為L。在結束本小節之前,最後補充一個softmax函數的求導公式:
由於RNN模型與時間序列有關,因此不能直接使用BP(back propagation)演算法。針對RNN問題的特殊情況,提出了BPTT演算法。BPTT的全稱是「隨時間變化的反向傳播演算法」(back propagation through time)。這個方法的基礎仍然是常規的鏈式求導法則,接下來開始具體推導。雖然RNN的全局損失是與全部N個時刻有關的,但為了簡單筆者在推導時只關注t時刻的損失函數。
首先求出t時刻下損失函數關於o_t*的微分:
求出損失函數關於參數V的微分:
因此,全局損失關於參數V的微分為:
求出t時刻的損失函數關於關於st*的微分:
求出t時刻的損失函數關於s_t-1*的微分:
求出t時刻損失函數關於參數U的偏微分。注意:由於是時間序列模型,因此t時刻關於U的微分與前t-1個時刻都有關,在具體計算時可以限定最遠回溯到前n個時刻,但在推導時需要將前t-1個時刻全部帶入:
因此,全局損失關於U的偏微分為:
求t時刻損失函數關於參數W的偏微分,和上面相同的道理,在這里仍然要計算全部前t-1時刻的情況:
因此,全局損失關於參數W的微分結果為:
至此,全局損失函數關於三個主要參數的微分都已經得到了。整理如下:
接下來進一步化簡上述微分表達式,化簡的主要方向為t時刻的損失函數關於ot的微分以及關於st*的微分。已知t時刻損失函數的表達式,求關於ot的微分:
softmax函數求導:
因此:
又因為:
且:
有了上面的數學推導,我們可以得到全局損失關於U,V,W三個參數的梯度公式:
由於參數U和W的微分公式不僅僅與t時刻有關,還與前面的t-1個時刻都有關,因此無法寫出直接的計算公式。不過上面已經給出了t時刻的損失函數關於s_t-1的微分遞推公式,想來求解這個式子也是十分簡單的,在這里就不贅述了。
以上就是關於BPTT演算法的全部數學推導。從最終結果可以看出三個公式的偏微分結果非常簡單,在具體的優化過程中可以直接帶入進行計算。對於這種優化問題來說,最常用的方法就是梯度下降法。針對本文涉及的RNN問題,可以構造出三個參數的梯度更新公式:
依靠上述梯度更新公式就能夠迭代求解三個參數,直到三個參數的值發生收斂。
這是筆者第一次嘗試推導RNN的數學模型,在推導過程中遇到了非常多的bug。非常感謝互聯網上的一些公開資料和博客,給了我非常大的幫助和指引。接下來筆者將嘗試實現一個單隱層的RNN模型用於實現一個語義預測模型。
4. 循環神經網路
花書中關於RNN的內容記錄於 https://www.jianshu.com/p/206090600f13 。
在前饋神經網路中,信息的傳遞是單向的,這種限制雖然使得網路變得更容易學習,但在一定程度上也減弱了神經網路模型的能力。在生物神經網路中,神經元之間的連接關系要復雜的多。 前饋神經網路可以看作是一個復雜的函數,每次輸入都是獨立的,即網路的輸出只依賴於當前的輸入。但是在很多現實任務中,網路的輸入不僅和當前時刻的輸入相關,也和其過去一段時間的輸出相關 。因此,前饋網路難以處理時序數據,比如視頻、語音、文本等。時序數據的長度一般是不固定的,而前饋神經網路要求輸入和輸出的維數都是固定的,不能任意改變。因此,當處理這一類和時序相關的問題時,就需要一種能力更強的模型。
循環神經網路(Recurrent Neural Network,RNN)是一類具有短期記憶能力的神經網路。在循環神經網路中,神經元不但可以接受其它神經元的信息,也可以接受自身的信息,形成具有環路的網路結構。 和前饋神經網路相比,循環神經網路更加符合生物神經網路的結構。循環神經網路已經被廣泛應用在語音識別、語言模型以及自然語言生成等任務上。循環神經網路的參數學習可以通過 隨時間反向傳播演算法 來學習。
為了處理這些時序數據並利用其歷史信息,我們需要讓網路具有短期記憶能力。而前饋網路是一個靜態網路,不具備這種記憶能力。
一種簡單的利用歷史信息的方法是建立一個額外的延時單元,用來存儲網路的歷史信息(可以包括輸入、輸出、隱狀態等)。比較有代表性的模型是延時神經網路。
延時神經網路是在前饋網路中的非輸出層都添加一個延時器,記錄最近幾次神經元的輸出。在第 個時刻,第 層神經元和第 層神經元的最近 次輸出相關,即:
延時神經網路在時間維度上共享權值,以降低參數數量。因此對於序列輸入來講,延時神經網路就相當於卷積神經網路 。
自回歸模型(Autoregressive Model,AR) 是統計學上常用的一類時間序列模型,用一個變數 的歷史信息來預測自己:
其中 為超參數, 為參數, 為第 個時刻的雜訊,方差 和時間無關。
有外部輸入的非線性自回歸模型(Nonlinear Autoregressive with ExogenousInputs Model,NARX) 是自回歸模型的擴展,在每個時刻 都有一個外部輸入 ,產生一個輸出 。NARX通過一個延時器記錄最近幾次的外部輸入和輸出,第 個時刻的輸出 為:
其中 表示非線性函數,可以是一個前饋網路, 和 為超參數。
循環神經網路通過使用帶自反饋的神經元,能夠處理任意長度的時序數據。
給定一個輸入序列 ,循環神經網路通過下面
公式更新帶反饋邊的隱藏層的活性值 :
其中 , 為一個非線性函數,也可以是一個前饋網路。
從數學上講,上式可以看成一個動力系統。動力系統(Dynamical System)是一個數學上的概念,指 系統狀態按照一定的規律隨時間變化的系統 。具體地講,動力系統是使用一個函數來描述一個給定空間(如某個物理系統的狀態空間)中所有點隨時間的變化情況。因此, 隱藏層的活性值 在很多文獻上也稱為狀態(State)或隱狀態(Hidden States) 。理論上,循環神經網路可以近似任意的非線性動力系統。
簡單循環網路(Simple Recurrent Network,SRN)是一個非常簡單的循環神經網路,只有一個隱藏層的神經網路。
在一個兩層的前饋神經網路中,連接存在相鄰的層與層之間,隱藏層的節點之間是無連接的。而 簡單循環網路增加了從隱藏層到隱藏層的反饋連接 。
假設在時刻 時,網路的輸入為 ,隱藏層狀態(即隱藏層神經元活性值) 不僅和當前時刻的輸入 相關,也和上一個時刻的隱藏層狀態 相關:
其中 為隱藏層的凈輸入, 是非線性激活函數,通常為Logistic函數或Tanh函數, 為狀態-狀態權重矩陣, 為狀態-輸入權重矩陣, 為偏置。上面兩式也經常直接寫為:
如果我們把每個時刻的狀態都看作是前饋神經網路的一層的話,循環神經網路可以看作是在時間維度上權值共享的神經網路 。下圖給出了按時間展開的循環神經網路。
由於循環神經網路具有短期記憶能力,相當於存儲裝置,因此其計算能力十分強大。 前饋神經網路可以模擬任何連續函數,而循環神經網路可以模擬任何程序。
定義一個完全連接的循環神經網路,其輸入為 ,輸出為 :
其中 為隱狀態, 為非線性激活函數, 和 為網路參數。
這樣一個完全連接的循環神經網路可以近似解決所有的可計算問題 。
循環神經網路可以應用到很多不同類型的機器學習任務。根據這些任務的特點可以分為以下幾種模式: 序列到類別模式、同步的序列到序列模式、非同步的序列到序列模式 。
序列到類別模式主要用於序列數據的分類問題:輸入為序列,輸出為類別。比如在文本分類中,輸入數據為單詞的序列,輸出為該文本的類別。
假設一個樣本 為一個長度為 的序列,輸出為一個類別 。我們可以將樣本 按不同時刻輸入到循環神經網路中,並得到不同時刻的隱藏狀態 。我們可以將 看作整個序列的最終表示(或特徵),並輸入給分類器 進行分類:
其中 可以是簡單的線性分類器(比如Logistic 回歸)或復雜的分類器(比如多層前饋神經網路)
除了將最後時刻的狀態作為序列表示之外,我們還可以對整個序列的所有狀態進行平均,並用這個平均狀態來作為整個序列的表示:
同步的序列到序列模式 主要用於序列標注(Sequence Labeling)任務,即每一時刻都有輸入和輸出,輸入序列和輸出序列的長度相同 。比如詞性標注(Partof-Speech Tagging)中,每一個單詞都需要標注其對應的詞性標簽。
輸入為序列 ,輸出為序列 。樣本 按不同時刻輸入到循環神經網路中,並得到不同時刻的隱狀態 。每個時刻的隱狀態 代表當前和歷史的信息,並輸入給分類器 得到當前時刻的標簽 。
非同步的序列到序列模式也稱為 編碼器-解碼器(Encoder-Decoder)模型,即輸入序列和輸出序列不需要有嚴格的對應關系,也不需要保持相同的長度。 比如在機器翻譯中,輸入為源語言的單詞序列,輸出為目標語言的單詞序列。
在非同步的序列到序列模式中,輸入為長度為 的序列 ,輸出為長度為 的序列 。經常通過 先編碼後解碼 的方式來實現。先將樣本 按不同時刻輸入到一個循環神經網路(編碼器)中,並得到其編碼 。然後再使用另一個循環神經網路(解碼器)中,得到輸出序列 。為了建立輸出序列之間的依賴關系,在解碼器中通常使用非線性的自回歸模型。
其中 分別為用作編碼器和解碼器的循環神經網路, 為分類器, 為預測輸出 的向量表示。
循環神經網路的參數可以通過梯度下降方法來進行學習。給定一個訓練樣本 ,其中 為長度是 的輸入序列, 是長度為 的標簽序列。即在每個時刻 ,都有一個監督信息 ,我們定義時刻 的損失函數為:
其中 為第 時刻的輸出, 為可微分的損失函數,比如交叉熵。那麼整個序列上損失函數為:
整個序列的損失函數 關於參數 的梯度為:
即每個時刻損失 對參數 的偏導數之和。
循環神經網路中存在一個遞歸調用的函數 ,因此其計算參數梯度的方式和前饋神經網路不太相同。在循環神經網路中主要有兩種計算梯度的方式: 隨時間反向傳播(BPTT)和實時循環學習(RTRL)演算法。
隨時間反向傳播(Backpropagation Through Time,BPTT) 演算法的主要思想是通過類似前饋神經網路的錯誤反向傳播演算法來進行計算梯度。
BPTT演算法將循環神經網路看作是一個展開的多層前饋網路,其中「每一層」對應循環網路中的「每個時刻」。在「展開」的前饋網路中,所有層的參數是共享的,因此參數的真實梯度是將所有「展開層」的參數梯度之和 。
因為參數 和隱藏層在每個時刻 的凈輸入 有關,因此第 時刻的損失函數 關於參數 的梯度為:
其中 表示「直接」偏導數,即公式 中保持 不變,對 求偏導數,得到:
其中 為第 時刻隱狀態的第 維; 除了第 個值為 外,其餘都為 的行向量。
定義誤差項 為第 時刻的損失對第 時刻隱藏神經層的凈輸入 的導數,則:
從而:
寫成矩陣形式為:
由此得到整個序列的損失函數 關於參數 的梯度:
同理可得, 關於權重 和偏置 的梯度為:
在BPTT演算法中,參數的梯度需要在一個完整的「前向」計算和「反向」計算後才能得到並進行參數更新。如下圖所示。
與反向傳播的BPTT演算法不同的是,實時循環學習(Real-Time Recurrent Learning)是通過前向傳播的方式來計算梯度。
假設循環神經網路中第 時刻的狀態 為:
其關於參數 的偏導數為:
RTRL演算法從第1 個時刻開始,除了計算循環神經網路的隱狀態之外,還依次前向計算偏導數 。
兩種學習演算法比較:
RTRL演算法和BPTT演算法都是基於梯度下降的演算法,分別通過前向模式和反向模式應用鏈式法則來計算梯度。 在循環神經網路中,一般網路輸出維度遠低於輸入維度,因此BPTT演算法的計算量會更小,但BPTT演算法需要保存所有時刻的中間梯度,空間復雜度較高。RTRL演算法不需要梯度回傳,因此非常適合於需要在線學習或無限序列的任務中 。
循環神經網路在學習過程中的主要問題是由於 梯度消失或爆炸問題 ,很難建模長時間間隔(Long Range)的狀態之間的依賴關系。
在BPTT演算法中,我們有:
如果定義 ,則:
若 ,當 時, ,會造成系統不穩定,稱為梯度爆炸問題;相反,若 ,當 時, ,會出現和深度前饋神經網路類似的梯度消失問題。
雖然簡單循環網路理論上可以建立長時間間隔的狀態之間的依賴關系,但是由於梯度爆炸或消失問題,實際上只能學習到短期的依賴關系。這樣,如果t時刻的輸出 依賴於 時刻的輸入 ,當間隔 比較大時,簡單神經網路很難建模這種長距離的依賴關系,稱為 長程依賴問題(Long-Term dependencies Problem) 。
一般而言,循環網路的梯度爆炸問題比較容易解決,一般 通過權重衰減或梯度截斷來避免。 權重衰減是通過給參數增加 或 范數的正則化項來限制參數的取值范圍,從而使得 。梯度截斷是另一種有效的啟發式方法,當梯度的模大於一定閾值時,就將它截斷成為一個較小的數。
梯度消失是循環網路的主要問題。除了使用一些優化技巧外,更有效的方式就是改變模型,比如讓 ,同時使用 ,即:
其中 是一個非線性函數, 為參數。
上式中, 和 之間為線性依賴關系,且權重系數為1,這樣就不存在梯度爆炸或消失問題。但是,這種改變也丟失了神經元在反饋邊上的非線性激活的性質,因此也降低了模型的表示能力。
為了避免這個缺點,我們可以採用一種更加有效的改進策略:
這樣 和 之間為既有線性關系,也有非線性關系,並且可以緩解梯度消失問題。但這種改進依然存在兩個問題:
為了解決這兩個問題,可以通過引入 門控機制 來進一步改進模型。
為了改善循環神經網路的長程依賴問題,一種非常好的解決方案是引入門控機制來控制信息的累積速度,包括 有選擇地加入新的信息,並有選擇地遺忘之前累積的信息 。這一類網路可以稱為基於門控的循環神經網路(Gated RNN)。本節中,主要介紹兩種基於門控的循環神經網路: 長短期記憶網路和門控循環單元網路。
長短期記憶(Long Short-Term Memory,LSTM)網路 是循環神經網路的一個變體,可以有效地解決簡單循環神經網路的梯度爆炸或消失問題。
在 基礎上,LSTM網路主要改進在以下兩個方面:
其中 和 三個門(gate)來控制信息傳遞的路徑; 為向量元素乘積; 為上一時刻的記憶單元; 是通過非線性函數得到的候選狀態:
在每個時刻 ,LSTM網路的內部狀態 記錄了到當前時刻為止的歷史信息。
在數字電路中,門(Gate)為一個二值變數{0, 1},0代表關閉狀態,不許任何信息通過;1代表開放狀態,允許所有信息通過。LSTM網路中的「門」是一種「軟」門,取值在(0, 1) 之間,表示 以一定的比例運行信息通過 。LSTM網路中三個門的作用為:
(1)遺忘門 控制上一個時刻的內部狀態 需要遺忘多少信息。
(2)輸入門 控制當前時刻的候選狀態 有多少信息需要保存。
(3)輸出門
5. 神經網路結構搜索(Neural Architecture search)
神經網路搜索是生成和優化網路結構的有效工具 Neural Architecture Search 。
在不確定網路的長度和結構的情況下,使用一個循環神經網路(recurrent network)作為控制器來生成網路結構的欄位,用來構建子神經網路。將訓練子網路之後的准確率作為控制器回饋信號(reward signal),通過計算策略梯度(policy gradient)更新控制器,這樣不斷的迭代循環。在下一次迭代中,控制器將有更高的概率提出一個高准確率的網路結構。總之,伴隨著時間的推移,控制器將通過不斷的學習來提高搜索結果。如下圖所示就是網路結構搜索。
神經結構搜索中,我們使用控制器產生神經網路的超參數。控制器使用的是一個循環神經網路。假設我們希望預測只有卷積層的前饋神經網路,就可以使用控制器來生成這些超參數的序列。
控制器可以看到代理(agent),生成的超參數序列(網路結構的描述字元串)可以被看做代理一系列的動作(actions) 。子網路在收斂後將達到准確率 。隨後,將 作為回饋信號並使用增強學習訓練控制器。具體的說,為了優化的結構,需要讓控制器最大化期望回饋,期望回饋可以表示為 :
由於 不可微分,因此不能使用傳統的BP演算法。我們需要使用回饋更新代理的策略參數 ,進而實現回饋的最優化。這里我們使用 Williams 提出的REINFORCE,這個公式關聯了回饋 和策略參數 :
上述數值的可以近似表示為:
是控制器一個批樣本網路模型的數量, 是控制器生成的網路結構的超參數數量。 是第 個神經網路模型的准確率。
上述更新的梯度是梯度的無偏估計,但是方差很大。為了減小方差,我們使用了一個基線函數: 。
只要 不依賴與當前的動作,這個梯度導數將始終是無偏估計。這里,我們的 是准確率的指數移動平均值 EMA 。
在神經網路搜索中,訓練一個子網路可能需要幾個小時的時間。使用分布式訓練和並行參數更新可以加速控制器的學習過程。我們使用參數伺服器保存所有參數,伺服器將參數分發給控制器,控制器被分成 個,每一個控制器使用得到的參數進行模型的構建,由於得到的參數可能不同,構建模型的策略也是隨機的,導致每次構建的網路結構也會不同。每個控制器會構建一個batch, 個子網路,然後並行訓練子網路得到准確率。計算出參數的梯度。然後計算完梯度的控制器將梯度傳遞到參數伺服器,分別對自己負責的參數進行更新。接下來控制器得到更新的參數開始構建新的神經網路模型。這里,每一個控制器獨立的發送自己的梯度更新伺服器參數,不需要控制器之間同步,這及時非同步更新。這里子網路的訓練次數固定(epochs)。這種並行架構如下圖所示
為了讓控制器產生跳躍連接。在第 層中,添加一個錨點(anchor point)表示是否和前面的網路層連接:
表示控制器第 層網路錨點的隱藏狀態, 介於0到 之間。根據這些sigmoids的結果來決定哪些網路層被用作當前層的輸入。 , 和 是可訓練參數。[圖片上傳失敗...(image-feb8fe-1558488967580)]
為了產生循環元胞。控制器需要找到一個公式,以 和 作為輸入, 作為結果。最簡單的方式 ,這是一個基本的循環細胞的公式。一個更復雜的公式是廣泛應用的LSTM循環元胞。
基礎RNN和LSTM都可以描述為一個樹形結構,輸入 和 ,產生 ,這些變數作為葉子。控制器RNN需要標明樹上的每個節點的結合方法(相加,按元素相乘等)和激活函數,用於融合兩個輸入並產生一個輸出。然後兩個節點輸出又被作為樹上下一個節點的輸入。為了控制器可以選擇這些方法和函數,我們將樹上的節點以一定的順序編號,這樣控制器可以順序的預測。
6. 循環神經網路
為什麼卷積神經網路不會出現嚴重的數值問題呢?
卷積神經網路中每一層的權重矩陣 W 是不同的,並且在初始化時它們是獨立同分布的,因此可以相互抵消,在多層之後一般不會出現嚴重的數值問題。
循環神經網路採用 ReLu 激活函數,只有當 W 的取值在單位矩陣附近時才能取得比較好的效果,因此需要將 W 初始化為單位矩陣。
Seq2Seq 模型最基礎的解碼方法是貪心法,即選取一種度量標准後,每次都在當前狀態下選擇最佳的一個結果,直到結束。貪心法的計算代價低,適合作為基準結果與其他方法相比較。貪心法獲得的是一個局部最優解,由於實際問題的復雜性,該方法往往不能取得最好的結果。
集束搜索: 是一種啟發式演算法,會保存 beam size 個當前的較佳選擇,然後解碼時每一步根據保存的選則進行下一步擴展和排序,接著選擇前 b 個進行保存,循環迭代,知道結束時選擇最佳的一個作為解碼的結果。 b 往往選擇一個適中的范圍,以 8-12 為佳。
Seq2Seq 模型引入注意力機制是為了解決什麼問題?為什麼選用了雙向的循環神經網路模型?
編碼時輸入序列的全部信息壓縮到了一個向量中,隨著序列增長,句子越前面的詞的信息丟失越嚴重。同時,Seq2Seq 模型的輸出序列中,常常會損失部分輸入序列信息,這是解碼時,當前詞及對應的源語言詞的上下文信息和位置信息在編解碼過程中丟失了。 引入注意力機制,解決上述問題 。使用雙向的循環神經網路進行建模,可以獲取前後文的信息。
7. 循環神經網路(RNN)簡介
循環神經網路英文名稱為 ( Recurrent Neural Network, RNN ),其通過使用帶自反饋的神經元,能夠處理任意長度的 時序 數據。
給定輸入時序序列
式中, 表示一段時序數據, 為時間長度
以一段英文段落為例,其時序數據可以表示為:
若是一段視頻,將其每一幀通過CNN網路處理得到相應的編碼向量
循環神經網路通過以下公式更新隱藏層的活性值
循環神經網路圖示
RNN的基本模型如下圖所示,為便於理解,圖中將RNN的模型展開,按照時序方向對其前向傳播流程進行介紹
RNN的基本模型
利用數學表達式整個過程可以變得更加清晰,RNN的前向傳播公式如下:
將上述過程整合到一個RNN cell中,可以表示為如下圖所示的過程:
RNN的前向傳播示意圖
缺陷:
沒有利用到模型後續的信息,可以通過雙向RNN網路進行優化
RNN主要有兩種計算梯度的方式:隨時間反向傳播(BPTT)和實時循環學習法(RTRL)演算法
本文中主要介紹隨時間反向傳播的方法 ( BackPropagation Through Time )
RNN的損失函數與任務有關,對於同步的序列對序列任務,其loss可以用交叉熵公式表示
然後通過BPTT演算法便可以進行梯度的反向傳播計算
梯度爆炸的解決方法:梯度修剪
梯度消失的解決方法:增加長程依賴 LSTM,GRU
GRU的基本思路:增加相關門(Relate Gate)和更新門(Update Gate),進而使得RNN單元具有記憶能力
首先從數學角度對GRU的前向傳播過程進行介紹,具體公式如下:
公式中各變數的含義:
將上述數學公式轉化為圖像,可得
GRU Cell的前向傳播流程
LSTM意為長短時記憶網路 (Long Short-Term Memory Network,LSTM) ,可以有效地解決簡單神經網路的梯度消失和爆炸問題
在LSTM中,與GRU主要有兩點不同
同樣,先從數學公式入手,對LSTM的前向傳播過程進行了解
基於數學公式的過程,可將LSTM CELL的前向傳播過程總結為(圖片借用於nndl):
LSTM Cell的前向傳播示意圖
從上圖中可以看出,LSTM在前向傳播的過程中傳輸了兩個狀態:內部狀態 以及外部狀態 ,在整個傳播過程中 外部狀態(隱狀態) 每個時刻都會被重寫,因此可以看作一種 短時記憶 ,而 內部狀態 可以在某個時刻捕捉一些關鍵信息,並將此信息保存一段時間間隔,可以看作一種 長時記憶 (長的短時記憶)
此外,在LSTM網路初始化訓練的時候,需要手動將遺忘門的數值設置的大一些,否則在參數初始化的時候,遺忘門的數據會被初始化為一個很小的值,前一時刻的內部狀態 大部分都會丟失,這樣網路很難獲取到長距離的依賴信息,並且相鄰時間間隔的梯度會非常小,導致 梯度彌散 問題,因此遺忘門的 偏置變數 的初始值 一般很大,取 1或2
將 設置為1即可,但是長度非常的大的時候會造成記憶單元的飽和,降低性能
三個門不僅依賴於 和 ,也依賴於
將兩者合並為一個門,即:
首先,我們要理解什麼是深層的RNN,對於單個的RNN cell,若將其在時間維度上展開,其深度與時間維度的長度成正比,但若將一個RNN cell看作為單個從 的映射函數,則單個cell實際上是很淺顯的一層,因此深層循環神經網路要做的就是把多個RNN cell組合起來,換句話說,就是增加從輸入 到輸出 的路徑,使得網路的深度更深。
如何增加從輸入 到輸出 的路徑呢?兩種途徑:
堆疊循環神經網路示意圖
將網路帶入到實際應用場景中:假如我們要翻譯一段句子
在這里,is和are實際上是由後面的Lucy和they所決定的,而這種單向的按照時序進行傳播的方式沒有利用到後面的信息。因此誕生了雙向循環網路
雙向循環神經網路示意圖
雙向循環神經網路實際上就是簡單的雙層循環神經網路,只不過第二層網路的傳播方式為按時序的逆向傳播,其傳播公式為:
8. 深層神經網路的超參數調試、正則化及優化
訓練集 ( Training set )
作用是用來擬合模型,通過設置分類器的參數,訓練分類模型。後續結合驗證集作用時,會選出同一參數的不同取值,擬合出多個分類器。
驗證集 ( Dev set )
作用是當通過訓練集訓練出多個模型後,為了能找出效果最佳的模型,使用各個模型對驗證集數據進行預測,並記錄模型准確率。選出效果最佳的模型所對應的參數,即用來調整模型參數。如svm中的參數c和核函數等。
測試集 ( Test set )
通過訓練集和驗證集得出最優模型後,使用測試集進行模型預測。用來衡量該最優模型的性能和分類能力。即可以把測試集當做從來不存在的數據集,當已經確定模型參數後,使用測試集進行模型性能評價。
一個有助於理解的形象比喻:
訓練集 —— 課本,學生根據課本里的內容來掌握知識。
驗證集 —— 作業,通過作業可以知道 不同學生學習情況、進步的速度快慢。
測試集 —— 考試,考的題是平常都沒有見過,考察學生舉一反三的能力。
訓練集 直接參與了模型調參的過程,顯然不能用來反映模型真實的能力(防止課本死記硬背的學生擁有最好的成績,即防止 過擬合 ) 。
驗證集 參與了人工調參(超參數)的過程,也不能用來最終評判一個模型(刷題庫的學生不代表其學習能力強)。
所以要通過最終的考試 (測試集) 來考察一個學生(模型)真正的能力。
如何將只有一個包含m個樣例的數據集D,產生出訓練集S和測試集T(驗證集可以省略)?主要有以下三種方法:
自助法 ( bootstrapping )
給定m個樣本的數據集D,我們對它進行采樣產生數據集D',每次隨機從D中挑選一個樣本,將其拷貝入D',然後再將樣本放回原始數據集D。顯然,該樣本在下次采樣時任然有可能被採到。這個過程重復m次後,我們就得到了含有m個樣本的數據集D',這就是自助采樣的結果。 樣本有重復采樣,也有一次也沒有被採到的。從未採到的結果是 ,取極限得到
因此,使用自助法約有1/3的數據集沒有被選中過,它們用於測試,這種方式叫「外包估計」。
自助法在數據集小,難以劃分訓練集、測試集的時候有很大的效果,如果數據集足夠大的時候,留出法和交叉驗證是更好的選擇。
留出法 ( hold-out )
將整個數據集D劃分為兩個互斥的集合,其中一個作為訓練集S,另一個作為測試集T。即,D=S∪T,S∩T=∅。在S上訓練出模型,T作為測試集,來評估模型效果。
當樣本數據量較小(10000條左右及以下)時,通常取其中70%作為訓練集,30%作為測試集;或60%作為訓練集,驗證集和測試集各20%。
交叉驗證法 ( cross validation )
如圖所示,交叉驗證法的實現流程大致如下:
(1) 將整個數據集分成k個大小相似的子集,即D=D1∪D2∪...∪Dk,Di∩Dj=∅(故又稱k折交叉驗證法,通常取k=10 )。
(2) 對於每一個模型Mi,演算法執行k次,每次選擇一個Sj(1≤j≤k)作為測試集,其它作為訓練集來訓練模型Mi,把訓練得到的模型在Sj上進行測試,這樣一來,每次都會得到一個誤差E,最後對k次得到的誤差求平均,就可以得到模型Mi的泛化誤差。
(3) 演算法選擇具有最小泛化誤差的模型作為最終模型,並且在整個訓練集上再次訓練該模型,從而得到最終的模型。
交叉驗證的主要的目的是 為了選擇不同的模型類型(比如一次線性模型、非線性模型) ,而 不是為了選擇具體模型的具體參數 。比如在BP神經網路中,其目的主要為了選擇模型的層數、神經元的激活函數、每層模型的神經元個數(即所謂的超參數),每一層網路神經元連接的最終權重是在模型選擇(即K折交叉驗證)之後,由全部的訓練數據重新訓練。
假設這就是數據集,顯然用簡單分類器(如邏輯回歸)並不能很好地擬合上述數據。這種情況稱為 欠擬合 。
相反地,如果採用一個非常復雜的分類器(如深度神經網路或含有隱藏單元的神經網路),擬合效果會非常好。但與此同時,模型的復雜度也會過高,這種稱為 過擬合 。
在兩者之間,可能會存在一些復雜程度適中、數據擬合適度的分類器,擬合結果較為合理,稱為 適度擬合 。
如上圖所示,訓練集誤差和驗證集誤差均較高時為 高偏差(欠擬合) 情況;訓練集誤差較高,驗證集誤差較高低時為 高方差(過擬合) 情況。
(1) 如何減小偏差(防止欠擬合)
① 增大神經網路規模。
(2) 如何減小方差(防止過擬合)
① 增加數據集樣本數量;
② 正則化。
參數 是指神經網路中由數據驅動並進行調整的變數,如𝑊和𝑏。
超參數 是指無需數據驅動,而是在訓練前或者訓練中人為進行調整的變數。例如演算法中的learning rate 𝑎(學習率)、iterations(梯度下降法循環的數量)、𝐿(隱藏層數目)、𝑛[𝑙](隱藏層單元數目)、choice of activation function(激活函數的選擇)等都需要人為設置,這些數字實際上控制了最後的參數𝑊和𝑏的值,所以它們被稱作超參數。
神經網路中的超參數主要分為三類:網路參數、優化參數、正則化參數。
網路參數
可指網路層與層之間的交互方式(相加、相乘或者串接等)、卷積核數量和卷積核尺寸、網路層數(也稱深度)和激活函數等。
優化參數
一般指學習率(learning rate)、批樣本數量(batch size)、不同優化器的參數以及部分損失函數的可調參數等。
正則化參數
權重衰減系數,隨機失活比率(dropout)等。
正則化有利於減小訓練集和驗證集准確率的方差,防止過擬合。在無法增加樣本數量或增加樣本數量的成本過高時,正則化是一種行之有效的方法。
一般將任意 維向量 的 - 范數定義為
根據定義:
當 時, 的 范數為 ,表示向量 中非0元素的個數。
當 時, 的 范數為 ,等於向量 中所有元素的絕對值之和。
當 時, 的 范數為 ,等於向量 中所有元素的平方和開根號。
正則化(Regularization) 的主要目的是控制模型復雜度,減小過擬合。最基本的正則化方法是在原目標(代價)函數 中添加懲罰項,對復雜度高的模型進行「懲罰」。
對於神經網路模型, 正則化即在其代價函數中添加 正則項:
其中, 。之後再求解優化問題 即可。
假設某三層神經網路存在過擬合問題,採用dropout正則化會遍歷網路的每一層,並設置消除該層中每一個節點的概率(比如0.5),最後得到一個節點更少、規模更小的網路,然後再用反向傳播方法進行訓練,就能有效防止過擬合。
最常用的方法是 inverted dropout(反向隨機失活) 。對於一個三層神經網路( ),以第三層為例,實施dropout的步驟如下:
① 定義一個三層dropout矩陣d3:
d3=numpy.random.rand(a3.shape[0],a3.shape[1])
其中,a3表示神經網路第三層的激活函數矩陣。
② 設置 ( )的大小。 表示保留某個隱藏單元的概率。將第①步產生的隨機矩陣d3的每個元素與 進行比較,小於置1,大於置0,得到新的d3矩陣(1表示保留該節點,0表示刪除該節點)。
③ 將a3與新的d3矩陣相乘(矩陣對應元素相乘),得到新的激活函數矩陣:
a3 =np.multiply(a3,d3)
④ 將新的a3矩陣除以keep-prob:
a3 /= keep_prob
目的是保證a3的期望值(均值)不變,從而保證第三層的輸出不變。
① 使用dropout可以使得部分節點失活,可以起到簡化神經網路結構的作用,從而起到正則化的作用。
② 因為dropout是使得神經網路的節點隨機失活,這樣會讓神經網路在訓練的時候不會使得某一個節點權重過大。因為該節點輸入的特徵可能會被清除,所以神經網路的節點不能依賴任何輸入的特徵。dropout最終會產生收縮權重的平方范數的效果,來壓縮權重,達到類似於 正則化的效果。
① dropout在測試階段不需要使用,因為如果在測試階段使用dropout可能會導致預測值產生隨機變化(因為dropout使節點隨機失活)。而且,在訓練階段已經將權重參數除以keep-prob來保證輸出的期望值不變,所以在測試階段沒必要再使用dropout。
② 神經網路的不同層在使用dropout的時候,keep-prob可以不同。因為可能有的層參數比較多,比較復雜,keep-prob可以小一些,而對於結構比較簡單的層,keep-prob的值可以大一些甚至為1,keep-prob等於1表示不使用dropout,即該層的所有節點都保留。
加快訓練速度。
對於一個神經網路模型,考慮其代價函數:
如果未歸一化輸入,其代價函數的形狀會較為細長狹窄。在這樣的代價函數的限制下,為避免陷入局部最優解,梯度下降法的學習率必須設置得非常小。
如果歸一化輸入,代價函數便呈現球形輪廓。這種情況下,不論從哪個位置開始梯度下降法,都能使用較大的學習率,從而更快速、直接地找到全局最優解。
對於包含n個特徵的m個樣本的數據集,其輸入歸一化的過程主要分為兩步:
① 零均值化
② 歸一化方差
其中, 代表第 個樣本的特徵矩陣。
訓練集、驗證集、測試集特徵矩陣的平均值 和標准差 要保持一致,確保它們歸一化後符合同一分布。
9. AI數學基礎14——神經網路的參數和超參數
神經網路的參數( Parameters ),是指神經網路模型內部的配置變數,比如W、b,可以用訓練的方式獲得
神經網路的超參數( Hyper Parameters) ,是神經網路模型外部的配置參數,比如學習率a、隱藏層數L、隱藏層單元數、激活函數的選擇、momentum、mini batch size、regularization parameters等等,這些參數不能從訓練中得到, 必須手動設置, 並且影響最後的參數W和b的值 。
訓練神經網路的過程,也是系統性調整神經網路超參數的過程;Andrew Ng說:「經常試試不同的超參數,勤於檢查結果,看看有沒有更好的超參數取值,你將會得到設定超參數的直覺」